diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b0a27409b..7a8b358242 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ option(FLECS_STATIC "Build static flecs lib" ON) option(FLECS_SHARED "Build shared flecs lib" ON) option(FLECS_PIC "Compile static flecs lib with position independent code (PIC)" ON) option(FLECS_TESTS "Build flecs tests" OFF) +option(FLECS_M0DULE "Build flecs C++20 module" OFF) include(cmake/target_default_compile_warnings.cmake) include(cmake/target_default_compile_options.cmake) @@ -75,6 +76,10 @@ if(FLECS_TESTS) add_subdirectory(test) endif() +if(FLECS_M0DULE) + add_subdirectory(module) +endif() + message(STATUS "Targets: ${FLECS_TARGETS}") # define the install steps diff --git a/distr/flecs.h b/distr/flecs.h index 1db12b5aaa..bda89f1ae6 100644 --- a/distr/flecs.h +++ b/distr/flecs.h @@ -16405,6 +16405,7 @@ ecs_entity_t ecs_module_init( #ifdef FLECS_NO_CPP #error "FLECS_NO_CPP failed: CPP is required by other addons" #endif + /** * @file addons/flecs_cpp.h * @brief C++ utility functions @@ -16541,6 +16542,8 @@ const ecs_member_t* ecs_cpp_last_member( #endif // FLECS_CPP +#ifndef FLECS_CPP20_MODULE_HEADER + #ifdef __cplusplus /** * @file addons/cpp/flecs.hpp @@ -16550,7 +16553,17 @@ const ecs_member_t* ecs_cpp_last_member( #pragma once // STL includes +#ifndef FLECS_CUSTOM_STD_INCLUDE #include +#endif + +#ifndef FLECS_API_STRUCT +#define FLECS_API_STRUCT +#endif + +#ifndef FLECS_API_GLOBAL +#define FLECS_API_GLOBAL static +#endif /** * @defgroup cpp C++ API @@ -16560,19 +16573,21 @@ const ecs_member_t* ecs_cpp_last_member( namespace flecs { -struct world; -struct world_async_stage; -struct iter; -struct entity_view; -struct entity; -struct type; -struct table; -struct table_range; -struct untyped_component; - +FLECS_API_STRUCT struct world; +FLECS_API_STRUCT struct world_async_stage; +FLECS_API_STRUCT struct iter; +FLECS_API_STRUCT struct entity_view; +FLECS_API_STRUCT struct entity; +FLECS_API_STRUCT struct type; +FLECS_API_STRUCT struct table; +FLECS_API_STRUCT struct table_range; +FLECS_API_STRUCT struct untyped_component; + +FLECS_API_STRUCT template struct component; +FLECS_API_STRUCT template struct ref; @@ -16663,96 +16678,96 @@ using Poly = EcsPoly; using DefaultChildComponent = EcsDefaultChildComponent; /* Builtin tags */ -static const flecs::entity_t Query = EcsQuery; -static const flecs::entity_t Observer = EcsObserver; -static const flecs::entity_t Private = EcsPrivate; -static const flecs::entity_t Module = EcsModule; -static const flecs::entity_t Prefab = EcsPrefab; -static const flecs::entity_t Disabled = EcsDisabled; -static const flecs::entity_t Empty = EcsEmpty; -static const flecs::entity_t Monitor = EcsMonitor; -static const flecs::entity_t System = EcsSystem; -static const flecs::entity_t Pipeline = ecs_id(EcsPipeline); -static const flecs::entity_t Phase = EcsPhase; +FLECS_API_GLOBAL const flecs::entity_t Query = EcsQuery; +FLECS_API_GLOBAL const flecs::entity_t Observer = EcsObserver; +FLECS_API_GLOBAL const flecs::entity_t Private = EcsPrivate; +FLECS_API_GLOBAL const flecs::entity_t Module = EcsModule; +FLECS_API_GLOBAL const flecs::entity_t Prefab = EcsPrefab; +FLECS_API_GLOBAL const flecs::entity_t Disabled = EcsDisabled; +FLECS_API_GLOBAL const flecs::entity_t Empty = EcsEmpty; +FLECS_API_GLOBAL const flecs::entity_t Monitor = EcsMonitor; +FLECS_API_GLOBAL const flecs::entity_t System = EcsSystem; +FLECS_API_GLOBAL const flecs::entity_t Pipeline = ecs_id(EcsPipeline); +FLECS_API_GLOBAL const flecs::entity_t Phase = EcsPhase; /* Builtin event tags */ -static const flecs::entity_t OnAdd = EcsOnAdd; -static const flecs::entity_t OnRemove = EcsOnRemove; -static const flecs::entity_t OnSet = EcsOnSet; -static const flecs::entity_t OnTableCreate = EcsOnTableCreate; -static const flecs::entity_t OnTableDelete = EcsOnTableDelete; +FLECS_API_GLOBAL const flecs::entity_t OnAdd = EcsOnAdd; +FLECS_API_GLOBAL const flecs::entity_t OnRemove = EcsOnRemove; +FLECS_API_GLOBAL const flecs::entity_t OnSet = EcsOnSet; +FLECS_API_GLOBAL const flecs::entity_t OnTableCreate = EcsOnTableCreate; +FLECS_API_GLOBAL const flecs::entity_t OnTableDelete = EcsOnTableDelete; /* Builtin term flags */ -static const uint64_t Self = EcsSelf; -static const uint64_t Up = EcsUp; -static const uint64_t Trav = EcsTrav; -static const uint64_t Cascade = EcsCascade; -static const uint64_t Desc = EcsDesc; -static const uint64_t IsVariable = EcsIsVariable; -static const uint64_t IsEntity = EcsIsEntity; -static const uint64_t IsName = EcsIsName; -static const uint64_t TraverseFlags = EcsTraverseFlags; -static const uint64_t TermRefFlags = EcsTermRefFlags; +FLECS_API_GLOBAL const uint64_t Self = EcsSelf; +FLECS_API_GLOBAL const uint64_t Up = EcsUp; +FLECS_API_GLOBAL const uint64_t Trav = EcsTrav; +FLECS_API_GLOBAL const uint64_t Cascade = EcsCascade; +FLECS_API_GLOBAL const uint64_t Desc = EcsDesc; +FLECS_API_GLOBAL const uint64_t IsVariable = EcsIsVariable; +FLECS_API_GLOBAL const uint64_t IsEntity = EcsIsEntity; +FLECS_API_GLOBAL const uint64_t IsName = EcsIsName; +FLECS_API_GLOBAL const uint64_t TraverseFlags = EcsTraverseFlags; +FLECS_API_GLOBAL const uint64_t TermRefFlags = EcsTermRefFlags; /* Builtin entity ids */ -static const flecs::entity_t Flecs = EcsFlecs; -static const flecs::entity_t FlecsCore = EcsFlecsCore; -static const flecs::entity_t World = EcsWorld; +FLECS_API_GLOBAL const flecs::entity_t Flecs = EcsFlecs; +FLECS_API_GLOBAL const flecs::entity_t FlecsCore = EcsFlecsCore; +FLECS_API_GLOBAL const flecs::entity_t World = EcsWorld; /* Component traits */ -static const flecs::entity_t Wildcard = EcsWildcard; -static const flecs::entity_t Any = EcsAny; -static const flecs::entity_t This = EcsThis; -static const flecs::entity_t Transitive = EcsTransitive; -static const flecs::entity_t Reflexive = EcsReflexive; -static const flecs::entity_t Final = EcsFinal; -static const flecs::entity_t PairIsTag = EcsPairIsTag; -static const flecs::entity_t Exclusive = EcsExclusive; -static const flecs::entity_t Acyclic = EcsAcyclic; -static const flecs::entity_t Traversable = EcsTraversable; -static const flecs::entity_t Symmetric = EcsSymmetric; -static const flecs::entity_t With = EcsWith; -static const flecs::entity_t OneOf = EcsOneOf; -static const flecs::entity_t Trait = EcsTrait; -static const flecs::entity_t Relationship = EcsRelationship; -static const flecs::entity_t Target = EcsTarget; -static const flecs::entity_t CanToggle = EcsCanToggle; +FLECS_API_GLOBAL const flecs::entity_t Wildcard = EcsWildcard; +FLECS_API_GLOBAL const flecs::entity_t Any = EcsAny; +FLECS_API_GLOBAL const flecs::entity_t This = EcsThis; +FLECS_API_GLOBAL const flecs::entity_t Transitive = EcsTransitive; +FLECS_API_GLOBAL const flecs::entity_t Reflexive = EcsReflexive; +FLECS_API_GLOBAL const flecs::entity_t Final = EcsFinal; +FLECS_API_GLOBAL const flecs::entity_t PairIsTag = EcsPairIsTag; +FLECS_API_GLOBAL const flecs::entity_t Exclusive = EcsExclusive; +FLECS_API_GLOBAL const flecs::entity_t Acyclic = EcsAcyclic; +FLECS_API_GLOBAL const flecs::entity_t Traversable = EcsTraversable; +FLECS_API_GLOBAL const flecs::entity_t Symmetric = EcsSymmetric; +FLECS_API_GLOBAL const flecs::entity_t With = EcsWith; +FLECS_API_GLOBAL const flecs::entity_t OneOf = EcsOneOf; +FLECS_API_GLOBAL const flecs::entity_t Trait = EcsTrait; +FLECS_API_GLOBAL const flecs::entity_t Relationship = EcsRelationship; +FLECS_API_GLOBAL const flecs::entity_t Target = EcsTarget; +FLECS_API_GLOBAL const flecs::entity_t CanToggle = EcsCanToggle; /* OnInstantiate trait */ -static const flecs::entity_t OnInstantiate = EcsOnInstantiate; -static const flecs::entity_t Override = EcsOverride; -static const flecs::entity_t Inherit = EcsInherit; -static const flecs::entity_t DontInherit = EcsDontInherit; +FLECS_API_GLOBAL const flecs::entity_t OnInstantiate = EcsOnInstantiate; +FLECS_API_GLOBAL const flecs::entity_t Override = EcsOverride; +FLECS_API_GLOBAL const flecs::entity_t Inherit = EcsInherit; +FLECS_API_GLOBAL const flecs::entity_t DontInherit = EcsDontInherit; /* OnDelete/OnDeleteTarget traits */ -static const flecs::entity_t OnDelete = EcsOnDelete; -static const flecs::entity_t OnDeleteTarget = EcsOnDeleteTarget; -static const flecs::entity_t Remove = EcsRemove; -static const flecs::entity_t Delete = EcsDelete; -static const flecs::entity_t Panic = EcsPanic; +FLECS_API_GLOBAL const flecs::entity_t OnDelete = EcsOnDelete; +FLECS_API_GLOBAL const flecs::entity_t OnDeleteTarget = EcsOnDeleteTarget; +FLECS_API_GLOBAL const flecs::entity_t Remove = EcsRemove; +FLECS_API_GLOBAL const flecs::entity_t Delete = EcsDelete; +FLECS_API_GLOBAL const flecs::entity_t Panic = EcsPanic; /* Builtin relationships */ -static const flecs::entity_t IsA = EcsIsA; -static const flecs::entity_t ChildOf = EcsChildOf; -static const flecs::entity_t DependsOn = EcsDependsOn; -static const flecs::entity_t SlotOf = EcsSlotOf; +FLECS_API_GLOBAL const flecs::entity_t IsA = EcsIsA; +FLECS_API_GLOBAL const flecs::entity_t ChildOf = EcsChildOf; +FLECS_API_GLOBAL const flecs::entity_t DependsOn = EcsDependsOn; +FLECS_API_GLOBAL const flecs::entity_t SlotOf = EcsSlotOf; /* Builtin identifiers */ -static const flecs::entity_t Name = EcsName; -static const flecs::entity_t Symbol = EcsSymbol; +FLECS_API_GLOBAL const flecs::entity_t Name = EcsName; +FLECS_API_GLOBAL const flecs::entity_t Symbol = EcsSymbol; /* Storage */ -static const flecs::entity_t Sparse = EcsSparse; -static const flecs::entity_t Union = EcsUnion; +FLECS_API_GLOBAL const flecs::entity_t Sparse = EcsSparse; +FLECS_API_GLOBAL const flecs::entity_t Union = EcsUnion; /* Builtin predicates for comparing entity ids in queries. */ -static const flecs::entity_t PredEq = EcsPredEq; -static const flecs::entity_t PredMatch = EcsPredMatch; -static const flecs::entity_t PredLookup = EcsPredLookup; +FLECS_API_GLOBAL const flecs::entity_t PredEq = EcsPredEq; +FLECS_API_GLOBAL const flecs::entity_t PredMatch = EcsPredMatch; +FLECS_API_GLOBAL const flecs::entity_t PredLookup = EcsPredLookup; /* Builtin marker entities for query scopes */ -static const flecs::entity_t ScopeOpen = EcsScopeOpen; -static const flecs::entity_t ScopeClose = EcsScopeClose; +FLECS_API_GLOBAL const flecs::entity_t ScopeOpen = EcsScopeOpen; +FLECS_API_GLOBAL const flecs::entity_t ScopeClose = EcsScopeClose; /** @} */ @@ -16763,7 +16778,7 @@ static const flecs::entity_t ScopeClose = EcsScopeClose; /** * @file addons/cpp/utils/utils.hpp * @brief Flecs STL (FTL?) - * + * * Flecs STL (FTL?) * Minimalistic utilities that allow for STL like functionality without having * to depend on the actual STL. @@ -16798,7 +16813,7 @@ static const flecs::entity_t ScopeClose = EcsScopeClose; #define FLECS_FWD(...) \ static_cast(__VA_ARGS__) -namespace flecs +namespace flecs { namespace _ @@ -16808,10 +16823,10 @@ namespace _ struct placement_new_tag_t{}; constexpr placement_new_tag_t placement_new_tag{}; template inline void destruct_obj(Ty* _ptr) { _ptr->~Ty(); } -template inline void free_obj(Ty* _ptr) { +template inline void free_obj(Ty* _ptr) { if (_ptr) { - destruct_obj(_ptr); - ecs_os_free(_ptr); + destruct_obj(_ptr); + ecs_os_free(_ptr); } } @@ -16908,7 +16923,9 @@ struct always_false { } // namespace flecs +#ifndef FLECS_CUSTOM_STD_INCLUDE #include +#endif /** * @file addons/cpp/utils/array.hpp * @brief Array class. @@ -17177,13 +17194,15 @@ struct string_view : string { /** * @file addons/cpp/utils/enum.hpp * @brief Compile time enum reflection utilities. - * + * * Discover at compile time valid enumeration constants for an enumeration type * and their names. This is used to automatically register enum constants. */ +#ifndef FLECS_CUSTOM_STD_INCLUDE #include #include +#endif #define FLECS_ENUM_MAX(T) _::to_constant::value #define FLECS_ENUM_MAX_COUNT (FLECS_ENUM_MAX(int) + 1) @@ -17247,7 +17266,7 @@ namespace _ { #define ECS_SIZE_T_STR "unsigned __int64" #else #define ECS_SIZE_T_STR "unsigned int" - #endif + #endif #elif defined(__clang__) #define ECS_SIZE_T_STR "size_t" #else @@ -17263,7 +17282,7 @@ namespace _ { #define ECS_SIZE_T_STR "unsigned __int32" #else #define ECS_SIZE_T_STR "unsigned int" - #endif + #endif #elif defined(__clang__) #define ECS_SIZE_T_STR "size_t" #else @@ -17277,12 +17296,12 @@ namespace _ { template constexpr size_t enum_type_len() { - return ECS_FUNC_TYPE_LEN(, enum_type_len, ECS_FUNC_NAME) + return ECS_FUNC_TYPE_LEN(, enum_type_len, ECS_FUNC_NAME) - (sizeof(ECS_SIZE_T_STR) - 1u); } /** Test if value is valid for enumeration. - * This function leverages that when a valid value is provided, + * This function leverages that when a valid value is provided, * __PRETTY_FUNCTION__ contains the enumeration name, whereas if a value is * invalid, the string contains a number or a negative (-) symbol. */ #if defined(ECS_TARGET_CLANG) @@ -17345,11 +17364,11 @@ struct enum_constant_data { /** * @brief Provides utilities for enum reflection. - * + * * This struct provides static functions for enum reflection, including conversion * between enum values and their underlying integral types, and iteration over enum * values. - * + * * @tparam E The enum type. * @tparam Handler The handler for enum reflection operations. */ @@ -17376,7 +17395,7 @@ struct enum_reflection { * Recursively divide and conquers the search space to reduce the template-depth. Once * recursive division is complete, calls Handle::handle_constant in ascending order, * passing the values computed up the chain. - * + * * @tparam Low The lower bound of the search range, inclusive. * @tparam High The upper bound of the search range, inclusive. * @tparam Args Additional arguments to be passed through to Handler::handle_constant @@ -17399,10 +17418,10 @@ struct enum_reflection { /** * @brief Iterates over the mask range (Low, High] of enum values between Low and High. * - * Recursively iterates the search space, looking for enums defined as multiple-of-2 + * Recursively iterates the search space, looking for enums defined as multiple-of-2 * bitmasks. Each iteration, shifts bit to the right until it hits Low, then calls * Handler::handle_constant for each bitmask in ascending order. - * + * * @tparam Low The lower bound of the search range, not inclusive * @tparam High The upper bound of the search range, inclusive. * @tparam Args Additional arguments to be passed through to Handler::handle_constant @@ -17424,10 +17443,10 @@ struct enum_reflection { /** * @brief Handles enum iteration for gathering reflection data. * - * Iterates over all enum values up to a specified maximum value + * Iterates over all enum values up to a specified maximum value * (each_enum_range<0, Value>), then iterates the rest of the possible bitmasks * (each_mask_range). - * + * * @tparam Value The maximum enum value to iterate up to. * @tparam Args Additional arguments to be passed through to Handler::handle_constant * @param args Additional arguments to be passed through to Handler::handle_constant @@ -17482,7 +17501,7 @@ struct enum_type { * * Because reflection occurs in-order, we can use current value/last value to determine continuity, and * use that as a lookup heuristic later on. - * + * * @tparam Enum The enum type. */ template @@ -17498,7 +17517,7 @@ struct enum_type { // Constant is valid, so fill reflection data. auto v = enum_reflection::template to_int(); const char *name = enum_constant_to_name(); - + ++enum_type::data.max; // Increment cursor as we build constants array. // If the enum was previously contiguous, and continues to be through the current value... @@ -17576,10 +17595,10 @@ struct enum_data { enum_data(flecs::world_t *world, _::enum_data_impl& impl) : world_(world) , impl_(impl) { } - + /** * @brief Checks if a given integral value is a valid enum value. - * + * * @param value The integral value. * @return true If the value is a valid enum value. * @return false If the value is not a valid enum value. @@ -17594,7 +17613,7 @@ struct enum_data { /** * @brief Checks if a given enum value is valid. - * + * * @param value The enum value. * @return true If the value is valid. * @return false If the value is not valid. @@ -17605,7 +17624,7 @@ struct enum_data { /** * @brief Finds the index into the constants array for a value, if one exists - * + * * @param value The enum value. * @return int The index of the enum value. */ @@ -17629,7 +17648,7 @@ struct enum_data { /** * @brief Finds the index into the constants array for an enum value, if one exists - * + * * @param value The enum value. * @return int The index of the enum value. */ @@ -17876,8 +17895,8 @@ using second_arg_t = typename second_arg::type; namespace flecs { -struct id; -struct entity; +FLECS_API_STRUCT struct id; +FLECS_API_STRUCT struct entity; /** * @defgroup cpp_ids Ids @@ -17893,6 +17912,7 @@ struct entity; * - pair ids * - entities with id flags set (like flecs::AUTO_OVERRIDE, flecs::TOGGLE) */ +FLECS_API_STRUCT struct id { id() : world_(nullptr) @@ -18031,8 +18051,8 @@ namespace flecs { * @{ */ -struct term; -struct term_builder; +FLECS_API_STRUCT struct term; +FLECS_API_STRUCT struct term_builder; /** @} */ @@ -18056,9 +18076,11 @@ namespace flecs { struct query_base; +FLECS_API_STRUCT template struct query; +FLECS_API_STRUCT template struct query_builder; @@ -18280,8 +18302,9 @@ namespace flecs { * @{ */ -struct observer; +FLECS_API_STRUCT struct observer; +FLECS_API_STRUCT template struct observer_builder; @@ -18307,10 +18330,12 @@ namespace flecs { * @{ */ +FLECS_API_STRUCT using TickSource = EcsTickSource; -struct system; +FLECS_API_STRUCT struct system; +FLECS_API_STRUCT template struct system_builder; @@ -18349,17 +18374,17 @@ template struct pipeline_builder; /* Builtin pipeline tags */ -static const flecs::entity_t OnStart = EcsOnStart; -static const flecs::entity_t PreFrame = EcsPreFrame; -static const flecs::entity_t OnLoad = EcsOnLoad; -static const flecs::entity_t PostLoad = EcsPostLoad; -static const flecs::entity_t PreUpdate = EcsPreUpdate; -static const flecs::entity_t OnUpdate = EcsOnUpdate; -static const flecs::entity_t OnValidate = EcsOnValidate; -static const flecs::entity_t PostUpdate = EcsPostUpdate; -static const flecs::entity_t PreStore = EcsPreStore; -static const flecs::entity_t OnStore = EcsOnStore; -static const flecs::entity_t PostFrame = EcsPostFrame; +FLECS_API_GLOBAL const flecs::entity_t OnStart = EcsOnStart; +FLECS_API_GLOBAL const flecs::entity_t PreFrame = EcsPreFrame; +FLECS_API_GLOBAL const flecs::entity_t OnLoad = EcsOnLoad; +FLECS_API_GLOBAL const flecs::entity_t PostLoad = EcsPostLoad; +FLECS_API_GLOBAL const flecs::entity_t PreUpdate = EcsPreUpdate; +FLECS_API_GLOBAL const flecs::entity_t OnUpdate = EcsOnUpdate; +FLECS_API_GLOBAL const flecs::entity_t OnValidate = EcsOnValidate; +FLECS_API_GLOBAL const flecs::entity_t PostUpdate = EcsPostUpdate; +FLECS_API_GLOBAL const flecs::entity_t PreStore = EcsPreStore; +FLECS_API_GLOBAL const flecs::entity_t OnStore = EcsOnStore; +FLECS_API_GLOBAL const flecs::entity_t PostFrame = EcsPostFrame; /** @} */ @@ -18384,10 +18409,10 @@ namespace flecs { * @{ */ -using Timer = EcsTimer; -using RateFilter = EcsRateFilter; +FLECS_API_STRUCT using Timer = EcsTimer; +FLECS_API_STRUCT using RateFilter = EcsRateFilter; -struct timer; +FLECS_API_STRUCT struct timer; /** @} */ @@ -18419,19 +18444,19 @@ namespace doc { */ /** flecs.doc.Description component */ -using Description = EcsDocDescription; +FLECS_API_STRUCT using Description = EcsDocDescription; /** flecs.doc.Brief component */ -static const flecs::entity_t Brief = EcsDocBrief; +FLECS_API_GLOBAL const flecs::entity_t Brief = EcsDocBrief; /** flecs.doc.Detail component */ -static const flecs::entity_t Detail = EcsDocDetail; +FLECS_API_GLOBAL const flecs::entity_t Detail = EcsDocDetail; /** flecs.doc.Link component */ -static const flecs::entity_t Link = EcsDocLink; +FLECS_API_GLOBAL const flecs::entity_t Link = EcsDocLink; /** flecs.doc.Color component */ -static const flecs::entity_t Color = EcsDocColor; +FLECS_API_GLOBAL const flecs::entity_t Color = EcsDocColor; /** @private */ namespace _ { @@ -18463,6 +18488,7 @@ namespace flecs { * @{ */ +FLECS_API_STRUCT using Rest = EcsRest; namespace rest { @@ -18498,98 +18524,98 @@ namespace flecs { */ /* Primitive type aliases */ -using bool_t = ecs_bool_t; -using char_t = ecs_char_t; -using u8_t = ecs_u8_t; -using u16_t = ecs_u16_t; -using u32_t = ecs_u32_t; -using u64_t = ecs_u64_t; -using uptr_t = ecs_uptr_t; -using i8_t = ecs_i8_t; -using i16_t = ecs_i16_t; -using i32_t = ecs_i32_t; -using i64_t = ecs_i64_t; -using iptr_t = ecs_iptr_t; -using f32_t = ecs_f32_t; -using f64_t = ecs_f64_t; +FLECS_API_STRUCT using bool_t = ecs_bool_t; +FLECS_API_STRUCT using char_t = ecs_char_t; +FLECS_API_STRUCT using u8_t = ecs_u8_t; +FLECS_API_STRUCT using u16_t = ecs_u16_t; +FLECS_API_STRUCT using u32_t = ecs_u32_t; +FLECS_API_STRUCT using u64_t = ecs_u64_t; +FLECS_API_STRUCT using uptr_t = ecs_uptr_t; +FLECS_API_STRUCT using i8_t = ecs_i8_t; +FLECS_API_STRUCT using i16_t = ecs_i16_t; +FLECS_API_STRUCT using i32_t = ecs_i32_t; +FLECS_API_STRUCT using i64_t = ecs_i64_t; +FLECS_API_STRUCT using iptr_t = ecs_iptr_t; +FLECS_API_STRUCT using f32_t = ecs_f32_t; +FLECS_API_STRUCT using f64_t = ecs_f64_t; /* Embedded type aliases */ -using member_t = ecs_member_t; -using enum_constant_t = ecs_enum_constant_t; -using bitmask_constant_t = ecs_bitmask_constant_t; +FLECS_API_STRUCT using member_t = ecs_member_t; +FLECS_API_STRUCT using enum_constant_t = ecs_enum_constant_t; +FLECS_API_STRUCT using bitmask_constant_t = ecs_bitmask_constant_t; /* Components */ -using Type = EcsType; -using TypeSerializer = EcsTypeSerializer; -using Primitive = EcsPrimitive; -using Enum = EcsEnum; -using Bitmask = EcsBitmask; -using Member = EcsMember; -using MemberRanges = EcsMemberRanges; -using Struct = EcsStruct; -using Array = EcsArray; -using Vector = EcsVector; -using Unit = EcsUnit; +FLECS_API_STRUCT using Type = EcsType; +FLECS_API_STRUCT using TypeSerializer = EcsTypeSerializer; +FLECS_API_STRUCT using Primitive = EcsPrimitive; +FLECS_API_STRUCT using Enum = EcsEnum; +FLECS_API_STRUCT using Bitmask = EcsBitmask; +FLECS_API_STRUCT using Member = EcsMember; +FLECS_API_STRUCT using MemberRanges = EcsMemberRanges; +FLECS_API_STRUCT using Struct = EcsStruct; +FLECS_API_STRUCT using Array = EcsArray; +FLECS_API_STRUCT using Vector = EcsVector; +FLECS_API_STRUCT using Unit = EcsUnit; /** Base type for bitmasks */ -struct bitmask { +FLECS_API_STRUCT struct bitmask { uint32_t value; }; /* Handles to builtin reflection types */ -static const flecs::entity_t Bool = ecs_id(ecs_bool_t); -static const flecs::entity_t Char = ecs_id(ecs_char_t); -static const flecs::entity_t Byte = ecs_id(ecs_byte_t); -static const flecs::entity_t U8 = ecs_id(ecs_u8_t); -static const flecs::entity_t U16 = ecs_id(ecs_u16_t); -static const flecs::entity_t U32 = ecs_id(ecs_u32_t); -static const flecs::entity_t U64 = ecs_id(ecs_u64_t); -static const flecs::entity_t Uptr = ecs_id(ecs_uptr_t); -static const flecs::entity_t I8 = ecs_id(ecs_i8_t); -static const flecs::entity_t I16 = ecs_id(ecs_i16_t); -static const flecs::entity_t I32 = ecs_id(ecs_i32_t); -static const flecs::entity_t I64 = ecs_id(ecs_i64_t); -static const flecs::entity_t Iptr = ecs_id(ecs_iptr_t); -static const flecs::entity_t F32 = ecs_id(ecs_f32_t); -static const flecs::entity_t F64 = ecs_id(ecs_f64_t); -static const flecs::entity_t String = ecs_id(ecs_string_t); -static const flecs::entity_t Entity = ecs_id(ecs_entity_t); -static const flecs::entity_t Constant = EcsConstant; -static const flecs::entity_t Quantity = EcsQuantity; +FLECS_API_GLOBAL const flecs::entity_t Bool = ecs_id(ecs_bool_t); +FLECS_API_GLOBAL const flecs::entity_t Char = ecs_id(ecs_char_t); +FLECS_API_GLOBAL const flecs::entity_t Byte = ecs_id(ecs_byte_t); +FLECS_API_GLOBAL const flecs::entity_t U8 = ecs_id(ecs_u8_t); +FLECS_API_GLOBAL const flecs::entity_t U16 = ecs_id(ecs_u16_t); +FLECS_API_GLOBAL const flecs::entity_t U32 = ecs_id(ecs_u32_t); +FLECS_API_GLOBAL const flecs::entity_t U64 = ecs_id(ecs_u64_t); +FLECS_API_GLOBAL const flecs::entity_t Uptr = ecs_id(ecs_uptr_t); +FLECS_API_GLOBAL const flecs::entity_t I8 = ecs_id(ecs_i8_t); +FLECS_API_GLOBAL const flecs::entity_t I16 = ecs_id(ecs_i16_t); +FLECS_API_GLOBAL const flecs::entity_t I32 = ecs_id(ecs_i32_t); +FLECS_API_GLOBAL const flecs::entity_t I64 = ecs_id(ecs_i64_t); +FLECS_API_GLOBAL const flecs::entity_t Iptr = ecs_id(ecs_iptr_t); +FLECS_API_GLOBAL const flecs::entity_t F32 = ecs_id(ecs_f32_t); +FLECS_API_GLOBAL const flecs::entity_t F64 = ecs_id(ecs_f64_t); +FLECS_API_GLOBAL const flecs::entity_t String = ecs_id(ecs_string_t); +FLECS_API_GLOBAL const flecs::entity_t Entity = ecs_id(ecs_entity_t); +FLECS_API_GLOBAL const flecs::entity_t Constant = EcsConstant; +FLECS_API_GLOBAL const flecs::entity_t Quantity = EcsQuantity; namespace meta { /* Type kinds supported by reflection system */ -using type_kind_t = ecs_type_kind_t; -static const type_kind_t PrimitiveType = EcsPrimitiveType; -static const type_kind_t BitmaskType = EcsBitmaskType; -static const type_kind_t EnumType = EcsEnumType; -static const type_kind_t StructType = EcsStructType; -static const type_kind_t ArrayType = EcsArrayType; -static const type_kind_t VectorType = EcsVectorType; -static const type_kind_t CustomType = EcsOpaqueType; -static const type_kind_t TypeKindLast = EcsTypeKindLast; +FLECS_API_STRUCT using type_kind_t = ecs_type_kind_t; +FLECS_API_GLOBAL const type_kind_t PrimitiveType = EcsPrimitiveType; +FLECS_API_GLOBAL const type_kind_t BitmaskType = EcsBitmaskType; +FLECS_API_GLOBAL const type_kind_t EnumType = EcsEnumType; +FLECS_API_GLOBAL const type_kind_t StructType = EcsStructType; +FLECS_API_GLOBAL const type_kind_t ArrayType = EcsArrayType; +FLECS_API_GLOBAL const type_kind_t VectorType = EcsVectorType; +FLECS_API_GLOBAL const type_kind_t CustomType = EcsOpaqueType; +FLECS_API_GLOBAL const type_kind_t TypeKindLast = EcsTypeKindLast; /* Primitive type kinds supported by reflection system */ -using primitive_kind_t = ecs_primitive_kind_t; -static const primitive_kind_t Bool = EcsBool; -static const primitive_kind_t Char = EcsChar; -static const primitive_kind_t Byte = EcsByte; -static const primitive_kind_t U8 = EcsU8; -static const primitive_kind_t U16 = EcsU16; -static const primitive_kind_t U32 = EcsU32; -static const primitive_kind_t U64 = EcsU64; -static const primitive_kind_t I8 = EcsI8; -static const primitive_kind_t I16 = EcsI16; -static const primitive_kind_t I32 = EcsI32; -static const primitive_kind_t I64 = EcsI64; -static const primitive_kind_t F32 = EcsF32; -static const primitive_kind_t F64 = EcsF64; -static const primitive_kind_t UPtr = EcsUPtr; -static const primitive_kind_t IPtr = EcsIPtr; -static const primitive_kind_t String = EcsString; -static const primitive_kind_t Entity = EcsEntity; -static const primitive_kind_t PrimitiveKindLast = EcsPrimitiveKindLast; +FLECS_API_STRUCT using primitive_kind_t = ecs_primitive_kind_t; +FLECS_API_GLOBAL const primitive_kind_t Bool = EcsBool; +FLECS_API_GLOBAL const primitive_kind_t Char = EcsChar; +FLECS_API_GLOBAL const primitive_kind_t Byte = EcsByte; +FLECS_API_GLOBAL const primitive_kind_t U8 = EcsU8; +FLECS_API_GLOBAL const primitive_kind_t U16 = EcsU16; +FLECS_API_GLOBAL const primitive_kind_t U32 = EcsU32; +FLECS_API_GLOBAL const primitive_kind_t U64 = EcsU64; +FLECS_API_GLOBAL const primitive_kind_t I8 = EcsI8; +FLECS_API_GLOBAL const primitive_kind_t I16 = EcsI16; +FLECS_API_GLOBAL const primitive_kind_t I32 = EcsI32; +FLECS_API_GLOBAL const primitive_kind_t I64 = EcsI64; +FLECS_API_GLOBAL const primitive_kind_t F32 = EcsF32; +FLECS_API_GLOBAL const primitive_kind_t F64 = EcsF64; +FLECS_API_GLOBAL const primitive_kind_t UPtr = EcsUPtr; +FLECS_API_GLOBAL const primitive_kind_t IPtr = EcsIPtr; +FLECS_API_GLOBAL const primitive_kind_t String = EcsString; +FLECS_API_GLOBAL const primitive_kind_t Entity = EcsEntity; +FLECS_API_GLOBAL const primitive_kind_t PrimitiveKindLast = EcsPrimitiveKindLast; /** @} */ @@ -18784,16 +18810,18 @@ namespace flecs { */ /** Serializer object, used for serializing opaque types */ -using serializer = ecs_serializer_t; +FLECS_API_STRUCT using serializer = ecs_serializer_t; /** Serializer function, used to serialize opaque types */ -using serialize_t = ecs_meta_serialize_t; +FLECS_API_STRUCT using serialize_t = ecs_meta_serialize_t; /** Type safe variant of serializer function */ +FLECS_API_STRUCT template using serialize = int(*)(const serializer *, const T*); /** Type safe interface for opaque types */ +FLECS_API_STRUCT template struct opaque { opaque(flecs::world_t *w = nullptr) : world(w) { @@ -18958,6 +18986,8 @@ struct opaque { #pragma once namespace flecs { + +FLECS_API_STRUCT struct units { /** @@ -19333,14 +19363,18 @@ namespace flecs { */ /** Component that stores world statistics */ +FLECS_API_STRUCT using WorldStats = EcsWorldStats; /** Component that stores system/pipeline statistics */ +FLECS_API_STRUCT using PipelineStats = EcsPipelineStats; /** Component with world summary stats */ +FLECS_API_STRUCT using WorldSummary = EcsWorldSummary; +FLECS_API_STRUCT struct stats { stats(flecs::world& world); }; @@ -19475,6 +19509,7 @@ namespace flecs { * @{ */ +FLECS_API_STRUCT struct metrics { using Value = EcsMetricValue; using Source = EcsMetricSource; @@ -19513,6 +19548,7 @@ namespace flecs { */ /** Module */ +FLECS_API_STRUCT struct alerts { using AlertsActive = EcsAlertsActive; using Instance = EcsAlertInstance; @@ -19525,9 +19561,11 @@ struct alerts { alerts(flecs::world& world); }; +FLECS_API_STRUCT template struct alert; +FLECS_API_STRUCT template struct alert_builder; @@ -19554,9 +19592,9 @@ namespace flecs { * @{ */ -using from_json_desc_t = ecs_from_json_desc_t; -using entity_to_json_desc_t = ecs_entity_to_json_desc_t; -using iter_to_json_desc_t = ecs_iter_to_json_desc_t; +FLECS_API_STRUCT using from_json_desc_t = ecs_from_json_desc_t; +FLECS_API_STRUCT using entity_to_json_desc_t = ecs_entity_to_json_desc_t; +FLECS_API_STRUCT using iter_to_json_desc_t = ecs_iter_to_json_desc_t; /** @} */ @@ -19589,6 +19627,7 @@ namespace flecs { */ /** App builder interface */ +FLECS_API_STRUCT struct app_builder { app_builder(flecs::world_t *world) : world_(world) @@ -19690,6 +19729,7 @@ namespace flecs { */ /** Script builder interface */ +FLECS_API_STRUCT struct script_builder { script_builder(flecs::world_t *world, const char *name = nullptr) : world_(world) @@ -19733,7 +19773,7 @@ namespace flecs { * @{ */ -struct script_builder; +FLECS_API_STRUCT struct script_builder; /** @} */ @@ -25625,12 +25665,14 @@ const char* from_json(const char *json) { #pragma once +#ifndef FLECS_CUSTOM_STD_INCLUDE #include // std::declval +#endif namespace flecs { -namespace _ +namespace _ { // Binding ctx for component hooks @@ -25686,7 +25728,7 @@ struct field_ptrs { private: void populate(const ecs_iter_t*, size_t) { } - template >, if_not_t< is_empty::value > = 0> void populate(const ecs_iter_t *iter, size_t index, T, Targs... comps) { @@ -25696,7 +25738,7 @@ struct field_ptrs { fields_[index].is_ref = true; fields_[index].index = static_cast(index); } else { - fields_[index].ptr = ecs_field_w_size(iter, sizeof(A), + fields_[index].ptr = ecs_field_w_size(iter, sizeof(A), static_cast(index)); fields_[index].is_ref = iter->sources[index] != 0; } @@ -25704,7 +25746,7 @@ struct field_ptrs { populate(iter, index + 1, comps ...); } - template >, if_t< is_empty::value > = 0> void populate(const ecs_iter_t *iter, size_t index, T, Targs... comps) { @@ -25713,11 +25755,11 @@ struct field_ptrs { void populate_self(const ecs_iter_t*, size_t) { } - template >, if_not_t< is_empty::value > = 0> void populate_self(const ecs_iter_t *iter, size_t index, T, Targs... comps) { - fields_[index].ptr = ecs_field_w_size(iter, sizeof(A), + fields_[index].ptr = ecs_field_w_size(iter, sizeof(A), static_cast(index)); // fields_[index].is_ref = iter->sources[index] != 0; fields_[index].is_ref = false; @@ -25742,27 +25784,27 @@ struct each_field { }; // Base class struct each_column_base { - each_column_base(const _::field_ptr& field, size_t row) + each_column_base(const _::field_ptr& field, size_t row) : field_(field), row_(row) { } protected: const _::field_ptr& field_; - size_t row_; + size_t row_; }; // If type is not a pointer, return a reference to the type (default case) template -struct each_field::value && - !is_empty>::value && is_actual::value > > - : each_column_base +struct each_field::value && + !is_empty>::value && is_actual::value > > + : each_column_base { - each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) + each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) : each_column_base(field, row) { } T& get_row() { return static_cast(this->field_.ptr)[this->row_]; - } + } }; // If argument type is not the same as actual component type, return by value. @@ -25770,25 +25812,25 @@ struct each_field::value && // A typical scenario where this happens is when using flecs::pair types. template struct each_field::value && - !is_empty>::value && !is_actual::value> > - : each_column_base + !is_empty>::value && !is_actual::value> > + : each_column_base { - each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) + each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) : each_column_base(field, row) { } T get_row() { return static_cast*>(this->field_.ptr)[this->row_]; - } + } }; // If type is empty (indicating a tag) the query will pass a nullptr. To avoid // returning nullptr to reference arguments, return a temporary value. template -struct each_field>::value && - !is_pointer::value > > - : each_column_base +struct each_field>::value && + !is_pointer::value > > + : each_column_base { - each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) + each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) : each_column_base(field, row) { } T get_row() { @@ -25799,11 +25841,11 @@ struct each_field>::value && // If type is a pointer (indicating an optional value) don't index with row if // the field is not set. template -struct each_field::value && - !is_empty>::value > > - : each_column_base +struct each_field::value && + !is_empty>::value > > + : each_column_base { - each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) + each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) : each_column_base(field, row) { } actual_type_t get_row() { @@ -25835,7 +25877,7 @@ struct each_ref_field : public each_field { } if (field.is_row) { - field.ptr = ecs_field_at_w_size(iter, sizeof(T), field.index, + field.ptr = ecs_field_at_w_size(iter, sizeof(T), field.index, static_cast(row)); } } @@ -25847,10 +25889,10 @@ struct each_delegate : public delegate { using Terms = typename field_ptrs::array; template < if_not_t< is_same< decay_t, decay_t& >::value > = 0> - explicit each_delegate(Func&& func) noexcept + explicit each_delegate(Func&& func) noexcept : func_(FLECS_MOV(func)) { } - explicit each_delegate(const Func& func) noexcept + explicit each_delegate(const Func& func) noexcept : func_(func) { } // Invoke object directly. This operation is useful when the calling @@ -25913,14 +25955,14 @@ struct each_delegate : public delegate { private: // func(flecs::entity, Components...) - template class ColumnType, + template class ColumnType, typename... Args, typename Fn = Func, decltype(std::declval()( std::declval(), std::declval > >().get_row()...), 0) = 0> static void invoke_callback( - ecs_iter_t *iter, const Func& func, size_t i, Args... comps) + ecs_iter_t *iter, const Func& func, size_t i, Args... comps) { ecs_assert(iter->count > 0, ECS_INVALID_OPERATION, "no entities returned, use each() without flecs::entity argument"); @@ -25931,7 +25973,7 @@ struct each_delegate : public delegate { } // func(flecs::iter&, size_t row, Components...) - template class ColumnType, + template class ColumnType, typename... Args, typename Fn = Func, decltype(std::declval()( @@ -25939,7 +25981,7 @@ struct each_delegate : public delegate { std::declval(), std::declval > >().get_row()...), 0) = 0> static void invoke_callback( - ecs_iter_t *iter, const Func& func, size_t i, Args... comps) + ecs_iter_t *iter, const Func& func, size_t i, Args... comps) { flecs::iter it(iter); func(it, i, (ColumnType< remove_reference_t >(iter, comps, i) @@ -25947,23 +25989,23 @@ struct each_delegate : public delegate { } // func(Components...) - template class ColumnType, + template class ColumnType, typename... Args, typename Fn = Func, decltype(std::declval()( std::declval > >().get_row()...), 0) = 0> static void invoke_callback( - ecs_iter_t *iter, const Func& func, size_t i, Args... comps) + ecs_iter_t *iter, const Func& func, size_t i, Args... comps) { func((ColumnType< remove_reference_t >(iter, comps, i) .get_row())...); } - template class ColumnType, - typename... Args, if_t< + template class ColumnType, + typename... Args, if_t< sizeof...(Components) == sizeof...(Args)> = 0> static void invoke_unpack( - ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) + ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) { ECS_TABLE_LOCK(iter->world, iter->table); @@ -25981,14 +26023,14 @@ struct each_delegate : public delegate { ECS_TABLE_UNLOCK(iter->world, iter->table); } - template class ColumnType, + template class ColumnType, typename... Args, if_t< sizeof...(Components) != sizeof...(Args) > = 0> - static void invoke_unpack(ecs_iter_t *iter, const Func& func, - size_t index, Terms& columns, Args... comps) + static void invoke_unpack(ecs_iter_t *iter, const Func& func, + size_t index, Terms& columns, Args... comps) { invoke_unpack( iter, func, index + 1, columns, comps..., columns[index]); - } + } public: Func func_; @@ -25999,10 +26041,10 @@ struct find_delegate : public delegate { using Terms = typename field_ptrs::array; template < if_not_t< is_same< decay_t, decay_t& >::value > = 0> - explicit find_delegate(Func&& func) noexcept + explicit find_delegate(Func&& func) noexcept : func_(FLECS_MOV(func)) { } - explicit find_delegate(const Func& func) noexcept + explicit find_delegate(const Func& func) noexcept : func_(func) { } // Invoke object directly. This operation is useful when the calling @@ -26033,7 +26075,7 @@ struct find_delegate : public delegate { std::declval(), std::declval > >().get_row()...))) = true> static flecs::entity invoke_callback( - ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) + ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) { ECS_TABLE_LOCK(iter->world, iter->table); @@ -26070,7 +26112,7 @@ struct find_delegate : public delegate { std::declval(), std::declval > >().get_row()...))) = true> static flecs::entity invoke_callback( - ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) + ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) { size_t count = static_cast(iter->count); if (count == 0) { @@ -26085,7 +26127,7 @@ struct find_delegate : public delegate { ECS_TABLE_LOCK(iter->world, iter->table); for (size_t i = 0; i < count; i ++) { - if (func(it, i, + if (func(it, i, (ColumnType< remove_reference_t >(iter, comps, i) .get_row())...)) { @@ -26107,7 +26149,7 @@ struct find_delegate : public delegate { decltype(bool(std::declval()( std::declval > >().get_row()...))) = true> static flecs::entity invoke_callback( - ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) + ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) { size_t count = static_cast(iter->count); if (count == 0) { @@ -26136,10 +26178,10 @@ struct find_delegate : public delegate { return result; } - template class ColumnType, + template class ColumnType, typename... Args, if_t< sizeof...(Components) != sizeof...(Args) > = 0> - static flecs::entity invoke_callback(ecs_iter_t *iter, const Func& func, - size_t index, Terms& columns, Args... comps) + static flecs::entity invoke_callback(ecs_iter_t *iter, const Func& func, + size_t index, Terms& columns, Args... comps) { return invoke_callback( iter, func, index + 1, columns, comps..., columns[index]); @@ -26155,10 +26197,10 @@ struct find_delegate : public delegate { template struct run_delegate : delegate { template < if_not_t< is_same< decay_t, decay_t& >::value > = 0> - explicit run_delegate(Func&& func) noexcept + explicit run_delegate(Func&& func) noexcept : func_(FLECS_MOV(func)) { } - explicit run_delegate(const Func& func) noexcept + explicit run_delegate(const Func& func) noexcept : func_(func) { } // Invoke object directly. This operation is useful when the calling @@ -26187,7 +26229,7 @@ struct run_delegate : delegate { template struct entity_observer_delegate : delegate { - explicit entity_observer_delegate(Func&& func) noexcept + explicit entity_observer_delegate(Func&& func) noexcept : func_(FLECS_MOV(func)) { } // Static function that can be used as callback for systems/triggers @@ -26217,7 +26259,7 @@ struct entity_observer_delegate : delegate { template struct entity_payload_observer_delegate : delegate { - explicit entity_payload_observer_delegate(Func&& func) noexcept + explicit entity_payload_observer_delegate(Func&& func) noexcept : func_(FLECS_MOV(func)) { } // Static function that can be used as callback for systems/triggers @@ -26233,7 +26275,7 @@ struct entity_payload_observer_delegate : delegate { auto self = static_cast( iter->callback_ctx); ecs_assert(self != nullptr, ECS_INTERNAL_ERROR, NULL); - ecs_assert(iter->param != nullptr, ECS_INVALID_OPERATION, + ecs_assert(iter->param != nullptr, ECS_INVALID_OPERATION, "entity observer invoked without payload"); Event *data = static_cast(iter->param); @@ -26248,7 +26290,7 @@ struct entity_payload_observer_delegate : delegate { auto self = static_cast( iter->callback_ctx); ecs_assert(self != nullptr, ECS_INTERNAL_ERROR, NULL); - ecs_assert(iter->param != nullptr, ECS_INVALID_OPERATION, + ecs_assert(iter->param != nullptr, ECS_INVALID_OPERATION, "entity observer invoked without payload"); Event *data = static_cast(iter->param); @@ -26286,13 +26328,13 @@ struct entity_with_delegate_impl> { return true; } - static + static bool get_ptrs(world_t *world, flecs::entity_t e, const ecs_record_t *r, ecs_table_t *table, - ArrayType& ptrs) + ArrayType& ptrs) { ecs_assert(table != NULL, ECS_INTERNAL_ERROR, NULL); - if (!ecs_table_column_count(table) && - !ecs_table_has_flags(table, EcsTableHasSparse)) + if (!ecs_table_column_count(table) && + !ecs_table_has_flags(table, EcsTableHasSparse)) { return false; } @@ -26306,7 +26348,7 @@ struct entity_with_delegate_impl> { /* Get column indices for components */ ColumnArray columns ({ - ecs_table_get_column_index(real_world, table, + ecs_table_get_column_index(real_world, table, _::type().id(world))... }); @@ -26334,12 +26376,12 @@ struct entity_with_delegate_impl> { /* Get pointers w/ensure */ size_t i = 0; DummyArray dummy ({ - (ptrs[i ++] = ecs_ensure_id(world, e, + (ptrs[i ++] = ecs_ensure_id(world, e, _::type().id(world)), 0)... }); return true; - } + } template static bool invoke_read(world_t *world, entity_t e, const Func& func) { @@ -26397,8 +26439,8 @@ struct entity_with_delegate_impl> { } // Utility for storing id in array in pack expansion - static size_t store_added(IdArray& added, size_t elem, ecs_table_t *prev, - ecs_table_t *next, id_t id) + static size_t store_added(IdArray& added, size_t elem, ecs_table_t *prev, + ecs_table_t *next, id_t id) { // Array should only contain ids for components that are actually added, // so check if the prev and next tables are different. @@ -26479,21 +26521,21 @@ struct entity_with_delegate_impl> { (void)dummy_after; return true; - } + } private: - template = 0> static void invoke_callback( - const Func& f, size_t, ArrayType&, TArgs&& ... comps) + const Func& f, size_t, ArrayType&, TArgs&& ... comps) { f(*static_cast::type*>(comps)...); } - template = 0> - static void invoke_callback(const Func& f, size_t arg, ArrayType& ptrs, - TArgs&& ... comps) + static void invoke_callback(const Func& f, size_t arg, ArrayType& ptrs, + TArgs&& ... comps) { invoke_callback(f, arg + 1, ptrs, comps..., ptrs[arg]); } @@ -26527,8 +26569,10 @@ using delegate = _::each_delegate::type, Args...>; #pragma once +#ifndef FLECS_CUSTOM_STD_INCLUDE #include #include +#endif /** * @defgroup cpp_components Components @@ -26782,7 +26826,7 @@ struct type_impl { (void)name; (void)allow_tag; - ecs_assert(registered(world), ECS_INVALID_OPERATION, + ecs_assert(registered(world), ECS_INVALID_OPERATION, "component '%s' was not registered before use", type_name()); #endif @@ -29865,19 +29909,19 @@ struct query_builder final : _::query_builder_base { } -namespace flecs +namespace flecs { struct query_base { query_base() { } query_base(query_t *q) - : query_(q) { + : query_(q) { flecs_poly_claim(q); } query_base(const query_t *q) - : query_(ECS_CONST_CAST(query_t*, q)) { + : query_(ECS_CONST_CAST(query_t*, q)) { flecs_poly_claim(q); } @@ -29903,7 +29947,7 @@ struct query_base { query_base& operator=(const query_base& obj) { this->query_ = obj.query_; flecs_poly_claim(this->query_); - return *this; + return *this; } query_base(query_base&& obj) noexcept { @@ -29914,7 +29958,7 @@ struct query_base { query_base& operator=(query_base&& obj) noexcept { this->query_ = obj.query_; obj.query_ = nullptr; - return *this; + return *this; } flecs::entity entity() { @@ -29936,7 +29980,7 @@ struct query_base { /** Free persistent query. * A persistent query is a query that is associated with an entity, such as * system queries and named queries. Persistent queries must be deleted with - * destruct(), or will be deleted automatically at world cleanup. + * destruct(), or will be deleted automatically at world cleanup. */ void destruct() { ecs_assert(query_->entity != 0, ECS_INVALID_OPERATION, "destruct() " @@ -29964,15 +30008,15 @@ struct query_base { * - new entities have been matched with * - matched entities were deleted * - matched components were changed - * + * * @return true if entities changed, otherwise false. */ bool changed() const { return ecs_query_changed(query_); } - /** Get info for group. - * + /** Get info for group. + * * @param group_id The group id for which to retrieve the info. * @return The group info. */ @@ -29980,8 +30024,8 @@ struct query_base { return ecs_query_get_group_info(query_, group_id); } - /** Get context for group. - * + /** Get context for group. + * * @param group_id The group id for which to retrieve the context. * @return The group context. */ @@ -30065,7 +30109,7 @@ struct query : query_base, iterable { private: ecs_iter_t get_iter(flecs::world_t *world) const override { - ecs_assert(query_ != nullptr, ECS_INVALID_PARAMETER, + ecs_assert(query_ != nullptr, ECS_INVALID_PARAMETER, "cannot iterate invalid query"); if (!world) { world = query_->world; @@ -31541,18 +31585,18 @@ inline void init(flecs::world& world) { if (!flecs::is_same() && !flecs::is_same()) { flecs::_::type::init(flecs::Iptr, true); - ecs_assert(flecs::type_id() == flecs::Iptr, + ecs_assert(flecs::type_id() == flecs::Iptr, ECS_INTERNAL_ERROR, NULL); - // Remove symbol to prevent validation errors, as it doesn't match with + // Remove symbol to prevent validation errors, as it doesn't match with // the typename ecs_remove_pair(world, flecs::Iptr, ecs_id(EcsIdentifier), EcsSymbol); } if (!flecs::is_same() && !flecs::is_same()) { flecs::_::type::init(flecs::Uptr, true); - ecs_assert(flecs::type_id() == flecs::Uptr, + ecs_assert(flecs::type_id() == flecs::Uptr, ECS_INTERNAL_ERROR, NULL); - // Remove symbol to prevent validation errors, as it doesn't match with + // Remove symbol to prevent validation errors, as it doesn't match with // the typename ecs_remove_pair(world, flecs::Uptr, ecs_id(EcsIdentifier), EcsSymbol); } @@ -31623,6 +31667,8 @@ inline flecs::entity world::vector() { } // namespace flecs +extern "C++" { + inline int ecs_serializer_t::value(ecs_entity_t type, const void *v) const { return this->value_(this, type, v); } @@ -31636,6 +31682,7 @@ inline int ecs_serializer_t::value(const T& v) const { inline int ecs_serializer_t::member(const char *name) const { return this->member_(this, name); } +} #endif #ifdef FLECS_UNITS @@ -32795,6 +32842,8 @@ inline flecs::scoped_world world::scope(const char* name) const { #endif // __cplusplus +#endif // !FLECS_CPP20_MODULE_HEADER + #endif // FLECS_CPP #endif diff --git a/include/flecs/addons/cpp/c_types.hpp b/include/flecs/addons/cpp/c_types.hpp index 1016c1fb8f..abc79d275a 100644 --- a/include/flecs/addons/cpp/c_types.hpp +++ b/include/flecs/addons/cpp/c_types.hpp @@ -73,96 +73,96 @@ using Poly = EcsPoly; using DefaultChildComponent = EcsDefaultChildComponent; /* Builtin tags */ -static const flecs::entity_t Query = EcsQuery; -static const flecs::entity_t Observer = EcsObserver; -static const flecs::entity_t Private = EcsPrivate; -static const flecs::entity_t Module = EcsModule; -static const flecs::entity_t Prefab = EcsPrefab; -static const flecs::entity_t Disabled = EcsDisabled; -static const flecs::entity_t Empty = EcsEmpty; -static const flecs::entity_t Monitor = EcsMonitor; -static const flecs::entity_t System = EcsSystem; -static const flecs::entity_t Pipeline = ecs_id(EcsPipeline); -static const flecs::entity_t Phase = EcsPhase; +FLECS_API_GLOBAL const flecs::entity_t Query = EcsQuery; +FLECS_API_GLOBAL const flecs::entity_t Observer = EcsObserver; +FLECS_API_GLOBAL const flecs::entity_t Private = EcsPrivate; +FLECS_API_GLOBAL const flecs::entity_t Module = EcsModule; +FLECS_API_GLOBAL const flecs::entity_t Prefab = EcsPrefab; +FLECS_API_GLOBAL const flecs::entity_t Disabled = EcsDisabled; +FLECS_API_GLOBAL const flecs::entity_t Empty = EcsEmpty; +FLECS_API_GLOBAL const flecs::entity_t Monitor = EcsMonitor; +FLECS_API_GLOBAL const flecs::entity_t System = EcsSystem; +FLECS_API_GLOBAL const flecs::entity_t Pipeline = ecs_id(EcsPipeline); +FLECS_API_GLOBAL const flecs::entity_t Phase = EcsPhase; /* Builtin event tags */ -static const flecs::entity_t OnAdd = EcsOnAdd; -static const flecs::entity_t OnRemove = EcsOnRemove; -static const flecs::entity_t OnSet = EcsOnSet; -static const flecs::entity_t OnTableCreate = EcsOnTableCreate; -static const flecs::entity_t OnTableDelete = EcsOnTableDelete; +FLECS_API_GLOBAL const flecs::entity_t OnAdd = EcsOnAdd; +FLECS_API_GLOBAL const flecs::entity_t OnRemove = EcsOnRemove; +FLECS_API_GLOBAL const flecs::entity_t OnSet = EcsOnSet; +FLECS_API_GLOBAL const flecs::entity_t OnTableCreate = EcsOnTableCreate; +FLECS_API_GLOBAL const flecs::entity_t OnTableDelete = EcsOnTableDelete; /* Builtin term flags */ -static const uint64_t Self = EcsSelf; -static const uint64_t Up = EcsUp; -static const uint64_t Trav = EcsTrav; -static const uint64_t Cascade = EcsCascade; -static const uint64_t Desc = EcsDesc; -static const uint64_t IsVariable = EcsIsVariable; -static const uint64_t IsEntity = EcsIsEntity; -static const uint64_t IsName = EcsIsName; -static const uint64_t TraverseFlags = EcsTraverseFlags; -static const uint64_t TermRefFlags = EcsTermRefFlags; +FLECS_API_GLOBAL const uint64_t Self = EcsSelf; +FLECS_API_GLOBAL const uint64_t Up = EcsUp; +FLECS_API_GLOBAL const uint64_t Trav = EcsTrav; +FLECS_API_GLOBAL const uint64_t Cascade = EcsCascade; +FLECS_API_GLOBAL const uint64_t Desc = EcsDesc; +FLECS_API_GLOBAL const uint64_t IsVariable = EcsIsVariable; +FLECS_API_GLOBAL const uint64_t IsEntity = EcsIsEntity; +FLECS_API_GLOBAL const uint64_t IsName = EcsIsName; +FLECS_API_GLOBAL const uint64_t TraverseFlags = EcsTraverseFlags; +FLECS_API_GLOBAL const uint64_t TermRefFlags = EcsTermRefFlags; /* Builtin entity ids */ -static const flecs::entity_t Flecs = EcsFlecs; -static const flecs::entity_t FlecsCore = EcsFlecsCore; -static const flecs::entity_t World = EcsWorld; +FLECS_API_GLOBAL const flecs::entity_t Flecs = EcsFlecs; +FLECS_API_GLOBAL const flecs::entity_t FlecsCore = EcsFlecsCore; +FLECS_API_GLOBAL const flecs::entity_t World = EcsWorld; /* Component traits */ -static const flecs::entity_t Wildcard = EcsWildcard; -static const flecs::entity_t Any = EcsAny; -static const flecs::entity_t This = EcsThis; -static const flecs::entity_t Transitive = EcsTransitive; -static const flecs::entity_t Reflexive = EcsReflexive; -static const flecs::entity_t Final = EcsFinal; -static const flecs::entity_t PairIsTag = EcsPairIsTag; -static const flecs::entity_t Exclusive = EcsExclusive; -static const flecs::entity_t Acyclic = EcsAcyclic; -static const flecs::entity_t Traversable = EcsTraversable; -static const flecs::entity_t Symmetric = EcsSymmetric; -static const flecs::entity_t With = EcsWith; -static const flecs::entity_t OneOf = EcsOneOf; -static const flecs::entity_t Trait = EcsTrait; -static const flecs::entity_t Relationship = EcsRelationship; -static const flecs::entity_t Target = EcsTarget; -static const flecs::entity_t CanToggle = EcsCanToggle; +FLECS_API_GLOBAL const flecs::entity_t Wildcard = EcsWildcard; +FLECS_API_GLOBAL const flecs::entity_t Any = EcsAny; +FLECS_API_GLOBAL const flecs::entity_t This = EcsThis; +FLECS_API_GLOBAL const flecs::entity_t Transitive = EcsTransitive; +FLECS_API_GLOBAL const flecs::entity_t Reflexive = EcsReflexive; +FLECS_API_GLOBAL const flecs::entity_t Final = EcsFinal; +FLECS_API_GLOBAL const flecs::entity_t PairIsTag = EcsPairIsTag; +FLECS_API_GLOBAL const flecs::entity_t Exclusive = EcsExclusive; +FLECS_API_GLOBAL const flecs::entity_t Acyclic = EcsAcyclic; +FLECS_API_GLOBAL const flecs::entity_t Traversable = EcsTraversable; +FLECS_API_GLOBAL const flecs::entity_t Symmetric = EcsSymmetric; +FLECS_API_GLOBAL const flecs::entity_t With = EcsWith; +FLECS_API_GLOBAL const flecs::entity_t OneOf = EcsOneOf; +FLECS_API_GLOBAL const flecs::entity_t Trait = EcsTrait; +FLECS_API_GLOBAL const flecs::entity_t Relationship = EcsRelationship; +FLECS_API_GLOBAL const flecs::entity_t Target = EcsTarget; +FLECS_API_GLOBAL const flecs::entity_t CanToggle = EcsCanToggle; /* OnInstantiate trait */ -static const flecs::entity_t OnInstantiate = EcsOnInstantiate; -static const flecs::entity_t Override = EcsOverride; -static const flecs::entity_t Inherit = EcsInherit; -static const flecs::entity_t DontInherit = EcsDontInherit; +FLECS_API_GLOBAL const flecs::entity_t OnInstantiate = EcsOnInstantiate; +FLECS_API_GLOBAL const flecs::entity_t Override = EcsOverride; +FLECS_API_GLOBAL const flecs::entity_t Inherit = EcsInherit; +FLECS_API_GLOBAL const flecs::entity_t DontInherit = EcsDontInherit; /* OnDelete/OnDeleteTarget traits */ -static const flecs::entity_t OnDelete = EcsOnDelete; -static const flecs::entity_t OnDeleteTarget = EcsOnDeleteTarget; -static const flecs::entity_t Remove = EcsRemove; -static const flecs::entity_t Delete = EcsDelete; -static const flecs::entity_t Panic = EcsPanic; +FLECS_API_GLOBAL const flecs::entity_t OnDelete = EcsOnDelete; +FLECS_API_GLOBAL const flecs::entity_t OnDeleteTarget = EcsOnDeleteTarget; +FLECS_API_GLOBAL const flecs::entity_t Remove = EcsRemove; +FLECS_API_GLOBAL const flecs::entity_t Delete = EcsDelete; +FLECS_API_GLOBAL const flecs::entity_t Panic = EcsPanic; /* Builtin relationships */ -static const flecs::entity_t IsA = EcsIsA; -static const flecs::entity_t ChildOf = EcsChildOf; -static const flecs::entity_t DependsOn = EcsDependsOn; -static const flecs::entity_t SlotOf = EcsSlotOf; +FLECS_API_GLOBAL const flecs::entity_t IsA = EcsIsA; +FLECS_API_GLOBAL const flecs::entity_t ChildOf = EcsChildOf; +FLECS_API_GLOBAL const flecs::entity_t DependsOn = EcsDependsOn; +FLECS_API_GLOBAL const flecs::entity_t SlotOf = EcsSlotOf; /* Builtin identifiers */ -static const flecs::entity_t Name = EcsName; -static const flecs::entity_t Symbol = EcsSymbol; +FLECS_API_GLOBAL const flecs::entity_t Name = EcsName; +FLECS_API_GLOBAL const flecs::entity_t Symbol = EcsSymbol; /* Storage */ -static const flecs::entity_t Sparse = EcsSparse; -static const flecs::entity_t Union = EcsUnion; +FLECS_API_GLOBAL const flecs::entity_t Sparse = EcsSparse; +FLECS_API_GLOBAL const flecs::entity_t Union = EcsUnion; /* Builtin predicates for comparing entity ids in queries. */ -static const flecs::entity_t PredEq = EcsPredEq; -static const flecs::entity_t PredMatch = EcsPredMatch; -static const flecs::entity_t PredLookup = EcsPredLookup; +FLECS_API_GLOBAL const flecs::entity_t PredEq = EcsPredEq; +FLECS_API_GLOBAL const flecs::entity_t PredMatch = EcsPredMatch; +FLECS_API_GLOBAL const flecs::entity_t PredLookup = EcsPredLookup; /* Builtin marker entities for query scopes */ -static const flecs::entity_t ScopeOpen = EcsScopeOpen; -static const flecs::entity_t ScopeClose = EcsScopeClose; +FLECS_API_GLOBAL const flecs::entity_t ScopeOpen = EcsScopeOpen; +FLECS_API_GLOBAL const flecs::entity_t ScopeClose = EcsScopeClose; /** @} */ diff --git a/include/flecs/addons/cpp/component.hpp b/include/flecs/addons/cpp/component.hpp index 58e82739ff..f7cee3a0fd 100644 --- a/include/flecs/addons/cpp/component.hpp +++ b/include/flecs/addons/cpp/component.hpp @@ -5,8 +5,10 @@ #pragma once +#ifndef FLECS_CUSTOM_STD_INCLUDE #include #include +#endif /** * @defgroup cpp_components Components @@ -260,7 +262,7 @@ struct type_impl { (void)name; (void)allow_tag; - ecs_assert(registered(world), ECS_INVALID_OPERATION, + ecs_assert(registered(world), ECS_INVALID_OPERATION, "component '%s' was not registered before use", type_name()); #endif diff --git a/include/flecs/addons/cpp/delegate.hpp b/include/flecs/addons/cpp/delegate.hpp index c9bdad7ff4..59cc8c2f03 100644 --- a/include/flecs/addons/cpp/delegate.hpp +++ b/include/flecs/addons/cpp/delegate.hpp @@ -5,12 +5,14 @@ #pragma once +#ifndef FLECS_CUSTOM_STD_INCLUDE #include // std::declval +#endif namespace flecs { -namespace _ +namespace _ { // Binding ctx for component hooks @@ -66,7 +68,7 @@ struct field_ptrs { private: void populate(const ecs_iter_t*, size_t) { } - template >, if_not_t< is_empty::value > = 0> void populate(const ecs_iter_t *iter, size_t index, T, Targs... comps) { @@ -76,7 +78,7 @@ struct field_ptrs { fields_[index].is_ref = true; fields_[index].index = static_cast(index); } else { - fields_[index].ptr = ecs_field_w_size(iter, sizeof(A), + fields_[index].ptr = ecs_field_w_size(iter, sizeof(A), static_cast(index)); fields_[index].is_ref = iter->sources[index] != 0; } @@ -84,7 +86,7 @@ struct field_ptrs { populate(iter, index + 1, comps ...); } - template >, if_t< is_empty::value > = 0> void populate(const ecs_iter_t *iter, size_t index, T, Targs... comps) { @@ -93,11 +95,11 @@ struct field_ptrs { void populate_self(const ecs_iter_t*, size_t) { } - template >, if_not_t< is_empty::value > = 0> void populate_self(const ecs_iter_t *iter, size_t index, T, Targs... comps) { - fields_[index].ptr = ecs_field_w_size(iter, sizeof(A), + fields_[index].ptr = ecs_field_w_size(iter, sizeof(A), static_cast(index)); // fields_[index].is_ref = iter->sources[index] != 0; fields_[index].is_ref = false; @@ -122,27 +124,27 @@ struct each_field { }; // Base class struct each_column_base { - each_column_base(const _::field_ptr& field, size_t row) + each_column_base(const _::field_ptr& field, size_t row) : field_(field), row_(row) { } protected: const _::field_ptr& field_; - size_t row_; + size_t row_; }; // If type is not a pointer, return a reference to the type (default case) template -struct each_field::value && - !is_empty>::value && is_actual::value > > - : each_column_base +struct each_field::value && + !is_empty>::value && is_actual::value > > + : each_column_base { - each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) + each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) : each_column_base(field, row) { } T& get_row() { return static_cast(this->field_.ptr)[this->row_]; - } + } }; // If argument type is not the same as actual component type, return by value. @@ -150,25 +152,25 @@ struct each_field::value && // A typical scenario where this happens is when using flecs::pair types. template struct each_field::value && - !is_empty>::value && !is_actual::value> > - : each_column_base + !is_empty>::value && !is_actual::value> > + : each_column_base { - each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) + each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) : each_column_base(field, row) { } T get_row() { return static_cast*>(this->field_.ptr)[this->row_]; - } + } }; // If type is empty (indicating a tag) the query will pass a nullptr. To avoid // returning nullptr to reference arguments, return a temporary value. template -struct each_field>::value && - !is_pointer::value > > - : each_column_base +struct each_field>::value && + !is_pointer::value > > + : each_column_base { - each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) + each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) : each_column_base(field, row) { } T get_row() { @@ -179,11 +181,11 @@ struct each_field>::value && // If type is a pointer (indicating an optional value) don't index with row if // the field is not set. template -struct each_field::value && - !is_empty>::value > > - : each_column_base +struct each_field::value && + !is_empty>::value > > + : each_column_base { - each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) + each_field(const flecs::iter_t*, _::field_ptr& field, size_t row) : each_column_base(field, row) { } actual_type_t get_row() { @@ -215,7 +217,7 @@ struct each_ref_field : public each_field { } if (field.is_row) { - field.ptr = ecs_field_at_w_size(iter, sizeof(T), field.index, + field.ptr = ecs_field_at_w_size(iter, sizeof(T), field.index, static_cast(row)); } } @@ -227,10 +229,10 @@ struct each_delegate : public delegate { using Terms = typename field_ptrs::array; template < if_not_t< is_same< decay_t, decay_t& >::value > = 0> - explicit each_delegate(Func&& func) noexcept + explicit each_delegate(Func&& func) noexcept : func_(FLECS_MOV(func)) { } - explicit each_delegate(const Func& func) noexcept + explicit each_delegate(const Func& func) noexcept : func_(func) { } // Invoke object directly. This operation is useful when the calling @@ -293,14 +295,14 @@ struct each_delegate : public delegate { private: // func(flecs::entity, Components...) - template class ColumnType, + template class ColumnType, typename... Args, typename Fn = Func, decltype(std::declval()( std::declval(), std::declval > >().get_row()...), 0) = 0> static void invoke_callback( - ecs_iter_t *iter, const Func& func, size_t i, Args... comps) + ecs_iter_t *iter, const Func& func, size_t i, Args... comps) { ecs_assert(iter->count > 0, ECS_INVALID_OPERATION, "no entities returned, use each() without flecs::entity argument"); @@ -311,7 +313,7 @@ struct each_delegate : public delegate { } // func(flecs::iter&, size_t row, Components...) - template class ColumnType, + template class ColumnType, typename... Args, typename Fn = Func, decltype(std::declval()( @@ -319,7 +321,7 @@ struct each_delegate : public delegate { std::declval(), std::declval > >().get_row()...), 0) = 0> static void invoke_callback( - ecs_iter_t *iter, const Func& func, size_t i, Args... comps) + ecs_iter_t *iter, const Func& func, size_t i, Args... comps) { flecs::iter it(iter); func(it, i, (ColumnType< remove_reference_t >(iter, comps, i) @@ -327,23 +329,23 @@ struct each_delegate : public delegate { } // func(Components...) - template class ColumnType, + template class ColumnType, typename... Args, typename Fn = Func, decltype(std::declval()( std::declval > >().get_row()...), 0) = 0> static void invoke_callback( - ecs_iter_t *iter, const Func& func, size_t i, Args... comps) + ecs_iter_t *iter, const Func& func, size_t i, Args... comps) { func((ColumnType< remove_reference_t >(iter, comps, i) .get_row())...); } - template class ColumnType, - typename... Args, if_t< + template class ColumnType, + typename... Args, if_t< sizeof...(Components) == sizeof...(Args)> = 0> static void invoke_unpack( - ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) + ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) { ECS_TABLE_LOCK(iter->world, iter->table); @@ -361,14 +363,14 @@ struct each_delegate : public delegate { ECS_TABLE_UNLOCK(iter->world, iter->table); } - template class ColumnType, + template class ColumnType, typename... Args, if_t< sizeof...(Components) != sizeof...(Args) > = 0> - static void invoke_unpack(ecs_iter_t *iter, const Func& func, - size_t index, Terms& columns, Args... comps) + static void invoke_unpack(ecs_iter_t *iter, const Func& func, + size_t index, Terms& columns, Args... comps) { invoke_unpack( iter, func, index + 1, columns, comps..., columns[index]); - } + } public: Func func_; @@ -379,10 +381,10 @@ struct find_delegate : public delegate { using Terms = typename field_ptrs::array; template < if_not_t< is_same< decay_t, decay_t& >::value > = 0> - explicit find_delegate(Func&& func) noexcept + explicit find_delegate(Func&& func) noexcept : func_(FLECS_MOV(func)) { } - explicit find_delegate(const Func& func) noexcept + explicit find_delegate(const Func& func) noexcept : func_(func) { } // Invoke object directly. This operation is useful when the calling @@ -413,7 +415,7 @@ struct find_delegate : public delegate { std::declval(), std::declval > >().get_row()...))) = true> static flecs::entity invoke_callback( - ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) + ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) { ECS_TABLE_LOCK(iter->world, iter->table); @@ -450,7 +452,7 @@ struct find_delegate : public delegate { std::declval(), std::declval > >().get_row()...))) = true> static flecs::entity invoke_callback( - ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) + ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) { size_t count = static_cast(iter->count); if (count == 0) { @@ -465,7 +467,7 @@ struct find_delegate : public delegate { ECS_TABLE_LOCK(iter->world, iter->table); for (size_t i = 0; i < count; i ++) { - if (func(it, i, + if (func(it, i, (ColumnType< remove_reference_t >(iter, comps, i) .get_row())...)) { @@ -487,7 +489,7 @@ struct find_delegate : public delegate { decltype(bool(std::declval()( std::declval > >().get_row()...))) = true> static flecs::entity invoke_callback( - ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) + ecs_iter_t *iter, const Func& func, size_t, Terms&, Args... comps) { size_t count = static_cast(iter->count); if (count == 0) { @@ -516,10 +518,10 @@ struct find_delegate : public delegate { return result; } - template class ColumnType, + template class ColumnType, typename... Args, if_t< sizeof...(Components) != sizeof...(Args) > = 0> - static flecs::entity invoke_callback(ecs_iter_t *iter, const Func& func, - size_t index, Terms& columns, Args... comps) + static flecs::entity invoke_callback(ecs_iter_t *iter, const Func& func, + size_t index, Terms& columns, Args... comps) { return invoke_callback( iter, func, index + 1, columns, comps..., columns[index]); @@ -535,10 +537,10 @@ struct find_delegate : public delegate { template struct run_delegate : delegate { template < if_not_t< is_same< decay_t, decay_t& >::value > = 0> - explicit run_delegate(Func&& func) noexcept + explicit run_delegate(Func&& func) noexcept : func_(FLECS_MOV(func)) { } - explicit run_delegate(const Func& func) noexcept + explicit run_delegate(const Func& func) noexcept : func_(func) { } // Invoke object directly. This operation is useful when the calling @@ -567,7 +569,7 @@ struct run_delegate : delegate { template struct entity_observer_delegate : delegate { - explicit entity_observer_delegate(Func&& func) noexcept + explicit entity_observer_delegate(Func&& func) noexcept : func_(FLECS_MOV(func)) { } // Static function that can be used as callback for systems/triggers @@ -597,7 +599,7 @@ struct entity_observer_delegate : delegate { template struct entity_payload_observer_delegate : delegate { - explicit entity_payload_observer_delegate(Func&& func) noexcept + explicit entity_payload_observer_delegate(Func&& func) noexcept : func_(FLECS_MOV(func)) { } // Static function that can be used as callback for systems/triggers @@ -613,7 +615,7 @@ struct entity_payload_observer_delegate : delegate { auto self = static_cast( iter->callback_ctx); ecs_assert(self != nullptr, ECS_INTERNAL_ERROR, NULL); - ecs_assert(iter->param != nullptr, ECS_INVALID_OPERATION, + ecs_assert(iter->param != nullptr, ECS_INVALID_OPERATION, "entity observer invoked without payload"); Event *data = static_cast(iter->param); @@ -628,7 +630,7 @@ struct entity_payload_observer_delegate : delegate { auto self = static_cast( iter->callback_ctx); ecs_assert(self != nullptr, ECS_INTERNAL_ERROR, NULL); - ecs_assert(iter->param != nullptr, ECS_INVALID_OPERATION, + ecs_assert(iter->param != nullptr, ECS_INVALID_OPERATION, "entity observer invoked without payload"); Event *data = static_cast(iter->param); @@ -666,13 +668,13 @@ struct entity_with_delegate_impl> { return true; } - static + static bool get_ptrs(world_t *world, flecs::entity_t e, const ecs_record_t *r, ecs_table_t *table, - ArrayType& ptrs) + ArrayType& ptrs) { ecs_assert(table != NULL, ECS_INTERNAL_ERROR, NULL); - if (!ecs_table_column_count(table) && - !ecs_table_has_flags(table, EcsTableHasSparse)) + if (!ecs_table_column_count(table) && + !ecs_table_has_flags(table, EcsTableHasSparse)) { return false; } @@ -686,7 +688,7 @@ struct entity_with_delegate_impl> { /* Get column indices for components */ ColumnArray columns ({ - ecs_table_get_column_index(real_world, table, + ecs_table_get_column_index(real_world, table, _::type().id(world))... }); @@ -714,12 +716,12 @@ struct entity_with_delegate_impl> { /* Get pointers w/ensure */ size_t i = 0; DummyArray dummy ({ - (ptrs[i ++] = ecs_ensure_id(world, e, + (ptrs[i ++] = ecs_ensure_id(world, e, _::type().id(world)), 0)... }); return true; - } + } template static bool invoke_read(world_t *world, entity_t e, const Func& func) { @@ -777,8 +779,8 @@ struct entity_with_delegate_impl> { } // Utility for storing id in array in pack expansion - static size_t store_added(IdArray& added, size_t elem, ecs_table_t *prev, - ecs_table_t *next, id_t id) + static size_t store_added(IdArray& added, size_t elem, ecs_table_t *prev, + ecs_table_t *next, id_t id) { // Array should only contain ids for components that are actually added, // so check if the prev and next tables are different. @@ -859,21 +861,21 @@ struct entity_with_delegate_impl> { (void)dummy_after; return true; - } + } private: - template = 0> static void invoke_callback( - const Func& f, size_t, ArrayType&, TArgs&& ... comps) + const Func& f, size_t, ArrayType&, TArgs&& ... comps) { f(*static_cast::type*>(comps)...); } - template = 0> - static void invoke_callback(const Func& f, size_t arg, ArrayType& ptrs, - TArgs&& ... comps) + static void invoke_callback(const Func& f, size_t arg, ArrayType& ptrs, + TArgs&& ... comps) { invoke_callback(f, arg + 1, ptrs, comps..., ptrs[arg]); } diff --git a/include/flecs/addons/cpp/flecs.hpp b/include/flecs/addons/cpp/flecs.hpp index 8d7c542e86..b66ca4c70e 100644 --- a/include/flecs/addons/cpp/flecs.hpp +++ b/include/flecs/addons/cpp/flecs.hpp @@ -6,7 +6,17 @@ #pragma once // STL includes +#ifndef FLECS_CUSTOM_STD_INCLUDE #include +#endif + +#ifndef FLECS_API_STRUCT +#define FLECS_API_STRUCT +#endif + +#ifndef FLECS_API_GLOBAL +#define FLECS_API_GLOBAL static +#endif /** * @defgroup cpp C++ API @@ -16,19 +26,21 @@ namespace flecs { -struct world; -struct world_async_stage; -struct iter; -struct entity_view; -struct entity; -struct type; -struct table; -struct table_range; -struct untyped_component; - +FLECS_API_STRUCT struct world; +FLECS_API_STRUCT struct world_async_stage; +FLECS_API_STRUCT struct iter; +FLECS_API_STRUCT struct entity_view; +FLECS_API_STRUCT struct entity; +FLECS_API_STRUCT struct type; +FLECS_API_STRUCT struct table; +FLECS_API_STRUCT struct table_range; +FLECS_API_STRUCT struct untyped_component; + +FLECS_API_STRUCT template struct component; +FLECS_API_STRUCT template struct ref; diff --git a/include/flecs/addons/cpp/mixins/alerts/decl.hpp b/include/flecs/addons/cpp/mixins/alerts/decl.hpp index d5b8b5f63c..7c0a971cdd 100644 --- a/include/flecs/addons/cpp/mixins/alerts/decl.hpp +++ b/include/flecs/addons/cpp/mixins/alerts/decl.hpp @@ -16,6 +16,7 @@ namespace flecs { */ /** Module */ +FLECS_API_STRUCT struct alerts { using AlertsActive = EcsAlertsActive; using Instance = EcsAlertInstance; @@ -28,9 +29,11 @@ struct alerts { alerts(flecs::world& world); }; +FLECS_API_STRUCT template struct alert; +FLECS_API_STRUCT template struct alert_builder; diff --git a/include/flecs/addons/cpp/mixins/app/builder.hpp b/include/flecs/addons/cpp/mixins/app/builder.hpp index 9bcd1fae87..15ba6bf328 100644 --- a/include/flecs/addons/cpp/mixins/app/builder.hpp +++ b/include/flecs/addons/cpp/mixins/app/builder.hpp @@ -16,6 +16,7 @@ namespace flecs { */ /** App builder interface */ +FLECS_API_STRUCT struct app_builder { app_builder(flecs::world_t *world) : world_(world) diff --git a/include/flecs/addons/cpp/mixins/doc/decl.hpp b/include/flecs/addons/cpp/mixins/doc/decl.hpp index 7eee2ae0aa..131c78ef2c 100644 --- a/include/flecs/addons/cpp/mixins/doc/decl.hpp +++ b/include/flecs/addons/cpp/mixins/doc/decl.hpp @@ -17,19 +17,19 @@ namespace doc { */ /** flecs.doc.Description component */ -using Description = EcsDocDescription; +FLECS_API_STRUCT using Description = EcsDocDescription; /** flecs.doc.Brief component */ -static const flecs::entity_t Brief = EcsDocBrief; +FLECS_API_GLOBAL const flecs::entity_t Brief = EcsDocBrief; /** flecs.doc.Detail component */ -static const flecs::entity_t Detail = EcsDocDetail; +FLECS_API_GLOBAL const flecs::entity_t Detail = EcsDocDetail; /** flecs.doc.Link component */ -static const flecs::entity_t Link = EcsDocLink; +FLECS_API_GLOBAL const flecs::entity_t Link = EcsDocLink; /** flecs.doc.Color component */ -static const flecs::entity_t Color = EcsDocColor; +FLECS_API_GLOBAL const flecs::entity_t Color = EcsDocColor; /** @private */ namespace _ { diff --git a/include/flecs/addons/cpp/mixins/id/decl.hpp b/include/flecs/addons/cpp/mixins/id/decl.hpp index 4cebfedd34..921943e182 100644 --- a/include/flecs/addons/cpp/mixins/id/decl.hpp +++ b/include/flecs/addons/cpp/mixins/id/decl.hpp @@ -7,8 +7,8 @@ namespace flecs { -struct id; -struct entity; +FLECS_API_STRUCT struct id; +FLECS_API_STRUCT struct entity; /** * @defgroup cpp_ids Ids @@ -24,6 +24,7 @@ struct entity; * - pair ids * - entities with id flags set (like flecs::AUTO_OVERRIDE, flecs::TOGGLE) */ +FLECS_API_STRUCT struct id { id() : world_(nullptr) diff --git a/include/flecs/addons/cpp/mixins/json/decl.hpp b/include/flecs/addons/cpp/mixins/json/decl.hpp index bfa18d361c..03ee0f8794 100644 --- a/include/flecs/addons/cpp/mixins/json/decl.hpp +++ b/include/flecs/addons/cpp/mixins/json/decl.hpp @@ -15,9 +15,9 @@ namespace flecs { * @{ */ -using from_json_desc_t = ecs_from_json_desc_t; -using entity_to_json_desc_t = ecs_entity_to_json_desc_t; -using iter_to_json_desc_t = ecs_iter_to_json_desc_t; +FLECS_API_STRUCT using from_json_desc_t = ecs_from_json_desc_t; +FLECS_API_STRUCT using entity_to_json_desc_t = ecs_entity_to_json_desc_t; +FLECS_API_STRUCT using iter_to_json_desc_t = ecs_iter_to_json_desc_t; /** @} */ diff --git a/include/flecs/addons/cpp/mixins/meta/decl.hpp b/include/flecs/addons/cpp/mixins/meta/decl.hpp index 0e7c93debc..2c3c974499 100644 --- a/include/flecs/addons/cpp/mixins/meta/decl.hpp +++ b/include/flecs/addons/cpp/mixins/meta/decl.hpp @@ -16,98 +16,98 @@ namespace flecs { */ /* Primitive type aliases */ -using bool_t = ecs_bool_t; -using char_t = ecs_char_t; -using u8_t = ecs_u8_t; -using u16_t = ecs_u16_t; -using u32_t = ecs_u32_t; -using u64_t = ecs_u64_t; -using uptr_t = ecs_uptr_t; -using i8_t = ecs_i8_t; -using i16_t = ecs_i16_t; -using i32_t = ecs_i32_t; -using i64_t = ecs_i64_t; -using iptr_t = ecs_iptr_t; -using f32_t = ecs_f32_t; -using f64_t = ecs_f64_t; +FLECS_API_STRUCT using bool_t = ecs_bool_t; +FLECS_API_STRUCT using char_t = ecs_char_t; +FLECS_API_STRUCT using u8_t = ecs_u8_t; +FLECS_API_STRUCT using u16_t = ecs_u16_t; +FLECS_API_STRUCT using u32_t = ecs_u32_t; +FLECS_API_STRUCT using u64_t = ecs_u64_t; +FLECS_API_STRUCT using uptr_t = ecs_uptr_t; +FLECS_API_STRUCT using i8_t = ecs_i8_t; +FLECS_API_STRUCT using i16_t = ecs_i16_t; +FLECS_API_STRUCT using i32_t = ecs_i32_t; +FLECS_API_STRUCT using i64_t = ecs_i64_t; +FLECS_API_STRUCT using iptr_t = ecs_iptr_t; +FLECS_API_STRUCT using f32_t = ecs_f32_t; +FLECS_API_STRUCT using f64_t = ecs_f64_t; /* Embedded type aliases */ -using member_t = ecs_member_t; -using enum_constant_t = ecs_enum_constant_t; -using bitmask_constant_t = ecs_bitmask_constant_t; +FLECS_API_STRUCT using member_t = ecs_member_t; +FLECS_API_STRUCT using enum_constant_t = ecs_enum_constant_t; +FLECS_API_STRUCT using bitmask_constant_t = ecs_bitmask_constant_t; /* Components */ -using Type = EcsType; -using TypeSerializer = EcsTypeSerializer; -using Primitive = EcsPrimitive; -using Enum = EcsEnum; -using Bitmask = EcsBitmask; -using Member = EcsMember; -using MemberRanges = EcsMemberRanges; -using Struct = EcsStruct; -using Array = EcsArray; -using Vector = EcsVector; -using Unit = EcsUnit; +FLECS_API_STRUCT using Type = EcsType; +FLECS_API_STRUCT using TypeSerializer = EcsTypeSerializer; +FLECS_API_STRUCT using Primitive = EcsPrimitive; +FLECS_API_STRUCT using Enum = EcsEnum; +FLECS_API_STRUCT using Bitmask = EcsBitmask; +FLECS_API_STRUCT using Member = EcsMember; +FLECS_API_STRUCT using MemberRanges = EcsMemberRanges; +FLECS_API_STRUCT using Struct = EcsStruct; +FLECS_API_STRUCT using Array = EcsArray; +FLECS_API_STRUCT using Vector = EcsVector; +FLECS_API_STRUCT using Unit = EcsUnit; /** Base type for bitmasks */ -struct bitmask { +FLECS_API_STRUCT struct bitmask { uint32_t value; }; /* Handles to builtin reflection types */ -static const flecs::entity_t Bool = ecs_id(ecs_bool_t); -static const flecs::entity_t Char = ecs_id(ecs_char_t); -static const flecs::entity_t Byte = ecs_id(ecs_byte_t); -static const flecs::entity_t U8 = ecs_id(ecs_u8_t); -static const flecs::entity_t U16 = ecs_id(ecs_u16_t); -static const flecs::entity_t U32 = ecs_id(ecs_u32_t); -static const flecs::entity_t U64 = ecs_id(ecs_u64_t); -static const flecs::entity_t Uptr = ecs_id(ecs_uptr_t); -static const flecs::entity_t I8 = ecs_id(ecs_i8_t); -static const flecs::entity_t I16 = ecs_id(ecs_i16_t); -static const flecs::entity_t I32 = ecs_id(ecs_i32_t); -static const flecs::entity_t I64 = ecs_id(ecs_i64_t); -static const flecs::entity_t Iptr = ecs_id(ecs_iptr_t); -static const flecs::entity_t F32 = ecs_id(ecs_f32_t); -static const flecs::entity_t F64 = ecs_id(ecs_f64_t); -static const flecs::entity_t String = ecs_id(ecs_string_t); -static const flecs::entity_t Entity = ecs_id(ecs_entity_t); -static const flecs::entity_t Constant = EcsConstant; -static const flecs::entity_t Quantity = EcsQuantity; +FLECS_API_GLOBAL const flecs::entity_t Bool = ecs_id(ecs_bool_t); +FLECS_API_GLOBAL const flecs::entity_t Char = ecs_id(ecs_char_t); +FLECS_API_GLOBAL const flecs::entity_t Byte = ecs_id(ecs_byte_t); +FLECS_API_GLOBAL const flecs::entity_t U8 = ecs_id(ecs_u8_t); +FLECS_API_GLOBAL const flecs::entity_t U16 = ecs_id(ecs_u16_t); +FLECS_API_GLOBAL const flecs::entity_t U32 = ecs_id(ecs_u32_t); +FLECS_API_GLOBAL const flecs::entity_t U64 = ecs_id(ecs_u64_t); +FLECS_API_GLOBAL const flecs::entity_t Uptr = ecs_id(ecs_uptr_t); +FLECS_API_GLOBAL const flecs::entity_t I8 = ecs_id(ecs_i8_t); +FLECS_API_GLOBAL const flecs::entity_t I16 = ecs_id(ecs_i16_t); +FLECS_API_GLOBAL const flecs::entity_t I32 = ecs_id(ecs_i32_t); +FLECS_API_GLOBAL const flecs::entity_t I64 = ecs_id(ecs_i64_t); +FLECS_API_GLOBAL const flecs::entity_t Iptr = ecs_id(ecs_iptr_t); +FLECS_API_GLOBAL const flecs::entity_t F32 = ecs_id(ecs_f32_t); +FLECS_API_GLOBAL const flecs::entity_t F64 = ecs_id(ecs_f64_t); +FLECS_API_GLOBAL const flecs::entity_t String = ecs_id(ecs_string_t); +FLECS_API_GLOBAL const flecs::entity_t Entity = ecs_id(ecs_entity_t); +FLECS_API_GLOBAL const flecs::entity_t Constant = EcsConstant; +FLECS_API_GLOBAL const flecs::entity_t Quantity = EcsQuantity; namespace meta { /* Type kinds supported by reflection system */ -using type_kind_t = ecs_type_kind_t; -static const type_kind_t PrimitiveType = EcsPrimitiveType; -static const type_kind_t BitmaskType = EcsBitmaskType; -static const type_kind_t EnumType = EcsEnumType; -static const type_kind_t StructType = EcsStructType; -static const type_kind_t ArrayType = EcsArrayType; -static const type_kind_t VectorType = EcsVectorType; -static const type_kind_t CustomType = EcsOpaqueType; -static const type_kind_t TypeKindLast = EcsTypeKindLast; +FLECS_API_STRUCT using type_kind_t = ecs_type_kind_t; +FLECS_API_GLOBAL const type_kind_t PrimitiveType = EcsPrimitiveType; +FLECS_API_GLOBAL const type_kind_t BitmaskType = EcsBitmaskType; +FLECS_API_GLOBAL const type_kind_t EnumType = EcsEnumType; +FLECS_API_GLOBAL const type_kind_t StructType = EcsStructType; +FLECS_API_GLOBAL const type_kind_t ArrayType = EcsArrayType; +FLECS_API_GLOBAL const type_kind_t VectorType = EcsVectorType; +FLECS_API_GLOBAL const type_kind_t CustomType = EcsOpaqueType; +FLECS_API_GLOBAL const type_kind_t TypeKindLast = EcsTypeKindLast; /* Primitive type kinds supported by reflection system */ -using primitive_kind_t = ecs_primitive_kind_t; -static const primitive_kind_t Bool = EcsBool; -static const primitive_kind_t Char = EcsChar; -static const primitive_kind_t Byte = EcsByte; -static const primitive_kind_t U8 = EcsU8; -static const primitive_kind_t U16 = EcsU16; -static const primitive_kind_t U32 = EcsU32; -static const primitive_kind_t U64 = EcsU64; -static const primitive_kind_t I8 = EcsI8; -static const primitive_kind_t I16 = EcsI16; -static const primitive_kind_t I32 = EcsI32; -static const primitive_kind_t I64 = EcsI64; -static const primitive_kind_t F32 = EcsF32; -static const primitive_kind_t F64 = EcsF64; -static const primitive_kind_t UPtr = EcsUPtr; -static const primitive_kind_t IPtr = EcsIPtr; -static const primitive_kind_t String = EcsString; -static const primitive_kind_t Entity = EcsEntity; -static const primitive_kind_t PrimitiveKindLast = EcsPrimitiveKindLast; +FLECS_API_STRUCT using primitive_kind_t = ecs_primitive_kind_t; +FLECS_API_GLOBAL const primitive_kind_t Bool = EcsBool; +FLECS_API_GLOBAL const primitive_kind_t Char = EcsChar; +FLECS_API_GLOBAL const primitive_kind_t Byte = EcsByte; +FLECS_API_GLOBAL const primitive_kind_t U8 = EcsU8; +FLECS_API_GLOBAL const primitive_kind_t U16 = EcsU16; +FLECS_API_GLOBAL const primitive_kind_t U32 = EcsU32; +FLECS_API_GLOBAL const primitive_kind_t U64 = EcsU64; +FLECS_API_GLOBAL const primitive_kind_t I8 = EcsI8; +FLECS_API_GLOBAL const primitive_kind_t I16 = EcsI16; +FLECS_API_GLOBAL const primitive_kind_t I32 = EcsI32; +FLECS_API_GLOBAL const primitive_kind_t I64 = EcsI64; +FLECS_API_GLOBAL const primitive_kind_t F32 = EcsF32; +FLECS_API_GLOBAL const primitive_kind_t F64 = EcsF64; +FLECS_API_GLOBAL const primitive_kind_t UPtr = EcsUPtr; +FLECS_API_GLOBAL const primitive_kind_t IPtr = EcsIPtr; +FLECS_API_GLOBAL const primitive_kind_t String = EcsString; +FLECS_API_GLOBAL const primitive_kind_t Entity = EcsEntity; +FLECS_API_GLOBAL const primitive_kind_t PrimitiveKindLast = EcsPrimitiveKindLast; /** @} */ diff --git a/include/flecs/addons/cpp/mixins/meta/impl.hpp b/include/flecs/addons/cpp/mixins/meta/impl.hpp index e6f18a8431..92ce9aaacf 100644 --- a/include/flecs/addons/cpp/mixins/meta/impl.hpp +++ b/include/flecs/addons/cpp/mixins/meta/impl.hpp @@ -66,18 +66,18 @@ inline void init(flecs::world& world) { if (!flecs::is_same() && !flecs::is_same()) { flecs::_::type::init(flecs::Iptr, true); - ecs_assert(flecs::type_id() == flecs::Iptr, + ecs_assert(flecs::type_id() == flecs::Iptr, ECS_INTERNAL_ERROR, NULL); - // Remove symbol to prevent validation errors, as it doesn't match with + // Remove symbol to prevent validation errors, as it doesn't match with // the typename ecs_remove_pair(world, flecs::Iptr, ecs_id(EcsIdentifier), EcsSymbol); } if (!flecs::is_same() && !flecs::is_same()) { flecs::_::type::init(flecs::Uptr, true); - ecs_assert(flecs::type_id() == flecs::Uptr, + ecs_assert(flecs::type_id() == flecs::Uptr, ECS_INTERNAL_ERROR, NULL); - // Remove symbol to prevent validation errors, as it doesn't match with + // Remove symbol to prevent validation errors, as it doesn't match with // the typename ecs_remove_pair(world, flecs::Uptr, ecs_id(EcsIdentifier), EcsSymbol); } @@ -148,6 +148,8 @@ inline flecs::entity world::vector() { } // namespace flecs +extern "C++" { + inline int ecs_serializer_t::value(ecs_entity_t type, const void *v) const { return this->value_(this, type, v); } @@ -161,3 +163,4 @@ inline int ecs_serializer_t::value(const T& v) const { inline int ecs_serializer_t::member(const char *name) const { return this->member_(this, name); } +} diff --git a/include/flecs/addons/cpp/mixins/meta/opaque.hpp b/include/flecs/addons/cpp/mixins/meta/opaque.hpp index d1f23803cf..5b887e0492 100644 --- a/include/flecs/addons/cpp/mixins/meta/opaque.hpp +++ b/include/flecs/addons/cpp/mixins/meta/opaque.hpp @@ -18,16 +18,18 @@ namespace flecs { */ /** Serializer object, used for serializing opaque types */ -using serializer = ecs_serializer_t; +FLECS_API_STRUCT using serializer = ecs_serializer_t; /** Serializer function, used to serialize opaque types */ -using serialize_t = ecs_meta_serialize_t; +FLECS_API_STRUCT using serialize_t = ecs_meta_serialize_t; /** Type safe variant of serializer function */ +FLECS_API_STRUCT template using serialize = int(*)(const serializer *, const T*); /** Type safe interface for opaque types */ +FLECS_API_STRUCT template struct opaque { opaque(flecs::world_t *w = nullptr) : world(w) { diff --git a/include/flecs/addons/cpp/mixins/metrics/decl.hpp b/include/flecs/addons/cpp/mixins/metrics/decl.hpp index 0a394395c6..79d564a168 100644 --- a/include/flecs/addons/cpp/mixins/metrics/decl.hpp +++ b/include/flecs/addons/cpp/mixins/metrics/decl.hpp @@ -18,6 +18,7 @@ namespace flecs { * @{ */ +FLECS_API_STRUCT struct metrics { using Value = EcsMetricValue; using Source = EcsMetricSource; diff --git a/include/flecs/addons/cpp/mixins/observer/decl.hpp b/include/flecs/addons/cpp/mixins/observer/decl.hpp index ebf3f20615..601c425e46 100644 --- a/include/flecs/addons/cpp/mixins/observer/decl.hpp +++ b/include/flecs/addons/cpp/mixins/observer/decl.hpp @@ -15,8 +15,9 @@ namespace flecs { * @{ */ -struct observer; +FLECS_API_STRUCT struct observer; +FLECS_API_STRUCT template struct observer_builder; diff --git a/include/flecs/addons/cpp/mixins/pipeline/decl.hpp b/include/flecs/addons/cpp/mixins/pipeline/decl.hpp index 0ea1f6f248..d94320bb16 100644 --- a/include/flecs/addons/cpp/mixins/pipeline/decl.hpp +++ b/include/flecs/addons/cpp/mixins/pipeline/decl.hpp @@ -22,17 +22,17 @@ template struct pipeline_builder; /* Builtin pipeline tags */ -static const flecs::entity_t OnStart = EcsOnStart; -static const flecs::entity_t PreFrame = EcsPreFrame; -static const flecs::entity_t OnLoad = EcsOnLoad; -static const flecs::entity_t PostLoad = EcsPostLoad; -static const flecs::entity_t PreUpdate = EcsPreUpdate; -static const flecs::entity_t OnUpdate = EcsOnUpdate; -static const flecs::entity_t OnValidate = EcsOnValidate; -static const flecs::entity_t PostUpdate = EcsPostUpdate; -static const flecs::entity_t PreStore = EcsPreStore; -static const flecs::entity_t OnStore = EcsOnStore; -static const flecs::entity_t PostFrame = EcsPostFrame; +FLECS_API_GLOBAL const flecs::entity_t OnStart = EcsOnStart; +FLECS_API_GLOBAL const flecs::entity_t PreFrame = EcsPreFrame; +FLECS_API_GLOBAL const flecs::entity_t OnLoad = EcsOnLoad; +FLECS_API_GLOBAL const flecs::entity_t PostLoad = EcsPostLoad; +FLECS_API_GLOBAL const flecs::entity_t PreUpdate = EcsPreUpdate; +FLECS_API_GLOBAL const flecs::entity_t OnUpdate = EcsOnUpdate; +FLECS_API_GLOBAL const flecs::entity_t OnValidate = EcsOnValidate; +FLECS_API_GLOBAL const flecs::entity_t PostUpdate = EcsPostUpdate; +FLECS_API_GLOBAL const flecs::entity_t PreStore = EcsPreStore; +FLECS_API_GLOBAL const flecs::entity_t OnStore = EcsOnStore; +FLECS_API_GLOBAL const flecs::entity_t PostFrame = EcsPostFrame; /** @} */ diff --git a/include/flecs/addons/cpp/mixins/query/decl.hpp b/include/flecs/addons/cpp/mixins/query/decl.hpp index a89e88a353..61263d2d73 100644 --- a/include/flecs/addons/cpp/mixins/query/decl.hpp +++ b/include/flecs/addons/cpp/mixins/query/decl.hpp @@ -16,9 +16,11 @@ namespace flecs { struct query_base; +FLECS_API_STRUCT template struct query; +FLECS_API_STRUCT template struct query_builder; diff --git a/include/flecs/addons/cpp/mixins/query/impl.hpp b/include/flecs/addons/cpp/mixins/query/impl.hpp index c0c874bc3d..5ff3075434 100644 --- a/include/flecs/addons/cpp/mixins/query/impl.hpp +++ b/include/flecs/addons/cpp/mixins/query/impl.hpp @@ -7,19 +7,19 @@ #include "builder.hpp" -namespace flecs +namespace flecs { struct query_base { query_base() { } query_base(query_t *q) - : query_(q) { + : query_(q) { flecs_poly_claim(q); } query_base(const query_t *q) - : query_(ECS_CONST_CAST(query_t*, q)) { + : query_(ECS_CONST_CAST(query_t*, q)) { flecs_poly_claim(q); } @@ -45,7 +45,7 @@ struct query_base { query_base& operator=(const query_base& obj) { this->query_ = obj.query_; flecs_poly_claim(this->query_); - return *this; + return *this; } query_base(query_base&& obj) noexcept { @@ -56,7 +56,7 @@ struct query_base { query_base& operator=(query_base&& obj) noexcept { this->query_ = obj.query_; obj.query_ = nullptr; - return *this; + return *this; } flecs::entity entity() { @@ -78,7 +78,7 @@ struct query_base { /** Free persistent query. * A persistent query is a query that is associated with an entity, such as * system queries and named queries. Persistent queries must be deleted with - * destruct(), or will be deleted automatically at world cleanup. + * destruct(), or will be deleted automatically at world cleanup. */ void destruct() { ecs_assert(query_->entity != 0, ECS_INVALID_OPERATION, "destruct() " @@ -106,15 +106,15 @@ struct query_base { * - new entities have been matched with * - matched entities were deleted * - matched components were changed - * + * * @return true if entities changed, otherwise false. */ bool changed() const { return ecs_query_changed(query_); } - /** Get info for group. - * + /** Get info for group. + * * @param group_id The group id for which to retrieve the info. * @return The group info. */ @@ -122,8 +122,8 @@ struct query_base { return ecs_query_get_group_info(query_, group_id); } - /** Get context for group. - * + /** Get context for group. + * * @param group_id The group id for which to retrieve the context. * @return The group context. */ @@ -207,7 +207,7 @@ struct query : query_base, iterable { private: ecs_iter_t get_iter(flecs::world_t *world) const override { - ecs_assert(query_ != nullptr, ECS_INVALID_PARAMETER, + ecs_assert(query_ != nullptr, ECS_INVALID_PARAMETER, "cannot iterate invalid query"); if (!world) { world = query_->world; diff --git a/include/flecs/addons/cpp/mixins/rest/decl.hpp b/include/flecs/addons/cpp/mixins/rest/decl.hpp index fac86b2de1..f85b2dc0b4 100644 --- a/include/flecs/addons/cpp/mixins/rest/decl.hpp +++ b/include/flecs/addons/cpp/mixins/rest/decl.hpp @@ -15,6 +15,7 @@ namespace flecs { * @{ */ +FLECS_API_STRUCT using Rest = EcsRest; namespace rest { diff --git a/include/flecs/addons/cpp/mixins/script/builder.hpp b/include/flecs/addons/cpp/mixins/script/builder.hpp index 1a244b7545..54acef4d9f 100644 --- a/include/flecs/addons/cpp/mixins/script/builder.hpp +++ b/include/flecs/addons/cpp/mixins/script/builder.hpp @@ -13,6 +13,7 @@ namespace flecs { */ /** Script builder interface */ +FLECS_API_STRUCT struct script_builder { script_builder(flecs::world_t *world, const char *name = nullptr) : world_(world) diff --git a/include/flecs/addons/cpp/mixins/script/decl.hpp b/include/flecs/addons/cpp/mixins/script/decl.hpp index 21d789acfa..2330d5380d 100644 --- a/include/flecs/addons/cpp/mixins/script/decl.hpp +++ b/include/flecs/addons/cpp/mixins/script/decl.hpp @@ -16,7 +16,7 @@ namespace flecs { * @{ */ -struct script_builder; +FLECS_API_STRUCT struct script_builder; /** @} */ diff --git a/include/flecs/addons/cpp/mixins/stats/decl.hpp b/include/flecs/addons/cpp/mixins/stats/decl.hpp index 2435aa3a64..a7f7ac8351 100644 --- a/include/flecs/addons/cpp/mixins/stats/decl.hpp +++ b/include/flecs/addons/cpp/mixins/stats/decl.hpp @@ -16,14 +16,18 @@ namespace flecs { */ /** Component that stores world statistics */ +FLECS_API_STRUCT using WorldStats = EcsWorldStats; /** Component that stores system/pipeline statistics */ +FLECS_API_STRUCT using PipelineStats = EcsPipelineStats; /** Component with world summary stats */ +FLECS_API_STRUCT using WorldSummary = EcsWorldSummary; +FLECS_API_STRUCT struct stats { stats(flecs::world& world); }; diff --git a/include/flecs/addons/cpp/mixins/system/decl.hpp b/include/flecs/addons/cpp/mixins/system/decl.hpp index d8203c6879..eef94abd4c 100644 --- a/include/flecs/addons/cpp/mixins/system/decl.hpp +++ b/include/flecs/addons/cpp/mixins/system/decl.hpp @@ -15,10 +15,12 @@ namespace flecs { * @{ */ +FLECS_API_STRUCT using TickSource = EcsTickSource; -struct system; +FLECS_API_STRUCT struct system; +FLECS_API_STRUCT template struct system_builder; diff --git a/include/flecs/addons/cpp/mixins/term/decl.hpp b/include/flecs/addons/cpp/mixins/term/decl.hpp index b5a1bdbd54..b2a477b398 100644 --- a/include/flecs/addons/cpp/mixins/term/decl.hpp +++ b/include/flecs/addons/cpp/mixins/term/decl.hpp @@ -13,8 +13,8 @@ namespace flecs { * @{ */ -struct term; -struct term_builder; +FLECS_API_STRUCT struct term; +FLECS_API_STRUCT struct term_builder; /** @} */ diff --git a/include/flecs/addons/cpp/mixins/timer/decl.hpp b/include/flecs/addons/cpp/mixins/timer/decl.hpp index ccdf879901..4fd41039c4 100644 --- a/include/flecs/addons/cpp/mixins/timer/decl.hpp +++ b/include/flecs/addons/cpp/mixins/timer/decl.hpp @@ -15,10 +15,10 @@ namespace flecs { * @{ */ -using Timer = EcsTimer; -using RateFilter = EcsRateFilter; +FLECS_API_STRUCT using Timer = EcsTimer; +FLECS_API_STRUCT using RateFilter = EcsRateFilter; -struct timer; +FLECS_API_STRUCT struct timer; /** @} */ diff --git a/include/flecs/addons/cpp/mixins/units/decl.hpp b/include/flecs/addons/cpp/mixins/units/decl.hpp index 05592bcfd5..32cd1abb64 100644 --- a/include/flecs/addons/cpp/mixins/units/decl.hpp +++ b/include/flecs/addons/cpp/mixins/units/decl.hpp @@ -6,6 +6,8 @@ #pragma once namespace flecs { + +FLECS_API_STRUCT struct units { /** diff --git a/include/flecs/addons/cpp/utils/enum.hpp b/include/flecs/addons/cpp/utils/enum.hpp index 14a8182a69..9520690c31 100644 --- a/include/flecs/addons/cpp/utils/enum.hpp +++ b/include/flecs/addons/cpp/utils/enum.hpp @@ -1,13 +1,15 @@ /** * @file addons/cpp/utils/enum.hpp * @brief Compile time enum reflection utilities. - * + * * Discover at compile time valid enumeration constants for an enumeration type * and their names. This is used to automatically register enum constants. */ +#ifndef FLECS_CUSTOM_STD_INCLUDE #include #include +#endif #define FLECS_ENUM_MAX(T) _::to_constant::value #define FLECS_ENUM_MAX_COUNT (FLECS_ENUM_MAX(int) + 1) @@ -71,7 +73,7 @@ namespace _ { #define ECS_SIZE_T_STR "unsigned __int64" #else #define ECS_SIZE_T_STR "unsigned int" - #endif + #endif #elif defined(__clang__) #define ECS_SIZE_T_STR "size_t" #else @@ -87,7 +89,7 @@ namespace _ { #define ECS_SIZE_T_STR "unsigned __int32" #else #define ECS_SIZE_T_STR "unsigned int" - #endif + #endif #elif defined(__clang__) #define ECS_SIZE_T_STR "size_t" #else @@ -101,12 +103,12 @@ namespace _ { template constexpr size_t enum_type_len() { - return ECS_FUNC_TYPE_LEN(, enum_type_len, ECS_FUNC_NAME) + return ECS_FUNC_TYPE_LEN(, enum_type_len, ECS_FUNC_NAME) - (sizeof(ECS_SIZE_T_STR) - 1u); } /** Test if value is valid for enumeration. - * This function leverages that when a valid value is provided, + * This function leverages that when a valid value is provided, * __PRETTY_FUNCTION__ contains the enumeration name, whereas if a value is * invalid, the string contains a number or a negative (-) symbol. */ #if defined(ECS_TARGET_CLANG) @@ -169,11 +171,11 @@ struct enum_constant_data { /** * @brief Provides utilities for enum reflection. - * + * * This struct provides static functions for enum reflection, including conversion * between enum values and their underlying integral types, and iteration over enum * values. - * + * * @tparam E The enum type. * @tparam Handler The handler for enum reflection operations. */ @@ -200,7 +202,7 @@ struct enum_reflection { * Recursively divide and conquers the search space to reduce the template-depth. Once * recursive division is complete, calls Handle::handle_constant in ascending order, * passing the values computed up the chain. - * + * * @tparam Low The lower bound of the search range, inclusive. * @tparam High The upper bound of the search range, inclusive. * @tparam Args Additional arguments to be passed through to Handler::handle_constant @@ -223,10 +225,10 @@ struct enum_reflection { /** * @brief Iterates over the mask range (Low, High] of enum values between Low and High. * - * Recursively iterates the search space, looking for enums defined as multiple-of-2 + * Recursively iterates the search space, looking for enums defined as multiple-of-2 * bitmasks. Each iteration, shifts bit to the right until it hits Low, then calls * Handler::handle_constant for each bitmask in ascending order. - * + * * @tparam Low The lower bound of the search range, not inclusive * @tparam High The upper bound of the search range, inclusive. * @tparam Args Additional arguments to be passed through to Handler::handle_constant @@ -248,10 +250,10 @@ struct enum_reflection { /** * @brief Handles enum iteration for gathering reflection data. * - * Iterates over all enum values up to a specified maximum value + * Iterates over all enum values up to a specified maximum value * (each_enum_range<0, Value>), then iterates the rest of the possible bitmasks * (each_mask_range). - * + * * @tparam Value The maximum enum value to iterate up to. * @tparam Args Additional arguments to be passed through to Handler::handle_constant * @param args Additional arguments to be passed through to Handler::handle_constant @@ -306,7 +308,7 @@ struct enum_type { * * Because reflection occurs in-order, we can use current value/last value to determine continuity, and * use that as a lookup heuristic later on. - * + * * @tparam Enum The enum type. */ template @@ -322,7 +324,7 @@ struct enum_type { // Constant is valid, so fill reflection data. auto v = enum_reflection::template to_int(); const char *name = enum_constant_to_name(); - + ++enum_type::data.max; // Increment cursor as we build constants array. // If the enum was previously contiguous, and continues to be through the current value... @@ -400,10 +402,10 @@ struct enum_data { enum_data(flecs::world_t *world, _::enum_data_impl& impl) : world_(world) , impl_(impl) { } - + /** * @brief Checks if a given integral value is a valid enum value. - * + * * @param value The integral value. * @return true If the value is a valid enum value. * @return false If the value is not a valid enum value. @@ -418,7 +420,7 @@ struct enum_data { /** * @brief Checks if a given enum value is valid. - * + * * @param value The enum value. * @return true If the value is valid. * @return false If the value is not valid. @@ -429,7 +431,7 @@ struct enum_data { /** * @brief Finds the index into the constants array for a value, if one exists - * + * * @param value The enum value. * @return int The index of the enum value. */ @@ -453,7 +455,7 @@ struct enum_data { /** * @brief Finds the index into the constants array for an enum value, if one exists - * + * * @param value The enum value. * @return int The index of the enum value. */ diff --git a/include/flecs/addons/cpp/utils/utils.hpp b/include/flecs/addons/cpp/utils/utils.hpp index 5c48534f5f..3d2490143a 100644 --- a/include/flecs/addons/cpp/utils/utils.hpp +++ b/include/flecs/addons/cpp/utils/utils.hpp @@ -1,7 +1,7 @@ /** * @file addons/cpp/utils/utils.hpp * @brief Flecs STL (FTL?) - * + * * Flecs STL (FTL?) * Minimalistic utilities that allow for STL like functionality without having * to depend on the actual STL. @@ -36,7 +36,7 @@ #define FLECS_FWD(...) \ static_cast(__VA_ARGS__) -namespace flecs +namespace flecs { namespace _ @@ -46,10 +46,10 @@ namespace _ struct placement_new_tag_t{}; constexpr placement_new_tag_t placement_new_tag{}; template inline void destruct_obj(Ty* _ptr) { _ptr->~Ty(); } -template inline void free_obj(Ty* _ptr) { +template inline void free_obj(Ty* _ptr) { if (_ptr) { - destruct_obj(_ptr); - ecs_os_free(_ptr); + destruct_obj(_ptr); + ecs_os_free(_ptr); } } @@ -146,7 +146,9 @@ struct always_false { } // namespace flecs +#ifndef FLECS_CUSTOM_STD_INCLUDE #include +#endif #include "array.hpp" #include "string.hpp" #include "enum.hpp" diff --git a/include/flecs/private/addons.h b/include/flecs/private/addons.h index 597e475306..e0ac20837a 100644 --- a/include/flecs/private/addons.h +++ b/include/flecs/private/addons.h @@ -197,12 +197,17 @@ #ifdef FLECS_NO_CPP #error "FLECS_NO_CPP failed: CPP is required by other addons" #endif + #include "../addons/flecs_cpp.h" +#ifndef FLECS_CPP20_MODULE_HEADER + #ifdef __cplusplus #include "../addons/cpp/flecs.hpp" #endif // __cplusplus +#endif // !FLECS_CPP20_MODULE_HEADER + #endif // FLECS_CPP #endif diff --git a/module/CMakeLists.txt b/module/CMakeLists.txt new file mode 100644 index 0000000000..0c72336200 --- /dev/null +++ b/module/CMakeLists.txt @@ -0,0 +1,10 @@ +add_library(flecs-module) + +target_sources(flecs-module PUBLIC + FILE_SET CXX_MODULES + BASE_DIRS ${PROJECT_SOURCE_DIR}/module + FILES flecs-module.cpp +) + +target_compile_features(flecs-module PUBLIC cxx_std_20) +target_link_libraries(flecs-module PRIVATE flecs) diff --git a/module/flecs-module.cpp b/module/flecs-module.cpp new file mode 100644 index 0000000000..8fbcf00d99 --- /dev/null +++ b/module/flecs-module.cpp @@ -0,0 +1,27 @@ +module; + +// TODO: find out why +#define FLECS_CPP_ENUM_REFLECTION_SUPPORT 0 + +#define FLECS_CPP20_MODULE_HEADER +#include "flecs.h" +#undef FLECS_CPP20_MODULE_HEADER + +#include +#include +#include +#include +#include +#include +#include + +export module flecs; + +#define FLECS_CUSTOM_STD_INCLUDE +#define FLECS_CPP20_MODULE_BODY +#undef FLECS_API +#define FLECS_API export +#define FLECS_API_STRUCT export +#define FLECS_API_GLOBAL export + +#include "flecs/addons/cpp/flecs.hpp"