Forráskód Böngészése

family: review to make it work with dllimport/dllexport

Michele Caini 6 éve
szülő
commit
882b91b221

+ 1 - 1
TODO

@@ -51,5 +51,5 @@
     * meta
     * monostate
     * locator
-  - update doc
+  - update doc: family, dispatcher, emitter, registry, meta, across boundaries
   - update tests

+ 20 - 15
src/entt/core/family.hpp

@@ -3,30 +3,35 @@
 
 
 #include "../config/config.h"
+#include "../lib/attribute.h"
 
 
 namespace entt {
 
 
-/**
- * @brief Dynamic identifier generator.
- *
- * Utility class template that can be used to assign unique identifiers to types
- * at runtime. Use different specializations to create separate sets of
- * identifiers.
- */
+/*! @brief Sequential number generator. */
 template<typename...>
-class family {
-    inline static ENTT_MAYBE_ATOMIC(ENTT_ID_TYPE) identifier{};
+struct ENTT_API generator {
+    /**
+     * @brief Returns the next available value.
+     * @return The next available value.
+     */
+    static ENTT_ID_TYPE next() ENTT_NOEXCEPT {
+        static ENTT_MAYBE_ATOMIC(ENTT_ID_TYPE) value{};
+        return value++;
+    }
+};
 
-public:
-    /*! @brief Unsigned integer type. */
-    using family_type = ENTT_ID_TYPE;
 
+/**
+ * @brief Runtime type unique identifier.
+ * @tparam Type Type for which to generate an unique identifier.
+ * @tparam Generator Tags to use to discriminate between different generators.
+ */
+template<typename Type, typename... Generator>
+struct ENTT_API family {
     /*! @brief Statically generated unique identifier for the given type. */
-    template<typename... Type>
-    // at the time I'm writing, clang crashes during compilation if auto is used instead of family_type
-    inline static const family_type type = identifier++;
+    inline static const ENTT_ID_TYPE type = generator<Generator...>::next();
 };
 
 

+ 11 - 6
src/entt/entity/registry.hpp

@@ -14,6 +14,7 @@
 #include "../core/family.hpp"
 #include "../core/algorithm.hpp"
 #include "../core/type_traits.hpp"
+#include "../lib/attribute.h"
 #include "../signal/sigh.hpp"
 #include "runtime_view.hpp"
 #include "sparse_set.hpp"
@@ -45,8 +46,12 @@ class basic_registry {
     template<typename>
     friend class basic_registry;
 
-    using context_family = family<struct internal_registry_context_family>;
-    using component_family = family<struct internal_registry_component_family>;
+    template<typename Type>
+    using context_family = family<Type, struct ENTT_API internal_registry_context_family>;
+
+    template<typename Type>
+    using component_family = family<Type, struct ENTT_API internal_registry_component_family>;
+
     using traits_type = entt_traits<std::underlying_type_t<Entity>>;
 
     template<typename Component>
@@ -270,7 +275,7 @@ public:
      */
     template<typename Component>
     static component type() ENTT_NOEXCEPT {
-        return component{component_family::type<std::decay_t<Component>>};
+        return component{component_family<std::decay_t<Component>>::type};
     }
 
     /**
@@ -1625,7 +1630,7 @@ public:
      */
     template<typename Type, typename... Args>
     Type & set(Args &&... args) {
-        const auto vtype = context_family::type<std::decay_t<Type>>;
+        const auto vtype = context_family<std::decay_t<Type>>::type;
 
         if(!(vtype < vars.size())) {
             vars.resize(vtype+1);
@@ -1641,7 +1646,7 @@ public:
      */
     template<typename Type>
     void unset() {
-        if(const auto vtype = context_family::type<std::decay_t<Type>>; vtype < vars.size()) {
+        if(const auto vtype = context_family<std::decay_t<Type>>::type; vtype < vars.size()) {
             vars[vtype].reset();
         }
     }
@@ -1671,7 +1676,7 @@ public:
      */
     template<typename Type>
     const Type * try_ctx() const {
-        const auto vtype = context_family::type<std::decay_t<Type>>;
+        const auto vtype = context_family<std::decay_t<Type>>::type;
         return vtype < vars.size() && vars[vtype] ? &static_cast<variable_handler<Type> &>(*vars[vtype]).value : nullptr;
     }
 

+ 4 - 2
src/entt/signal/dispatcher.hpp

@@ -10,6 +10,7 @@
 #include <type_traits>
 #include "../config/config.h"
 #include "../core/family.hpp"
+#include "../lib/attribute.h"
 #include "sigh.hpp"
 
 
@@ -30,7 +31,8 @@ namespace entt {
  * crashes.
  */
 class dispatcher {
-    using event_family = family<struct internal_dispatcher_event_family>;
+    template<typename Type>
+    using event_family = family<Type, struct ENTT_API internal_dispatcher_event_family>;
 
     struct basic_pool {
         virtual ~basic_pool() = default;
@@ -78,7 +80,7 @@ class dispatcher {
 
     template<typename Event>
     pool_handler<Event> & assure() {
-        const auto etype = event_family::type<std::decay_t<Event>>;
+        const auto etype = event_family<Event>::type;
 
         if(!(etype < pools.size())) {
             pools.resize(etype+1);

+ 4 - 2
src/entt/signal/emitter.hpp

@@ -11,6 +11,7 @@
 #include <list>
 #include "../config/config.h"
 #include "../core/family.hpp"
+#include "../lib/attribute.h"
 
 
 namespace entt {
@@ -39,7 +40,8 @@ namespace entt {
  */
 template<typename Derived>
 class emitter {
-    using event_family = family<struct internal_emitter_event_family>;
+    template<typename Type>
+    using event_family = family<Type, struct ENTT_API internal_emitter_event_family>;
 
     struct basic_pool {
         virtual ~basic_pool() = default;
@@ -116,7 +118,7 @@ class emitter {
 
     template<typename Event>
     const pool_handler<Event> & assure() const {
-        const auto etype = event_family::type<std::decay_t<Event>>;
+        const auto etype = event_family<std::decay_t<Event>>::type;
 
         if(!(etype < pools.size())) {
             pools.resize(etype+1);

+ 12 - 9
test/entt/core/family.cpp

@@ -1,14 +1,17 @@
 #include <gtest/gtest.h>
 #include <entt/core/family.hpp>
 
-using a_family = entt::family<struct a_family_type>;
-using another_family = entt::family<struct another_family_type>;
+template<typename Type>
+using a_family = entt::family<Type, struct a_family_type>;
+
+template<typename Type>
+using another_family = entt::family<Type, struct another_family_type>;
 
 TEST(Family, Functionalities) {
-    auto t1 = a_family::type<int>;
-    auto t2 = a_family::type<int>;
-    auto t3 = a_family::type<char>;
-    auto t4 = another_family::type<double>;
+    auto t1 = a_family<int>::type;
+    auto t2 = a_family<int>::type;
+    auto t3 = a_family<char>::type;
+    auto t4 = another_family<double>::type;
 
     ASSERT_EQ(t1, t2);
     ASSERT_NE(t1, t3);
@@ -16,7 +19,7 @@ TEST(Family, Functionalities) {
 }
 
 TEST(Family, Uniqueness) {
-    ASSERT_NE(a_family::type<int>, a_family::type<int &>);
-    ASSERT_NE(a_family::type<int>, a_family::type<int &&>);
-    ASSERT_NE(a_family::type<int>, a_family::type<const int &>);
+    ASSERT_NE(a_family<int>::type, a_family<int &>::type);
+    ASSERT_NE(a_family<int>::type, a_family<int &&>::type);
+    ASSERT_NE(a_family<int>::type, a_family<const int &>::type);
 }