#define flecs_meta_STATIC #ifndef FLECS_META_H #define FLECS_META_H /* This generated file contains includes for project dependencies */ /* ) (.) .|. | | _.--| |--._ .-'; ;`-'& ; `&. \ & ; & &_/ |"""---...---"""| \ | | | | | | | / `---.|.|.|.---' * This file is generated by bake.lang.c for your convenience. Headers of * dependencies will automatically show up in this file. Include bake_config.h * in your main project file. Do not edit! */ #ifndef FLECS_META_BAKE_CONFIG_H #define FLECS_META_BAKE_CONFIG_H /* Headers of public dependencies */ #include /* Convenience macro for exporting symbols */ #ifndef flecs_meta_STATIC #if flecs_meta_EXPORTS && (defined(_MSC_VER) || defined(__MINGW32__)) #define FLECS_META_API __declspec(dllexport) #elif flecs_meta_EXPORTS #define FLECS_META_API __attribute__((__visibility__("default"))) #elif defined _MSC_VER #define FLECS_META_API __declspec(dllimport) #else #define FLECS_META_API #endif #else #define FLECS_META_API #endif #endif #ifndef FLECS_LEGACY //////////////////////////////////////////////////////////////////////////////// //// Utility macro's (do not use in code!) //////////////////////////////////////////////////////////////////////////////// #define ECS_ENUM_BOOTSTRAP(name, ...)\ typedef enum name __VA_ARGS__ name;\ ECS_UNUSED \ static const char * __##name##__ = #__VA_ARGS__ #define ECS_STRUCT_IMPL(name, descriptor, ...)\ typedef struct name __VA_ARGS__ name;\ ECS_UNUSED \ static EcsMetaType __##name##__ = {EcsStructType, sizeof(name), ECS_ALIGNOF(name), descriptor, NULL}\ #define ECS_ENUM_IMPL(name, descriptor, ...)\ typedef enum name __VA_ARGS__ name;\ ECS_UNUSED \ static EcsMetaType __##name##__ = {EcsEnumType, sizeof(name), ECS_ALIGNOF(name), descriptor, NULL} #define ECS_BITMASK_IMPL(name, descriptor, ...)\ typedef enum name __VA_ARGS__ name;\ ECS_UNUSED \ static EcsMetaType __##name##__ = {EcsBitmaskType, sizeof(name), ECS_ALIGNOF(name), descriptor, NULL} #define ECS_STRUCT_C(T, ...) ECS_STRUCT_IMPL(T, #__VA_ARGS__, __VA_ARGS__) #define ECS_ENUM_C(T, ...) ECS_ENUM_IMPL(T, #__VA_ARGS__, __VA_ARGS__) #define ECS_BITMASK_C(T, ...) ECS_BITMASK_IMPL(T, #__VA_ARGS__, __VA_ARGS__) #define ECS_ARRAY(name, T, length)\ typedef T name[length];\ ECS_UNUSED \ static EcsMetaType __##name##__ = {EcsArrayType, sizeof(T) * length, ECS_ALIGNOF(T), "(" #T "," #length ")", NULL} #define ECS_VECTOR(name, T)\ typedef ecs_vector_t *name;\ ECS_UNUSED \ static EcsMetaType __##name##__ = {EcsVectorType, sizeof(ecs_vector_t*), ECS_ALIGNOF(ecs_vector_t*), "(" #T ")", NULL} #define ECS_MAP(name, K, T)\ typedef ecs_map_t *name;\ ECS_UNUSED \ static EcsMetaType __##name##__ = {EcsMapType, sizeof(ecs_map_t*), ECS_ALIGNOF(ecs_map_t*), "(" #K "," #T ")", NULL} #ifdef __cplusplus // Unspecialized class (see below) namespace flecs { template class __meta__ { }; } // Specialized C++ class that stores name and descriptor of type #define ECS_META_CPP(T, kind, descr);\ namespace flecs {\ template<>\ class __meta__ {\ public:\ static const char* name() {\ return #T;\ }\ static EcsMetaType descriptor() {\ return {kind, sizeof(T), ECS_ALIGNOF(T), descr, NULL};\ }\ };\ } #endif //////////////////////////////////////////////////////////////////////////////// //// Use these macro's to define types. //// The API will automatically select the right macro's for C or C++ //////////////////////////////////////////////////////////////////////////////// #ifdef __cplusplus // C++ // Define a struct #define ECS_STRUCT(T, ...)\ ECS_STRUCT_IMPL(T, #__VA_ARGS__, __VA_ARGS__);\ ECS_META_CPP(T, EcsStructType, #__VA_ARGS__) // Define an enumeration #define ECS_ENUM(T, ...)\ ECS_ENUM_IMPL(T, #__VA_ARGS__, __VA_ARGS__);\ ECS_META_CPP(T, EcsEnumType, #__VA_ARGS__); // Define a bitmask #define ECS_BITMASK(T, ...)\ ECS_BITMASK_IMPL(T, #__VA_ARGS__, __VA_ARGS__);\ ECS_META_CPP(T, EcsBitmaskType, #__VA_ARGS__) #else // C // Define a struct #define ECS_STRUCT(name, ...)\ ECS_STRUCT_IMPL(name, #__VA_ARGS__, __VA_ARGS__) // Define an enumeration #define ECS_ENUM(name, ...)\ ECS_ENUM_IMPL(name, #__VA_ARGS__, __VA_ARGS__) // Define a bitmask #define ECS_BITMASK(name, ...)\ ECS_BITMASK_IMPL(name, #__VA_ARGS__, __VA_ARGS__) // Define a type alias #define ECS_ALIAS(type, name)\ typedef type name;\ ECS_UNUSED \ static EcsMetaType __##name##__ = {0, sizeof(name), ECS_ALIGNOF(name), NULL, &__##type##__};\ #endif //////////////////////////////////////////////////////////////////////////////// //// Use these macro's inside types //////////////////////////////////////////////////////////////////////////////// // Define a vector #define ecs_vector(T) ecs_vector_t* // Define a map #define ecs_map(K, T) ecs_map_t* // Indicate that members after this should not be serialized #define ECS_PRIVATE //////////////////////////////////////////////////////////////////////////////// //// Meta description types //////////////////////////////////////////////////////////////////////////////// /* Explicit string type */ typedef const char* ecs_string_t; /* Explicit byte type */ typedef uint8_t ecs_byte_t; #ifdef __cplusplus namespace flecs { using string = ecs_string_t; using byte = ecs_byte_t; // Define a bitmask // In C++ trying to assign multiple flags to a variable of an enum type will // result in a compiler error. Use this template so that the serializer knows // this value is a bitmask, while also keeping the compiler happy. template using bitmask = int32_t; } #endif ECS_ENUM_BOOTSTRAP( ecs_type_kind_t, { EcsPrimitiveType, EcsBitmaskType, EcsEnumType, EcsStructType, EcsArrayType, EcsVectorType, EcsMapType }); ECS_STRUCT( EcsMetaType, { ecs_type_kind_t kind; ecs_size_t size; int16_t alignment; const char *descriptor; void *alias; }); ECS_ENUM( ecs_primitive_kind_t, { EcsBool, EcsChar, EcsByte, EcsU8, EcsU16, EcsU32, EcsU64, EcsI8, EcsI16, EcsI32, EcsI64, EcsF32, EcsF64, EcsUPtr, EcsIPtr, EcsString, EcsEntity }); ECS_STRUCT( EcsPrimitive, { ecs_primitive_kind_t kind; }); // Define EcsBitmask for both C and C++. Both representations are equivalent in // memory, but allow for a nicer type-safe API in C++ #if defined(__cplusplus) && !defined(FLECS_NO_CPP) ECS_STRUCT( EcsBitmask, { flecs::map constants; }); #else ECS_STRUCT( EcsBitmask, { ecs_map(int32_t, ecs_string_t) constants; }); #endif // Define EcsEnum for both C and C++. Both representations are equivalent in // memory, but allow for a nicer type-safe API in C++ #if defined(__cplusplus) && !defined(FLECS_NO_CPP) ECS_STRUCT( EcsEnum, { flecs::map constants; }); #else ECS_STRUCT( EcsEnum, { ecs_map(int32_t, ecs_string_t) constants; }); #endif ECS_STRUCT( EcsMember, { char *name; ecs_entity_t type; }); // Define EcsStruct for both C and C++. Both representations are equivalent in // memory, but allow for a nicer type-safe API in C++ #if defined(__cplusplus) && !defined(FLECS_NO_CPP) ECS_STRUCT( EcsStruct, { flecs::vector members; bool is_partial; }); #else ECS_STRUCT( EcsStruct, { ecs_vector(EcsMember) members; bool is_partial; }); #endif ECS_STRUCT( EcsArray, { ecs_entity_t element_type; int32_t count; }); ECS_STRUCT( EcsVector, { ecs_entity_t element_type; }); ECS_STRUCT( EcsMap, { ecs_entity_t key_type; ecs_entity_t element_type; }); //////////////////////////////////////////////////////////////////////////////// //// Type serializer //////////////////////////////////////////////////////////////////////////////// ECS_ENUM_C( ecs_type_op_kind_t, { EcsOpHeader, EcsOpPrimitive, EcsOpEnum, EcsOpBitmask, EcsOpPush, EcsOpPop, EcsOpArray, EcsOpVector, EcsOpMap }); typedef ecs_vector_t ecs_type_op_vector_t; typedef ecs_vector_t ecs_constant_vector_t; ECS_STRUCT_C( ecs_type_op_t, { ecs_entity_t type; ecs_type_op_kind_t kind; ecs_size_t size; /* Size of value or element type if array or vector */ int16_t alignment; /* Alignment of value */ int32_t count; /* Number of elements (only used for arrays) */ int32_t offset; /* Offset of value */ const char *name; /* Name of value (only used for struct members) */ ECS_PRIVATE /* Instruction-specific data */ union { ecs_primitive_kind_t primitive; ecs_ref_t constant; ecs_ref_t collection; struct { ecs_ref_t key; ecs_ref_t element; } map; } is; }); ECS_STRUCT_C( EcsMetaTypeSerializer, { ecs_vector(ecs_type_op_t) ops; }); #endif #ifdef __cplusplus extern "C" { #endif //////////////////////////////////////////////////////////////////////////////// //// Pretty printer //////////////////////////////////////////////////////////////////////////////// /** Convert value to a string. */ FLECS_META_API char* ecs_ptr_to_str( ecs_world_t *world, ecs_entity_t type, void* ptr); /** Convert value to a string. */ FLECS_META_API char* ecs_entity_to_str( ecs_world_t *world, ecs_entity_t entity); //////////////////////////////////////////////////////////////////////////////// //// Serialization utilities //////////////////////////////////////////////////////////////////////////////// #define ECS_MAX_I8 127 #define ECS_MIN_I8 -128 #define ECS_MAX_I16 32767 #define ECS_MIN_I16 -32768 #define ECS_MAX_I32 2147483647 #define ECS_MIN_I32 -2147483648 #define ECS_MAX_I64 9223372036854775807 #define ECS_MIN_I64 (-9223372036854775807 - 1) #define ECS_MAX_U8 255u #define ECS_MAX_U16 65535u #define ECS_MAX_U32 4294967295u #define ECS_MAX_U64 18446744073709551615u #define ECS_MAX_I8_STR "127" #define ECS_MIN_I8_STR "-128" #define ECS_MAX_I16_STR "32767" #define ECS_MIN_I16_STR "-32768" #define ECS_MAX_I32_STR "2147483647" #define ECS_MIN_I32_STR "-2147483648" #define ECS_MAX_I64_STR "9223372036854775807" #define ECS_MIN_I64_STR "-9223372036854775808" #define ECS_MAX_U8_STR "255" #define ECS_MAX_U16_STR "65535" #define ECS_MAX_U32_STR "4294967295" #define ECS_MAX_U64_STR "18446744073709551615" /** Escape a character */ FLECS_META_API char* ecs_chresc( char *out, char in, char delimiter); /** Parse an escaped character */ FLECS_META_API const char* ecs_chrparse( const char *in, char *out); /** Escape a string */ FLECS_META_API ecs_size_t ecs_stresc( char *out, ecs_size_t n, char delimiter, const char *in); #ifdef __cplusplus } #endif //////////////////////////////////////////////////////////////////////////////// //// Deserialization API //////////////////////////////////////////////////////////////////////////////// #define ECS_META_MAX_SCOPE_DEPTH (32) /* >32 levels of nesting is not sane */ typedef struct ecs_meta_scope_t { ecs_entity_t type; ecs_vector_t *ops; int32_t start; int32_t cur_op; int32_t cur_elem; int32_t count; void *base; ecs_vector_t *vector; bool is_collection; } ecs_meta_scope_t; typedef struct ecs_meta_cursor_t { ecs_world_t *world; ecs_meta_scope_t scope[ECS_META_MAX_SCOPE_DEPTH]; int32_t depth; } ecs_meta_cursor_t; FLECS_META_API ecs_meta_cursor_t ecs_meta_cursor( ecs_world_t *world, ecs_entity_t type, void *base); FLECS_META_API void* ecs_meta_get_ptr( ecs_meta_cursor_t *cursor); FLECS_META_API int ecs_meta_next( ecs_meta_cursor_t *cursor); FLECS_META_API int ecs_meta_move( ecs_meta_cursor_t *cursor, int32_t pos); FLECS_META_API int ecs_meta_move_name( ecs_meta_cursor_t *cursor, const char *name); FLECS_META_API int ecs_meta_push( ecs_meta_cursor_t *cursor); FLECS_META_API int ecs_meta_pop( ecs_meta_cursor_t *cursor); FLECS_META_API int ecs_meta_set_bool( ecs_meta_cursor_t *cursor, bool value); FLECS_META_API int ecs_meta_set_char( ecs_meta_cursor_t *cursor, char value); FLECS_META_API int ecs_meta_set_int( ecs_meta_cursor_t *cursor, int64_t value); FLECS_META_API int ecs_meta_set_uint( ecs_meta_cursor_t *cursor, uint64_t value); FLECS_META_API int ecs_meta_set_float( ecs_meta_cursor_t *cursor, double value); FLECS_META_API int ecs_meta_set_string( ecs_meta_cursor_t *cursor, const char *value); FLECS_META_API int ecs_meta_set_entity( ecs_meta_cursor_t *cursor, ecs_entity_t value); FLECS_META_API int ecs_meta_set_null( ecs_meta_cursor_t *cursor); //////////////////////////////////////////////////////////////////////////////// //// Module implementation //////////////////////////////////////////////////////////////////////////////// typedef struct FlecsMeta { ECS_DECLARE_COMPONENT(EcsPrimitive); ECS_DECLARE_COMPONENT(EcsEnum); ECS_DECLARE_COMPONENT(EcsBitmask); ECS_DECLARE_COMPONENT(EcsStruct); ECS_DECLARE_COMPONENT(EcsArray); ECS_DECLARE_COMPONENT(EcsVector); ECS_DECLARE_COMPONENT(EcsMap); ECS_DECLARE_COMPONENT(EcsMetaType); ECS_DECLARE_COMPONENT(EcsMetaTypeSerializer); } FlecsMeta; #ifdef __cplusplus extern "C" { #endif FLECS_META_API void FlecsMetaImport( ecs_world_t *world); #define FlecsMetaImportHandles(handles)\ ECS_IMPORT_COMPONENT(handles, EcsPrimitive);\ ECS_IMPORT_COMPONENT(handles, EcsEnum);\ ECS_IMPORT_COMPONENT(handles, EcsBitmask);\ ECS_IMPORT_COMPONENT(handles, EcsStruct);\ ECS_IMPORT_COMPONENT(handles, EcsArray);\ ECS_IMPORT_COMPONENT(handles, EcsVector);\ ECS_IMPORT_COMPONENT(handles, EcsMap);\ ECS_IMPORT_COMPONENT(handles, EcsMetaType);\ ECS_IMPORT_COMPONENT(handles, EcsMetaTypeSerializer); //////////////////////////////////////////////////////////////////////////////// //// Macro for inserting metadata in C application //////////////////////////////////////////////////////////////////////////////// FLECS_META_API void ecs_new_meta( ecs_world_t *world, ecs_entity_t component, struct EcsMetaType *meta_type); #define ECS_META(world, T)\ ECS_COMPONENT(world, T);\ ecs_new_meta(world, ecs_entity(T), &__##T##__); #ifdef __cplusplus } #endif //////////////////////////////////////////////////////////////////////////////// //// C++ Module implementation //////////////////////////////////////////////////////////////////////////////// #ifdef __cplusplus #ifndef FLECS_NO_CPP namespace flecs { namespace components { class meta { public: using Primitive = EcsPrimitive; using Enum = EcsEnum; using Bitmask = EcsBitmask; using Struct = EcsStruct; using Array = EcsArray; using Vector = EcsVector; using Type = EcsMetaType; using TypeSerializer = EcsMetaTypeSerializer; enum TypeKind { PrimitiveType = EcsPrimitiveType, BitmaskType = EcsBitmaskType, EnumType = EcsEnumType, StructType = EcsStructType, ArrayType = EcsArrayType, VectorType = EcsVectorType, MapType = EcsMapType }; meta(flecs::world& world) { FlecsMetaImport(world.c_ptr()); flecs::module(world, "flecs::components::meta"); flecs::component(world, "EcsPrimitive"); flecs::component(world, "EcsEnum"); flecs::component(world, "EcsBitmask"); flecs::component(world, "EcsStruct"); flecs::component(world, "EcsArray"); flecs::component(world, "EcsVector"); flecs::component(world, "EcsMetaType"); flecs::component(world, "EcsMetaTypeSerializer"); } }; } //////////////////////////////////////////////////////////////////////////////// //// Functions for inserting metadata in C++ applications //////////////////////////////////////////////////////////////////////////////// // Template that injects metadata into ECS template flecs::entity meta(flecs::world& world) { flecs::entity e = flecs::component(world, flecs::__meta__::name()); e.set({ flecs::__meta__::descriptor() }); return e; } //////////////////////////////////////////////////////////////////////////////// //// Serialize values to string //////////////////////////////////////////////////////////////////////////////// template std::string pretty_print(flecs::world& world, flecs::entity_t type, T& data) { char *str = ecs_ptr_to_str(world.c_ptr(), type, &data); std::string result = std::string(str); free(str); return result; } template std::string pretty_print(flecs::world& world, flecs::entity type, T& data) { return pretty_print(world, type.id(), data); } template std::string pretty_print(flecs::world& world, T& data) { entity_t type = _::component_info::id(); return flecs::pretty_print(world, type, data); } template <> inline std::string pretty_print(flecs::world& world, flecs::entity& entity) { char *str = ecs_entity_to_str(world.c_ptr(), entity.id()); std::string result = std::string(str); free(str); return result; } } #endif // FLECS_NO_CPP #endif // __cplusplus #endif // FLECS_META_H