Merge pull request #513 from MihailRis/enums-refactor
reduce boilerplate code of enums
This commit is contained in:
commit
bba647db5c
@ -1,3 +1,4 @@
|
||||
#define VC_ENABLE_REFLECTION
|
||||
#include "GLSLExtension.hpp"
|
||||
|
||||
#include <sstream>
|
||||
@ -95,22 +96,6 @@ inline void source_line(std::stringstream& ss, uint linenum) {
|
||||
ss << "#line " << linenum << "\n";
|
||||
}
|
||||
|
||||
static std::optional<Type> param_type_from(
|
||||
const std::string& name
|
||||
) {
|
||||
static const std::unordered_map<std::string, Type> typeNames {
|
||||
{"float", Type::FLOAT},
|
||||
{"vec2", Type::VEC2},
|
||||
{"vec3", Type::VEC3},
|
||||
{"vec4", Type::VEC4},
|
||||
};
|
||||
const auto& found = typeNames.find(name);
|
||||
if (found == typeNames.end()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return found->second;
|
||||
}
|
||||
|
||||
static Value default_value_for(Type type) {
|
||||
switch (type) {
|
||||
case Type::FLOAT:
|
||||
@ -212,11 +197,13 @@ public:
|
||||
}
|
||||
|
||||
bool processParamDirective() {
|
||||
using Param = PostEffect::Param;
|
||||
|
||||
skipWhitespace(false);
|
||||
// Parse type name
|
||||
auto typeName = parseName();
|
||||
auto type = param_type_from(typeName);
|
||||
if (!type.has_value()) {
|
||||
Param::Type type;
|
||||
if (!Param::TypeMeta.getItem(typeName, type)) {
|
||||
throw error("unsupported param type " + util::quote(typeName));
|
||||
}
|
||||
skipWhitespace(false);
|
||||
@ -228,17 +215,17 @@ public:
|
||||
skipWhitespace(false);
|
||||
ss << "uniform " << typeName << " " << paramName << ";\n";
|
||||
|
||||
auto defValue = default_value_for(type.value());
|
||||
auto defValue = default_value_for(type);
|
||||
// Parse default value
|
||||
if (peekNoJump() == '=') {
|
||||
skip(1);
|
||||
skipWhitespace(false);
|
||||
defValue = parseDefaultValue(type.value(), typeName);
|
||||
defValue = parseDefaultValue(type, typeName);
|
||||
}
|
||||
|
||||
skipLine();
|
||||
|
||||
params[paramName] = PostEffect::Param(type.value(), std::move(defValue));
|
||||
params[paramName] = PostEffect::Param(type, std::move(defValue));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
@ -25,23 +24,6 @@ namespace rigging {
|
||||
class SkeletonConfig;
|
||||
}
|
||||
|
||||
constexpr const char* ContentType_name(ContentType type) {
|
||||
switch (type) {
|
||||
case ContentType::NONE:
|
||||
return "none";
|
||||
case ContentType::BLOCK:
|
||||
return "block";
|
||||
case ContentType::ITEM:
|
||||
return "item";
|
||||
case ContentType::ENTITY:
|
||||
return "entity";
|
||||
case ContentType::GENERATOR:
|
||||
return "generator";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
class namereuse_error : public std::runtime_error {
|
||||
ContentType type;
|
||||
public:
|
||||
@ -185,26 +167,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
constexpr const char* to_string(ResourceType type) {
|
||||
switch (type) {
|
||||
case ResourceType::CAMERA:
|
||||
return "camera";
|
||||
case ResourceType::POST_EFFECT_SLOT:
|
||||
return "post-effect-slot";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
inline std::optional<ResourceType> ResourceType_from(std::string_view str) {
|
||||
if (str == "camera") {
|
||||
return ResourceType::CAMERA;
|
||||
} else if (str == "post-effect-slot") {
|
||||
return ResourceType::POST_EFFECT_SLOT;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
using ResourceIndicesSet = ResourceIndices[RESOURCE_TYPES_COUNT];
|
||||
|
||||
/// @brief Content is a definitions repository
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#define VC_ENABLE_REFLECTION
|
||||
#include "ContentLoader.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
@ -259,28 +260,25 @@ void ContentLoader::loadBlock(
|
||||
}
|
||||
|
||||
// block model
|
||||
std::string modelTypeName = to_string(def.model);
|
||||
std::string modelTypeName = BlockModelMeta.getNameString(def.model);
|
||||
root.at("model").get(modelTypeName);
|
||||
root.at("model-name").get(def.modelName);
|
||||
if (auto model = BlockModel_from(modelTypeName)) {
|
||||
if (*model == BlockModel::custom && def.customModelRaw == nullptr) {
|
||||
if (BlockModelMeta.getItem(modelTypeName, def.model)) {
|
||||
if (def.model == BlockModel::custom && def.customModelRaw == nullptr) {
|
||||
if (root.has("model-primitives")) {
|
||||
def.customModelRaw = root["model-primitives"];
|
||||
} else if (def.modelName.empty()) {
|
||||
throw std::runtime_error(name + ": no 'model-primitives' or 'model-name' found");
|
||||
}
|
||||
}
|
||||
def.model = *model;
|
||||
} else if (!modelTypeName.empty()) {
|
||||
logger.error() << "unknown model: " << modelTypeName;
|
||||
def.model = BlockModel::none;
|
||||
}
|
||||
|
||||
std::string cullingModeName = to_string(def.culling);
|
||||
std::string cullingModeName = CullingModeMeta.getNameString(def.culling);
|
||||
root.at("culling").get(cullingModeName);
|
||||
if (auto mode = CullingMode_from(cullingModeName)) {
|
||||
def.culling = *mode;
|
||||
} else {
|
||||
if (!CullingModeMeta.getItem(cullingModeName, def.culling)) {
|
||||
logger.error() << "unknown culling mode: " << cullingModeName;
|
||||
}
|
||||
|
||||
@ -518,9 +516,7 @@ void ContentLoader::loadEntity(
|
||||
|
||||
std::string bodyTypeName;
|
||||
root.at("body-type").get(bodyTypeName);
|
||||
if (auto bodyType = BodyType_from(bodyTypeName)) {
|
||||
def.bodyType = *bodyType;
|
||||
}
|
||||
BodyTypeMeta.getItem(bodyTypeName, def.bodyType);
|
||||
|
||||
root.at("skeleton-name").get(def.skeletonName);
|
||||
root.at("blocking").get(def.blocking);
|
||||
@ -799,8 +795,9 @@ void ContentLoader::load() {
|
||||
if (io::exists(resourcesFile)) {
|
||||
auto resRoot = io::read_json(resourcesFile);
|
||||
for (const auto& [key, arr] : resRoot.asObject()) {
|
||||
if (auto resType = ResourceType_from(key)) {
|
||||
loadResources(*resType, arr);
|
||||
ResourceType type;
|
||||
if (ResourceTypeMeta.getItem(key, type)) {
|
||||
loadResources(type, arr);
|
||||
} else {
|
||||
// Ignore unknown resources
|
||||
logger.warning() << "unknown resource type: " << key;
|
||||
@ -813,8 +810,9 @@ void ContentLoader::load() {
|
||||
if (io::exists(aliasesFile)) {
|
||||
auto resRoot = io::read_json(aliasesFile);
|
||||
for (const auto& [key, arr] : resRoot.asObject()) {
|
||||
if (auto resType = ResourceType_from(key)) {
|
||||
loadResourceAliases(*resType, arr);
|
||||
ResourceType type;
|
||||
if (ResourceTypeMeta.getItem(key, type)) {
|
||||
loadResourceAliases(type, arr);
|
||||
} else {
|
||||
// Ignore unknown resources
|
||||
logger.warning() << "unknown resource type: " << key;
|
||||
|
||||
@ -1,12 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "typedefs.hpp"
|
||||
#include "util/EnumMetadata.hpp"
|
||||
|
||||
class Content;
|
||||
class ContentPackRuntime;
|
||||
|
||||
enum class ContentType { NONE, BLOCK, ITEM, ENTITY, GENERATOR };
|
||||
|
||||
VC_ENUM_METADATA(ContentType)
|
||||
{"none", ContentType::NONE},
|
||||
{"block", ContentType::BLOCK},
|
||||
{"item", ContentType::ITEM},
|
||||
{"entity", ContentType::ENTITY},
|
||||
{"generator", ContentType::GENERATOR},
|
||||
VC_ENUM_END
|
||||
|
||||
enum class ResourceType : size_t {
|
||||
CAMERA,
|
||||
POST_EFFECT_SLOT,
|
||||
@ -15,3 +24,8 @@ enum class ResourceType : size_t {
|
||||
|
||||
inline constexpr auto RESOURCE_TYPES_COUNT =
|
||||
static_cast<size_t>(ResourceType::LAST) + 1;
|
||||
|
||||
VC_ENUM_METADATA(ResourceType)
|
||||
{"camera", ResourceType::CAMERA},
|
||||
{"post-effect-slot", ResourceType::POST_EFFECT_SLOT},
|
||||
VC_ENUM_END
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#define VC_ENABLE_REFLECTION
|
||||
#include "../ContentLoader.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
@ -210,13 +211,9 @@ void ContentLoader::loadGenerator(
|
||||
map.at("heights-bpd").get(def.heightsBPD);
|
||||
std::string interpName;
|
||||
map.at("heights-interpolation").get(interpName);
|
||||
if (auto interp = InterpolationType_from(interpName)) {
|
||||
def.heightsInterpolation = *interp;
|
||||
}
|
||||
InterpolationTypeMeta.getItem(interpName, def.heightsInterpolation);
|
||||
map.at("biomes-interpolation").get(interpName);
|
||||
if (auto interp = InterpolationType_from(interpName)) {
|
||||
def.biomesInterpolation = *interp;
|
||||
}
|
||||
InterpolationTypeMeta.getItem(interpName, def.biomesInterpolation);
|
||||
|
||||
map.at("sea-level").get(def.seaLevel);
|
||||
map.at("wide-structs-chunks-radius").get(def.wideStructsChunksRadius);
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
#include <optional>
|
||||
|
||||
#include "typedefs.hpp"
|
||||
#include "interfaces/Serializable.hpp"
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "data/dv_fwd.hpp"
|
||||
#include "util/EnumMetadata.hpp"
|
||||
|
||||
class Shader;
|
||||
|
||||
@ -14,6 +15,14 @@ class PostEffect {
|
||||
public:
|
||||
struct Param {
|
||||
enum class Type { FLOAT, VEC2, VEC3, VEC4 };
|
||||
|
||||
VC_ENUM_METADATA(Type)
|
||||
{"float", Type::FLOAT},
|
||||
{"vec2", Type::VEC2},
|
||||
{"vec3", Type::VEC3},
|
||||
{"vec4", Type::VEC4},
|
||||
VC_ENUM_END
|
||||
|
||||
using Value = std::variant<float, glm::vec2, glm::vec3, glm::vec4>;
|
||||
|
||||
Type type;
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
#include "commons.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
std::optional<CursorShape> CursorShape_from(std::string_view name) {
|
||||
static std::map<std::string_view, CursorShape> shapes = {
|
||||
{"arrow", CursorShape::ARROW},
|
||||
{"text", CursorShape::TEXT},
|
||||
{"crosshair", CursorShape::CROSSHAIR},
|
||||
{"pointer", CursorShape::POINTER},
|
||||
{"ew-resize", CursorShape::EW_RESIZE},
|
||||
{"ns-resize", CursorShape::NS_RESIZE},
|
||||
{"nwse-resize", CursorShape::NWSE_RESIZE},
|
||||
{"nesw-resize", CursorShape::NESW_RESIZE},
|
||||
{"all-resize", CursorShape::ALL_RESIZE},
|
||||
{"not-allowed", CursorShape::NOT_ALLOWED}
|
||||
};
|
||||
const auto& found = shapes.find(name);
|
||||
if (found == shapes.end()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return found->second;
|
||||
}
|
||||
|
||||
std::string to_string(CursorShape shape) {
|
||||
static std::string names[] = {
|
||||
"arrow",
|
||||
"text",
|
||||
"crosshair",
|
||||
"pointer",
|
||||
"ew-resize",
|
||||
"ns-resize",
|
||||
"nwse-resize",
|
||||
"nesw-resize",
|
||||
"all-resize",
|
||||
"not-allowed"
|
||||
};
|
||||
return names[static_cast<int>(shape)];
|
||||
}
|
||||
@ -3,6 +3,8 @@
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
||||
#include "util/EnumMetadata.hpp"
|
||||
|
||||
enum class DrawPrimitive {
|
||||
point = 0,
|
||||
line,
|
||||
@ -48,8 +50,18 @@ enum class CursorShape {
|
||||
LAST=NOT_ALLOWED
|
||||
};
|
||||
|
||||
std::optional<CursorShape> CursorShape_from(std::string_view name);
|
||||
std::string to_string(CursorShape shape);
|
||||
VC_ENUM_METADATA(CursorShape)
|
||||
{"arrow", CursorShape::ARROW},
|
||||
{"text", CursorShape::TEXT},
|
||||
{"crosshair", CursorShape::CROSSHAIR},
|
||||
{"pointer", CursorShape::POINTER},
|
||||
{"ew-resize", CursorShape::EW_RESIZE},
|
||||
{"ns-resize", CursorShape::NS_RESIZE},
|
||||
{"nwse-resize", CursorShape::NWSE_RESIZE},
|
||||
{"nesw-resize", CursorShape::NESW_RESIZE},
|
||||
{"all-resize", CursorShape::ALL_RESIZE},
|
||||
{"not-allowed", CursorShape::NOT_ALLOWED},
|
||||
VC_ENUM_END
|
||||
|
||||
class Flushable {
|
||||
public:
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#define VC_ENABLE_REFLECTION
|
||||
#include "gui_xml.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
@ -168,8 +169,9 @@ static void read_uinode(
|
||||
node.setTooltipDelay(element.attr("tooltip-delay").asFloat());
|
||||
}
|
||||
if (element.has("cursor")) {
|
||||
if (auto cursor = CursorShape_from(element.attr("cursor").getText())) {
|
||||
node.setCursor(*cursor);
|
||||
CursorShape cursor;
|
||||
if (CursorShapeMeta.getItem(element.attr("cursor").getText(), cursor)) {
|
||||
node.setCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#define VC_ENABLE_REFLECTION
|
||||
#include "EngineController.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
@ -164,7 +165,7 @@ static dv::value create_missing_content_report(
|
||||
auto root = dv::object();
|
||||
auto& contentEntries = root.list("content");
|
||||
for (auto& entry : report->getMissingContent()) {
|
||||
std::string contentName = ContentType_name(entry.type);
|
||||
std::string contentName = ContentTypeMeta.getNameString(entry.type);
|
||||
auto& contentEntry = contentEntries.object();
|
||||
contentEntry["type"] = contentName;
|
||||
contentEntry["name"] = entry.name;
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#define VC_ENABLE_REFLECTION
|
||||
|
||||
#include "util/stringutil.hpp"
|
||||
#include "libentity.hpp"
|
||||
|
||||
@ -96,8 +98,8 @@ static int l_set_crouching(lua::State* L) {
|
||||
|
||||
static int l_get_body_type(lua::State* L) {
|
||||
if (auto entity = get_entity(L, 1)) {
|
||||
return lua::pushstring(
|
||||
L, to_string(entity->getRigidbody().hitbox.type)
|
||||
return lua::pushlstring(
|
||||
L, BodyTypeMeta.getName(entity->getRigidbody().hitbox.type)
|
||||
);
|
||||
}
|
||||
return 0;
|
||||
@ -105,9 +107,9 @@ static int l_get_body_type(lua::State* L) {
|
||||
|
||||
static int l_set_body_type(lua::State* L) {
|
||||
if (auto entity = get_entity(L, 1)) {
|
||||
if (auto type = BodyType_from(lua::tostring(L, 2))) {
|
||||
entity->getRigidbody().hitbox.type = *type;
|
||||
} else {
|
||||
if (!BodyTypeMeta.getItem(
|
||||
lua::tostring(L, 2), entity->getRigidbody().hitbox.type
|
||||
)) {
|
||||
throw std::runtime_error(
|
||||
"unknown body type " + util::quote(lua::tostring(L, 2))
|
||||
);
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#define VC_ENABLE_REFLECTION
|
||||
#include "content/Content.hpp"
|
||||
#include "content/ContentLoader.hpp"
|
||||
#include "content/ContentControl.hpp"
|
||||
@ -311,7 +312,7 @@ static int l_get_textures(lua::State* L) {
|
||||
|
||||
static int l_get_model(lua::State* L) {
|
||||
if (auto def = require_block(L)) {
|
||||
return lua::pushstring(L, to_string(def->model));
|
||||
return lua::pushlstring(L, BlockModelMeta.getName(def->model));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#define VC_ENABLE_REFLECTION
|
||||
#include "libgui.hpp"
|
||||
#include "assets/Assets.hpp"
|
||||
#include "engine/Engine.hpp"
|
||||
@ -422,7 +423,7 @@ static int p_get_line_pos(UINode*, lua::State* L) {
|
||||
}
|
||||
|
||||
static int p_get_cursor(UINode* node, lua::State* L) {
|
||||
return lua::pushstring(L, to_string(node->getCursor()));
|
||||
return lua::pushlstring(L, CursorShapeMeta.getName(node->getCursor()));
|
||||
}
|
||||
|
||||
static int p_get_scroll(UINode* node, lua::State* L) {
|
||||
@ -660,9 +661,9 @@ static void p_set_focused(
|
||||
}
|
||||
|
||||
static void p_set_cursor(UINode* node, lua::State* L, int idx) {
|
||||
if (auto cursor = CursorShape_from(lua::require_string(L, idx))) {
|
||||
node->setCursor(*cursor);
|
||||
}
|
||||
auto cursor = CursorShape::ARROW; // reset to default
|
||||
CursorShapeMeta.getItem(lua::require_string(L, idx), cursor);
|
||||
node->setCursor(cursor);
|
||||
}
|
||||
|
||||
static int p_set_scroll(UINode* node, lua::State* L, int idx) {
|
||||
|
||||
@ -5,17 +5,6 @@
|
||||
#include <stdexcept>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
std::optional<InterpolationType> InterpolationType_from(std::string_view str) {
|
||||
if (str == "nearest") {
|
||||
return InterpolationType::NEAREST;
|
||||
} else if (str == "linear") {
|
||||
return InterpolationType::LINEAR;
|
||||
} else if (str == "cubic") {
|
||||
return InterpolationType::CUBIC;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static inline float sample_at(
|
||||
const float* buffer,
|
||||
uint width,
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
|
||||
#include "typedefs.hpp"
|
||||
#include "maths/Heightmap.hpp"
|
||||
#include "util/EnumMetadata.hpp"
|
||||
|
||||
enum class InterpolationType {
|
||||
NEAREST,
|
||||
@ -13,7 +14,11 @@ enum class InterpolationType {
|
||||
CUBIC,
|
||||
};
|
||||
|
||||
std::optional<InterpolationType> InterpolationType_from(std::string_view str);
|
||||
VC_ENUM_METADATA(InterpolationType)
|
||||
{"nearest", InterpolationType::NEAREST},
|
||||
{"linear", InterpolationType::LINEAR},
|
||||
{"cubic", InterpolationType::CUBIC},
|
||||
VC_ENUM_END
|
||||
|
||||
class Heightmap {
|
||||
uint width, height;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#define VC_ENABLE_REFLECTION
|
||||
#include "Entities.hpp"
|
||||
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
@ -216,9 +217,7 @@ void Entities::loadEntity(const dv::value& map, Entity entity) {
|
||||
dv::get_vec(bodymap, "vel", body.hitbox.velocity);
|
||||
std::string bodyTypeName;
|
||||
map.at("type").get(bodyTypeName);
|
||||
if (auto bodyType = BodyType_from(bodyTypeName)) {
|
||||
body.hitbox.type = *bodyType;
|
||||
}
|
||||
BodyTypeMeta.getItem(bodyTypeName, body.hitbox.type);
|
||||
bodymap["crouch"].asBoolean(body.hitbox.crouching);
|
||||
bodymap["damping"].asNumber(body.hitbox.linearDamping);
|
||||
}
|
||||
@ -329,7 +328,7 @@ dv::value Entities::serialize(const Entity& entity) {
|
||||
if (def.save.body.settings) {
|
||||
bodymap["damping"] = rigidbody.hitbox.linearDamping;
|
||||
if (hitbox.type != def.bodyType) {
|
||||
bodymap["type"] = to_string(hitbox.type);
|
||||
bodymap["type"] = BodyTypeMeta.getNameString(hitbox.type);
|
||||
}
|
||||
if (hitbox.crouching) {
|
||||
bodymap["crouch"] = hitbox.crouching;
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "interfaces/Serializable.hpp"
|
||||
#include "settings.hpp"
|
||||
|
||||
@ -2,26 +2,6 @@
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
std::optional<BodyType> BodyType_from(std::string_view str) {
|
||||
if (str == "kinematic") {
|
||||
return BodyType::KINEMATIC;
|
||||
} else if (str == "dynamic") {
|
||||
return BodyType::DYNAMIC;
|
||||
} else if (str == "static") {
|
||||
return BodyType::STATIC;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::string to_string(BodyType type) {
|
||||
switch (type) {
|
||||
case BodyType::KINEMATIC: return "kinematic";
|
||||
case BodyType::DYNAMIC: return "dynamic";
|
||||
case BodyType::STATIC: return "static";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
Hitbox::Hitbox(BodyType type, glm::vec3 position, glm::vec3 halfsize)
|
||||
: type(type),
|
||||
position(position),
|
||||
|
||||
@ -2,10 +2,10 @@
|
||||
|
||||
#include "maths/aabb.hpp"
|
||||
#include "typedefs.hpp"
|
||||
#include "util/EnumMetadata.hpp"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <functional>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
@ -41,8 +41,11 @@ enum class BodyType {
|
||||
STATIC, KINEMATIC, DYNAMIC
|
||||
};
|
||||
|
||||
std::optional<BodyType> BodyType_from(std::string_view str);
|
||||
std::string to_string(BodyType type);
|
||||
VC_ENUM_METADATA(BodyType)
|
||||
{"static", BodyType::STATIC},
|
||||
{"kinematic", BodyType::KINEMATIC},
|
||||
{"dynamic", BodyType::DYNAMIC},
|
||||
VC_ENUM_END
|
||||
|
||||
struct Hitbox {
|
||||
BodyType type;
|
||||
|
||||
@ -1,37 +1,13 @@
|
||||
#define VC_ENABLE_REFLECTION
|
||||
|
||||
#include "NotePreset.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "data/dv_util.hpp"
|
||||
|
||||
std::string to_string(NoteDisplayMode mode) {
|
||||
static std::vector<std::string> names = {
|
||||
"static_billboard",
|
||||
"y_free_billboard",
|
||||
"xy_free_billboard",
|
||||
"projected"
|
||||
};
|
||||
return names.at(static_cast<int>(mode));
|
||||
}
|
||||
|
||||
std::optional<NoteDisplayMode> NoteDisplayMode_from(std::string_view s) {
|
||||
static std::map<std::string_view, NoteDisplayMode, std::less<>> map {
|
||||
{"static_billboard", NoteDisplayMode::STATIC_BILLBOARD},
|
||||
{"y_free_billboard", NoteDisplayMode::Y_FREE_BILLBOARD},
|
||||
{"xy_free_billboard", NoteDisplayMode::XY_FREE_BILLBOARD},
|
||||
{"projected", NoteDisplayMode::PROJECTED}
|
||||
};
|
||||
const auto& found = map.find(s);
|
||||
if (found == map.end()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return found->second;
|
||||
}
|
||||
#include <vector>
|
||||
|
||||
dv::value NotePreset::serialize() const {
|
||||
return dv::object({
|
||||
{"display", to_string(displayMode)},
|
||||
{"display", NoteDisplayModeMeta.getNameString(displayMode)},
|
||||
{"color", dv::to_value(color)},
|
||||
{"scale", scale},
|
||||
{"render_distance", renderDistance},
|
||||
@ -42,7 +18,7 @@ dv::value NotePreset::serialize() const {
|
||||
|
||||
void NotePreset::deserialize(const dv::value& src) {
|
||||
if (src.has("display")) {
|
||||
displayMode = NoteDisplayMode_from(src["display"].asString()).value();
|
||||
NoteDisplayModeMeta.getItem(src["display"].asString(), displayMode);
|
||||
}
|
||||
if (src.has("color")) {
|
||||
dv::get_vec(src["color"], color);
|
||||
|
||||
@ -2,10 +2,10 @@
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "interfaces/Serializable.hpp"
|
||||
#include "util/EnumMetadata.hpp"
|
||||
|
||||
enum class NoteDisplayMode {
|
||||
STATIC_BILLBOARD,
|
||||
@ -14,8 +14,12 @@ enum class NoteDisplayMode {
|
||||
PROJECTED
|
||||
};
|
||||
|
||||
std::string to_string(NoteDisplayMode mode);
|
||||
std::optional<NoteDisplayMode> NoteDisplayMode_from(std::string_view s);
|
||||
VC_ENUM_METADATA(NoteDisplayMode)
|
||||
{"static_billboard", NoteDisplayMode::STATIC_BILLBOARD},
|
||||
{"y_free_billboard", NoteDisplayMode::Y_FREE_BILLBOARD},
|
||||
{"xy_free_billboard", NoteDisplayMode::XY_FREE_BILLBOARD},
|
||||
{"projected", NoteDisplayMode::PROJECTED},
|
||||
VC_ENUM_END
|
||||
|
||||
struct NotePreset : public Serializable {
|
||||
NoteDisplayMode displayMode = NoteDisplayMode::STATIC_BILLBOARD;
|
||||
|
||||
@ -1,26 +1,8 @@
|
||||
#define VC_ENABLE_REFLECTION
|
||||
|
||||
#include "ParticlesPreset.hpp"
|
||||
|
||||
#include "data/dv_util.hpp"
|
||||
|
||||
std::string to_string(ParticleSpawnShape shape) {
|
||||
static std::string names[] = {
|
||||
"ball",
|
||||
"sphere",
|
||||
"box"
|
||||
};
|
||||
return names[static_cast<int>(shape)];
|
||||
}
|
||||
|
||||
ParticleSpawnShape ParticleSpawnShape_from(std::string_view s) {
|
||||
if (s == "ball") {
|
||||
return ParticleSpawnShape::BALL;
|
||||
} else if (s == "sphere") {
|
||||
return ParticleSpawnShape::SPHERE;
|
||||
} else {
|
||||
return ParticleSpawnShape::BOX;
|
||||
}
|
||||
}
|
||||
|
||||
dv::value ParticlesPreset::serialize() const {
|
||||
auto root = dv::object();
|
||||
if (frames.empty()) {
|
||||
@ -47,7 +29,7 @@ dv::value ParticlesPreset::serialize() const {
|
||||
root["min_angular_vel"] = minAngularVelocity;
|
||||
root["max_angular_vel"] = maxAngularVelocity;
|
||||
root["spawn_spread"] = dv::to_value(size);
|
||||
root["spawn_shape"] = to_string(spawnShape);
|
||||
root["spawn_shape"] = ParticleSpawnShapeMeta.getName(spawnShape);
|
||||
root["random_sub_uv"] = randomSubUV;
|
||||
return root;
|
||||
}
|
||||
@ -82,7 +64,7 @@ void ParticlesPreset::deserialize(const dv::value& src) {
|
||||
dv::get_vec(src["explosion"], explosion);
|
||||
}
|
||||
if (src.has("spawn_shape")) {
|
||||
spawnShape = ParticleSpawnShape_from(src["spawn_shape"].asString());
|
||||
ParticleSpawnShapeMeta.getItem(src["spawn_shape"].asString(), spawnShape);
|
||||
}
|
||||
if (src.has("frames")) {
|
||||
for (const auto& frame : src["frames"]) {
|
||||
|
||||
@ -5,8 +5,9 @@
|
||||
#include <vector>
|
||||
|
||||
#include "interfaces/Serializable.hpp"
|
||||
#include "util/EnumMetadata.hpp"
|
||||
|
||||
enum ParticleSpawnShape {
|
||||
enum class ParticleSpawnShape {
|
||||
/// @brief Coordinates are regulary distributed within
|
||||
/// the volume of a ball.
|
||||
BALL = 0,
|
||||
@ -18,8 +19,11 @@ enum ParticleSpawnShape {
|
||||
BOX
|
||||
};
|
||||
|
||||
std::string to_string(ParticleSpawnShape shape);
|
||||
ParticleSpawnShape ParticleSpawnShape_from(std::string_view s);
|
||||
VC_ENUM_METADATA(ParticleSpawnShape)
|
||||
{"ball", ParticleSpawnShape::BALL},
|
||||
{"sphere", ParticleSpawnShape::SPHERE},
|
||||
{"box", ParticleSpawnShape::BOX},
|
||||
VC_ENUM_END
|
||||
|
||||
struct ParticlesPreset : public Serializable {
|
||||
/// @brief Collision detection
|
||||
@ -53,7 +57,7 @@ struct ParticlesPreset : public Serializable {
|
||||
/// @brief Maximum angular velocity
|
||||
float maxAngularVelocity = 0.0f;
|
||||
/// @brief Spawn spread shape
|
||||
ParticleSpawnShape spawnShape = BALL;
|
||||
ParticleSpawnShape spawnShape = ParticleSpawnShape::BALL;
|
||||
/// @brief Spawn spread
|
||||
glm::vec3 spawnSpread {};
|
||||
/// @brief Texture name
|
||||
|
||||
61
src/util/EnumMetadata.hpp
Normal file
61
src/util/EnumMetadata.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef VC_ENABLE_REFLECTION
|
||||
#define VC_ENUM_METADATA(NAME) static inline util::EnumMetadata<NAME> NAME##Meta {
|
||||
#define VC_ENUM_END };
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace util {
|
||||
template<typename EnumT>
|
||||
class EnumMetadata {
|
||||
public:
|
||||
EnumMetadata(
|
||||
std::initializer_list<std::pair<const std::string_view, EnumT>> items
|
||||
)
|
||||
: items(items) {
|
||||
for (const auto& [name, item] : items) {
|
||||
names[item] = name;
|
||||
}
|
||||
}
|
||||
|
||||
std::string_view getName(EnumT item) const {
|
||||
const auto& found = names.find(item);
|
||||
if (found == names.end()) {
|
||||
return "";
|
||||
}
|
||||
return found->second;
|
||||
}
|
||||
|
||||
std::string getNameString(EnumT item) const {
|
||||
return std::string(getName(item));
|
||||
}
|
||||
|
||||
bool getItem(std::string_view name, EnumT& dst) const {
|
||||
const auto& found = items.find(name);
|
||||
if (found == items.end()) {
|
||||
return false;
|
||||
}
|
||||
dst = found->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return items.size();
|
||||
}
|
||||
private:
|
||||
std::map<std::string_view, EnumT> items;
|
||||
std::map<EnumT, std::string_view> names;
|
||||
};
|
||||
}
|
||||
|
||||
#else
|
||||
#include <initializer_list>
|
||||
|
||||
#define VC_ENUM_METADATA(NAME) \
|
||||
struct NAME##__PAIR {const char* n; NAME i;}; \
|
||||
[[maybe_unused]] static inline std::initializer_list<NAME##__PAIR> NAME##_PAIRS {
|
||||
#define VC_ENUM_END };
|
||||
#endif // VC_ENABLE_REFLECTION
|
||||
@ -18,62 +18,6 @@ dv::value BlockMaterial::serialize() const {
|
||||
});
|
||||
}
|
||||
|
||||
std::string to_string(BlockModel model) {
|
||||
switch (model) {
|
||||
case BlockModel::none:
|
||||
return "none";
|
||||
case BlockModel::block:
|
||||
return "block";
|
||||
case BlockModel::xsprite:
|
||||
return "X";
|
||||
case BlockModel::aabb:
|
||||
return "aabb";
|
||||
case BlockModel::custom:
|
||||
return "custom";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<BlockModel> BlockModel_from(std::string_view str) {
|
||||
if (str == "none") {
|
||||
return BlockModel::none;
|
||||
} else if (str == "block") {
|
||||
return BlockModel::block;
|
||||
} else if (str == "X") {
|
||||
return BlockModel::xsprite;
|
||||
} else if (str == "aabb") {
|
||||
return BlockModel::aabb;
|
||||
} else if (str == "custom") {
|
||||
return BlockModel::custom;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::string to_string(CullingMode mode) {
|
||||
switch (mode) {
|
||||
case CullingMode::DEFAULT:
|
||||
return "default";
|
||||
case CullingMode::OPTIONAL:
|
||||
return "optional";
|
||||
case CullingMode::DISABLED:
|
||||
return "disabled";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<CullingMode> CullingMode_from(std::string_view str) {
|
||||
if (str == "default") {
|
||||
return CullingMode::DEFAULT;
|
||||
} else if (str == "optional") {
|
||||
return CullingMode::OPTIONAL;
|
||||
} else if (str == "disabled") {
|
||||
return CullingMode::DISABLED;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
CoordSystem::CoordSystem(glm::ivec3 axisX, glm::ivec3 axisY, glm::ivec3 axisZ)
|
||||
: axes({axisX, axisY, axisZ}) {
|
||||
fix = glm::ivec3(0);
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
@ -10,6 +9,7 @@
|
||||
#include "maths/UVRegion.hpp"
|
||||
#include "maths/aabb.hpp"
|
||||
#include "typedefs.hpp"
|
||||
#include "util/EnumMetadata.hpp"
|
||||
|
||||
struct ParticlesPreset;
|
||||
|
||||
@ -93,8 +93,13 @@ enum class BlockModel {
|
||||
custom
|
||||
};
|
||||
|
||||
std::string to_string(BlockModel model);
|
||||
std::optional<BlockModel> BlockModel_from(std::string_view str);
|
||||
VC_ENUM_METADATA(BlockModel)
|
||||
{"none", BlockModel::none},
|
||||
{"block", BlockModel::block},
|
||||
{"X", BlockModel::xsprite},
|
||||
{"aabb", BlockModel::aabb},
|
||||
{"custom", BlockModel::custom},
|
||||
VC_ENUM_END
|
||||
|
||||
enum class CullingMode {
|
||||
DEFAULT,
|
||||
@ -102,8 +107,11 @@ enum class CullingMode {
|
||||
DISABLED,
|
||||
};
|
||||
|
||||
std::string to_string(CullingMode mode);
|
||||
std::optional<CullingMode> CullingMode_from(std::string_view str);
|
||||
VC_ENUM_METADATA(CullingMode)
|
||||
{"default", CullingMode::DEFAULT},
|
||||
{"optional", CullingMode::OPTIONAL},
|
||||
{"disabled", CullingMode::DISABLED},
|
||||
VC_ENUM_END
|
||||
|
||||
using BoxModel = AABB;
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#define VC_ENABLE_REFLECTION
|
||||
#include "World.hpp"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
@ -49,7 +50,7 @@ void World::updateTimers(float delta) {
|
||||
void World::writeResources(const Content& content) {
|
||||
auto root = dv::object();
|
||||
for (size_t typeIndex = 0; typeIndex < RESOURCE_TYPES_COUNT; typeIndex++) {
|
||||
auto typeName = to_string(static_cast<ResourceType>(typeIndex));
|
||||
auto typeName = ResourceTypeMeta.getNameString(static_cast<ResourceType>(typeIndex));
|
||||
auto& list = root.list(typeName);
|
||||
auto& indices = content.resourceIndices[typeIndex];
|
||||
for (size_t i = 0; i < indices.size(); i++) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#define VC_ENABLE_REFLECTION
|
||||
#include "WorldFiles.hpp"
|
||||
|
||||
#include <cassert>
|
||||
@ -182,8 +183,9 @@ bool WorldFiles::readResourcesData(const Content& content) {
|
||||
}
|
||||
auto root = io::read_json(file);
|
||||
for (const auto& [key, arr] : root.asObject()) {
|
||||
if (auto resType = ResourceType_from(key)) {
|
||||
read_resources_data(content, arr, *resType);
|
||||
ResourceType type;
|
||||
if (ResourceTypeMeta.getItem(key, type)) {
|
||||
read_resources_data(content, arr, type);
|
||||
} else {
|
||||
logger.warning() << "unknown resource type: " << key;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user