diff --git a/TODO b/TODO index 2c07fdde3..5fde1a44b 100644 --- a/TODO +++ b/TODO @@ -17,3 +17,4 @@ - define systems as composable mixins (initializazion, reactive, update, whatever) with flexible auto-detected arguments (registry, views, etc) - from Tommaso on discord view().where([](h) {h > 5}).where([](t) {t.inside(aabb)}); * remove runtime views, welcome reflection and what about snapshot? +* add size+raw on multi comp views and groups, size retuns the actual size of the underlying pool and not that of the view/group diff --git a/docs/lib.md b/docs/lib.md index a30df975a..6564cab27 100644 --- a/docs/lib.md +++ b/docs/lib.md @@ -6,7 +6,7 @@ # Table of Contents * [Introduction](#introduction) -* [Shared types and traits class](#shared-types-and-traits-class) +* [Named types and traits class](#named-types-and-traits-class) * [Do not mix types](#do-not-mix-types) * [Macros, macros everywhere](#macros-macros-everywhere) * [Conflicts](#conflicts) @@ -27,13 +27,13 @@ The reasons for that are beyond the purposes of this document. However, the good news is that `EnTT` also offers now a way to overcome this limit and to push things across boundaries without problems when needed. -# Shared types and traits class +# Named types and traits class To allow a type to work properly across boundaries when used by a class that requires to assign unique identifiers to types, users must specialize a class template to literally give a compile-time name to the type itself.
-The name of the class template is `shared_traits` and the specialization must be -such that it exposes a static constexpr data member named `value` having type +The name of the class template is `name_type_traits` and the specialization must +be such that it exposes a static constexpr data member named `value` having type either `ENTT_ID_TYPE` or `entt::hashed_string::hash_type`. Its value is the user defined unique identifier assigned to the specific type.
Identifiers are not to be sequentially generated in this case. @@ -44,7 +44,7 @@ As an example: struct my_type { /* ... */ }; template<> -struct entt::shared_traits { +struct entt::named_type_traits { static constexpr auto value = "my_type"_hs; }; ``` @@ -58,17 +58,17 @@ way around was in fact forcing users to inherit all their classes from a common base. Something to avoid, at least from my point of view.
However, despite the fact that it's not intrusive, it would be great if it was also easier to use and a bit less error-prone. This is why a bunch of macros -exist to ease defining shared types. +exist to ease defining named types. ## Do not mix types Someone might think that this trick is valid only for the types to push across boundaries. This isn't how things work. In fact, the problem is more complex than that.
-As a rule of thumb, users should never mix shared and non-shared types. Whenever -a type is made shareable, all the types should be made shareable. As an example, -consider the `registry` class template. In case it is pushed across boundaries, -all the types of components should be shareable to avoid subtle bugs. +As a rule of thumb, users should never mix named and non-named types. Whenever +a type is given a name, all the types must be given a name. As an example, +consider the `registry` class template: in case it is pushed across boundaries, +all the types of components should be assigned a name to avoid subtle bugs. Indeed, this constraint can be relaxed in many cases. However, it is difficult to define a general rule to follow that is not the most stringent, unless users @@ -77,44 +77,44 @@ details on the topic. # Macros, macros everywhere -The library comes with a set of predefined macros to use to declare shared types +The library comes with a set of predefined macros to use to declare named types or export already existing ones. In particular: -* `ENTT_SHARED_TYPE` can be used to make shareable already existing types. This - macro must be used in the global namespace even when types to make shareable - are not. +* `ENTT_NAMED_TYPE` can be used to assign a name to already existing types. This + macro must be used in the global namespace even when the types to be named are + not. ```cpp - ENTT_SHARED_TYPE(my_type) - ENTT_SHARED_TYPE(ns::another_type) + ENTT_NAMED_TYPE(my_type) + ENTT_NAMED_TYPE(ns::another_type) ``` -* `ENTT_SHARED_STRUCT` can be used to define and export a struct at the same +* `ENTT_NAMED_STRUCT` can be used to define and export a struct at the same time. It accepts also an optional namespace in which to define the given type. This macro must be used in the global namespace. ```cpp - ENTT_SHARED_STRUCT(my_type, { /* struct definition */}) - ENTT_SHARED_STRUCT(ns, another_type, { /* struct definition */}) + ENTT_NAMED_STRUCT(my_type, { /* struct definition */}) + ENTT_NAMED_STRUCT(ns, another_type, { /* struct definition */}) ``` -* `ENTT_SHARED_CLASS` can be used to define and export a class at the same +* `ENTT_NAMED_CLASS` can be used to define and export a class at the same time. It accepts also an optional namespace in which to define the given type. This macro must be used in the global namespace. ```cpp - ENTT_SHARED_CLASS(my_type, { /* class definition */}) - ENTT_SHARED_CLASS(ns, another_type, { /* class definition */}) + ENTT_NAMED_CLASS(my_type, { /* class definition */}) + ENTT_NAMED_CLASS(ns, another_type, { /* class definition */}) ``` Nested namespaces are supported out of the box as well in all cases. As an example: ```cpp -ENTT_SHARED_STRUCT(nested::ns, my_type, { /* struct definition */}) +ENTT_NAMED_STRUCT(nested::ns, my_type, { /* struct definition */}) ``` -These macros can be used to avoid specializing the `shared_traits` class +These macros can be used to avoid specializing the `named_type_traits` class template. In all cases, the name of the class is used also as a seed to generate the compile-time unique identifier. @@ -127,7 +127,7 @@ the strangest things will probably take place.
Unfortunately, there is no safe way to prevent it. If this happens, it will be enough to give a different value to one of the conflicting types to solve the problem. To do this, users can either assign a different name to the class or -directly define a specialization for the `shared_traits` class template. +directly define a specialization for the `named_type_traits` class template. # Allocations: the dark side of the force diff --git a/src/entt/core/type_traits.hpp b/src/entt/core/type_traits.hpp index cabaa34a3..a7c69aed8 100644 --- a/src/entt/core/type_traits.hpp +++ b/src/entt/core/type_traits.hpp @@ -40,53 +40,53 @@ constexpr auto type_list_cat(type_list, type_list, List...) { /*! @brief Traits class used mainly to push things across boundaries. */ template -struct shared_traits; +struct named_type_traits; /** * @brief Specialization used to get rid of constness. - * @tparam Type Shared type. + * @tparam Type Named type. */ template -struct shared_traits - : shared_traits +struct named_type_traits + : named_type_traits {}; /** * @brief Helper type. - * @tparam Type Potentially shared type. + * @tparam Type Potentially named type. */ template -using shared_traits_t = typename shared_traits::type; +using named_type_traits_t = typename named_type_traits::type; /** - * @brief Provides the member constant `value` to true if a given type is - * shared. In all other cases, `value` is false. + * @brief Provides the member constant `value` to true if a given type has a + * name. In all other cases, `value` is false. */ template> -struct is_shared: std::false_type {}; +struct is_named_type: std::false_type {}; /** - * @brief Provides the member constant `value` to true if a given type is - * shared. In all other cases, `value` is false. - * @tparam Type Potentially shared type. + * @brief Provides the member constant `value` to true if a given type has a + * name. In all other cases, `value` is false. + * @tparam Type Potentially named type. */ template -struct is_shared>>>: std::true_type {}; +struct is_named_type>>>: std::true_type {}; /** * @brief Helper variable template. * - * True if a given type is shared, false otherwise. + * True if a given type has a name, false otherwise. * - * @tparam Type Potentially shared type. + * @tparam Type Potentially named type. */ template -constexpr auto is_shared_v = is_shared::value; +constexpr auto is_named_type_v = is_named_type::value; } @@ -103,68 +103,68 @@ constexpr auto is_shared_v = is_shared::value; /** - * @brief Makes an already existing type a shared type. - * @param type Type to make shareable. + * @brief Makes an already existing type a named type. + * @param type Type to assign a name to. */ -#define ENTT_SHARED_TYPE(type)\ +#define ENTT_NAMED_TYPE(type)\ template<>\ - struct entt::shared_traits\ + struct entt::named_type_traits\ : std::integral_constant\ {}; /** - * @brief Defines a type as shareable (to use for structs). - * @param clazz Name of the type to make shareable. - * @param body Body of the type to make shareable. + * @brief Defines a named type (to use for structs). + * @param clazz Name of the type to define. + * @param body Body of the type to define. */ -#define ENTT_SHARED_STRUCT_ONLY(clazz, body)\ +#define ENTT_NAMED_STRUCT_ONLY(clazz, body)\ struct clazz body;\ - ENTT_SHARED_TYPE(clazz) + ENTT_NAMED_TYPE(clazz) /** - * @brief Defines a type as shareable (to use for structs). - * @param ns Namespace where to define the type to make shareable. - * @param clazz Name of the type to make shareable. - * @param body Body of the type to make shareable. + * @brief Defines a named type (to use for structs). + * @param ns Namespace where to define the named type. + * @param clazz Name of the type to define. + * @param body Body of the type to define. */ -#define ENTT_SHARED_STRUCT_WITH_NAMESPACE(ns, clazz, body)\ +#define ENTT_NAMED_STRUCT_WITH_NAMESPACE(ns, clazz, body)\ namespace ns { struct clazz body; }\ - ENTT_SHARED_TYPE(ns::clazz) + ENTT_NAMED_TYPE(ns::clazz) /*! @brief Utility function to simulate macro overloading. */ -#define ENTT_SHARED_STRUCT_OVERLOAD(_1, _2, _3, FUNC, ...) FUNC -/*! @brief Defines a type as shareable (to use for structs). */ -#define ENTT_SHARED_STRUCT(...) ENTT_EXPAND(ENTT_SHARED_STRUCT_OVERLOAD(__VA_ARGS__, ENTT_SHARED_STRUCT_WITH_NAMESPACE, ENTT_SHARED_STRUCT_ONLY,)(__VA_ARGS__)) +#define ENTT_NAMED_STRUCT_OVERLOAD(_1, _2, _3, FUNC, ...) FUNC +/*! @brief Defines a named type (to use for structs). */ +#define ENTT_NAMED_STRUCT(...) ENTT_EXPAND(ENTT_NAMED_STRUCT_OVERLOAD(__VA_ARGS__, ENTT_NAMED_STRUCT_WITH_NAMESPACE, ENTT_NAMED_STRUCT_ONLY,)(__VA_ARGS__)) /** - * @brief Defines a type as shareable (to use for classes). - * @param clazz Name of the type to make shareable. - * @param body Body of the type to make shareable. + * @brief Defines a named type (to use for classes). + * @param clazz Name of the type to define. + * @param body Body of the type to define. */ -#define ENTT_SHARED_CLASS_ONLY(clazz, body)\ +#define ENTT_NAMED_CLASS_ONLY(clazz, body)\ class clazz body;\ - ENTT_SHARED_TYPE(clazz) + ENTT_NAMED_TYPE(clazz) /** - * @brief Defines a type as shareable (to use for classes). - * @param ns Namespace where to define the type to make shareable. - * @param clazz Name of the type to make shareable. - * @param body Body of the type to make shareable. + * @brief Defines a named type (to use for classes). + * @param ns Namespace where to define the named type. + * @param clazz Name of the type to define. + * @param body Body of the type to define. */ -#define ENTT_SHARED_CLASS_WITH_NAMESPACE(ns, clazz, body)\ +#define ENTT_NAMED_CLASS_WITH_NAMESPACE(ns, clazz, body)\ namespace ns { class clazz body; }\ - ENTT_SHARED_TYPE(ns::clazz) + ENTT_NAMED_TYPE(ns::clazz) /*! @brief Utility function to simulate macro overloading. */ -#define ENTT_SHARED_CLASS_MACRO(_1, _2, _3, FUNC, ...) FUNC -/*! @brief Defines a type as shareable (to use for classes). */ -#define ENTT_SHARED_CLASS(...) ENTT_EXPAND(ENTT_SHARED_CLASS_MACRO(__VA_ARGS__, ENTT_SHARED_CLASS_WITH_NAMESPACE, ENTT_SHARED_CLASS_ONLY,)(__VA_ARGS__)) +#define ENTT_NAMED_CLASS_MACRO(_1, _2, _3, FUNC, ...) FUNC +/*! @brief Defines a named type (to use for classes). */ +#define ENTT_NAMED_CLASS(...) ENTT_EXPAND(ENTT_NAMED_CLASS_MACRO(__VA_ARGS__, ENTT_NAMED_CLASS_WITH_NAMESPACE, ENTT_NAMED_CLASS_ONLY,)(__VA_ARGS__)) #endif // ENTT_CORE_TYPE_TRAITS_HPP diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index 0828a1b09..dd0f47dbb 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -182,7 +182,7 @@ class basic_registry { inline const auto * pool() const ENTT_NOEXCEPT { const auto ctype = type(); - if constexpr(is_shared_v) { + if constexpr(is_named_type_v) { const auto it = std::find_if(pools.begin(), pools.end(), [ctype](const auto &pdata) { return pdata.pool && pdata.runtime_type == ctype; }); @@ -207,7 +207,7 @@ class basic_registry { const auto ctype = type(); pool_data *pdata = nullptr; - if constexpr(is_shared_v) { + if constexpr(is_named_type_v) { const auto it = std::find_if(pools.begin(), pools.end(), [ctype](const auto &pdata) { return pdata.pool && pdata.runtime_type == ctype; }); @@ -270,8 +270,8 @@ public: */ template static component_type type() ENTT_NOEXCEPT { - if constexpr(is_shared_v) { - return shared_traits::value; + if constexpr(is_named_type_v) { + return named_type_traits::value; } else { return component_family::type; } diff --git a/src/entt/signal/dispatcher.hpp b/src/entt/signal/dispatcher.hpp index 2fe3f1d61..ecc878e88 100644 --- a/src/entt/signal/dispatcher.hpp +++ b/src/entt/signal/dispatcher.hpp @@ -80,8 +80,8 @@ class dispatcher { template static auto type() ENTT_NOEXCEPT { - if constexpr(is_shared_v) { - return shared_traits::value; + if constexpr(is_named_type_v) { + return named_type_traits::value; } else { return event_family::type; } @@ -92,7 +92,7 @@ class dispatcher { const auto wtype = type(); wrapper_data *wdata = nullptr; - if constexpr(is_shared_v) { + if constexpr(is_named_type_v) { const auto it = std::find_if(wrappers.begin(), wrappers.end(), [wtype](const auto &wdata) { return wdata.wrapper && wdata.runtime_type == wtype; }); diff --git a/src/entt/signal/emitter.hpp b/src/entt/signal/emitter.hpp index dc9d6be2c..2baae425a 100644 --- a/src/entt/signal/emitter.hpp +++ b/src/entt/signal/emitter.hpp @@ -122,8 +122,8 @@ class emitter { template static auto type() ENTT_NOEXCEPT { - if constexpr(is_shared_v) { - return shared_traits::value; + if constexpr(is_named_type_v) { + return named_type_traits::value; } else { return handler_family::type; } @@ -134,7 +134,7 @@ class emitter { const auto htype = type(); handler_data *hdata = nullptr; - if constexpr(is_shared_v) { + if constexpr(is_named_type_v) { const auto it = std::find_if(handlers.begin(), handlers.end(), [htype](const auto &hdata) { return hdata.handler && hdata.runtime_type == htype; }); diff --git a/test/entt/entity/registry.cpp b/test/entt/entity/registry.cpp index 46c5a1382..6522b7bfb 100644 --- a/test/entt/entity/registry.cpp +++ b/test/entt/entity/registry.cpp @@ -9,7 +9,7 @@ #include #include -ENTT_SHARED_TYPE(int) +ENTT_NAMED_TYPE(int) struct listener { template diff --git a/test/entt/signal/dispatcher.cpp b/test/entt/signal/dispatcher.cpp index a95c5ed7b..5d9507bb0 100644 --- a/test/entt/signal/dispatcher.cpp +++ b/test/entt/signal/dispatcher.cpp @@ -7,7 +7,7 @@ struct an_event {}; struct another_event {}; struct one_more_event {}; -ENTT_SHARED_TYPE(an_event) +ENTT_NAMED_TYPE(an_event) struct receiver { void receive(const an_event &) { ++cnt; } diff --git a/test/entt/signal/emitter.cpp b/test/entt/signal/emitter.cpp index fd81d6fd0..022018869 100644 --- a/test/entt/signal/emitter.cpp +++ b/test/entt/signal/emitter.cpp @@ -8,7 +8,7 @@ struct foo_event { int i; char c; }; struct bar_event {}; struct quux_event {}; -ENTT_SHARED_TYPE(foo_event) +ENTT_NAMED_TYPE(foo_event) TEST(Emitter, Clear) { test_emitter emitter; diff --git a/test/lib/a_module.cpp b/test/lib/a_module.cpp index 4d0907fcf..44f641f4b 100644 --- a/test/lib/a_module.cpp +++ b/test/lib/a_module.cpp @@ -13,10 +13,10 @@ #endif #endif -ENTT_SHARED_TYPE(int) -ENTT_SHARED_TYPE(char) -ENTT_SHARED_TYPE(double) -ENTT_SHARED_TYPE(float) +ENTT_NAMED_TYPE(int) +ENTT_NAMED_TYPE(char) +ENTT_NAMED_TYPE(double) +ENTT_NAMED_TYPE(float) LIB_EXPORT typename entt::registry::component_type a_module_int_type() { entt::registry registry; diff --git a/test/lib/another_module.cpp b/test/lib/another_module.cpp index 77da6c42c..b1155d207 100644 --- a/test/lib/another_module.cpp +++ b/test/lib/another_module.cpp @@ -13,10 +13,10 @@ #endif #endif -ENTT_SHARED_TYPE(int) -ENTT_SHARED_TYPE(char) -ENTT_SHARED_TYPE(double) -ENTT_SHARED_TYPE(float) +ENTT_NAMED_TYPE(int) +ENTT_NAMED_TYPE(char) +ENTT_NAMED_TYPE(double) +ENTT_NAMED_TYPE(float) LIB_EXPORT typename entt::registry::component_type another_module_int_type() { entt::registry registry; diff --git a/test/lib/lib.cpp b/test/lib/lib.cpp index 0adecb9a7..aec85fd4b 100644 --- a/test/lib/lib.cpp +++ b/test/lib/lib.cpp @@ -22,8 +22,8 @@ struct listener { int value; }; -ENTT_SHARED_TYPE(int) -ENTT_SHARED_TYPE(char) +ENTT_NAMED_TYPE(int) +ENTT_NAMED_TYPE(char) TEST(Lib, Types) { entt::registry registry; diff --git a/test/lib/types.h b/test/lib/types.h index 17254beb8..f26b100fa 100644 --- a/test/lib/types.h +++ b/test/lib/types.h @@ -5,18 +5,18 @@ struct test_emitter : entt::emitter {}; -ENTT_SHARED_STRUCT(position, { +ENTT_NAMED_STRUCT(position, { int x; int y; }) -ENTT_SHARED_STRUCT(velocity, { +ENTT_NAMED_STRUCT(velocity, { int dx; int dy; }) -ENTT_SHARED_STRUCT(an_event, { +ENTT_NAMED_STRUCT(an_event, { int payload; }) -ENTT_SHARED_STRUCT(another_event, {}) +ENTT_NAMED_STRUCT(another_event, {})