Przeglądaj źródła

thread safe family class + minor changes

Michele Caini 8 lat temu
rodzic
commit
9c540c03aa

+ 8 - 6
src/entt/core/family.hpp

@@ -4,6 +4,7 @@
 
 #include<type_traits>
 #include<cstddef>
+#include<atomic>
 
 
 namespace entt {
@@ -18,14 +19,11 @@ namespace entt {
  */
 template<typename...>
 class Family {
-    static std::size_t identifier() noexcept {
-        static std::size_t value = 0;
-        return value++;
-    }
+    static std::atomic<std::size_t> identifier;
 
     template<typename...>
     static std::size_t family() noexcept {
-        static const std::size_t value = identifier();
+        static const std::size_t value = identifier.fetch_add(1);
         return value;
     }
 
@@ -38,12 +36,16 @@ public:
      * @return Statically generated unique identifier for the given type.
      */
     template<typename... Type>
-    static family_type type() noexcept {
+    inline static family_type type() noexcept {
         return family<std::decay_t<Type>...>();
     }
 };
 
 
+template<typename... Types>
+std::atomic<std::size_t> Family<Types...>::identifier{};
+
+
 }
 
 

+ 9 - 7
src/entt/entity/sparse_set.hpp

@@ -331,7 +331,7 @@ public:
      *
      * @param other The sparse sets that imposes the order of the entities.
      */
-    virtual void respect(const SparseSet<Entity> &other) noexcept {
+    void respect(const SparseSet<Entity> &other) noexcept {
         auto from = other.begin();
         auto to = other.end();
 
@@ -610,8 +610,8 @@ public:
             auto next = copy[curr];
 
             while(curr != next) {
-                auto lhs = copy[curr];
-                auto rhs = copy[next];
+                const auto lhs = copy[curr];
+                const auto rhs = copy[next];
                 std::swap(instances[lhs], instances[rhs]);
                 underlying_type::swap(lhs, rhs);
                 copy[curr] = curr;
@@ -643,7 +643,7 @@ public:
      *
      * @param other The sparse sets that imposes the order of the entities.
      */
-    void respect(const SparseSet<Entity> &other) noexcept override {
+    void respect(const SparseSet<Entity> &other) noexcept {
         auto from = other.begin();
         auto to = other.end();
 
@@ -651,9 +651,11 @@ public:
         const auto *local = underlying_type::data();
 
         while(pos > 0 && from != to) {
-            if(underlying_type::has(*from)) {
-                if(*from != *(local + pos)) {
-                    auto candidate = underlying_type::get(*from);
+            const auto curr = *from;
+
+            if(underlying_type::has(curr)) {
+                if(curr != *(local + pos)) {
+                    auto candidate = underlying_type::get(curr);
                     std::swap(instances[pos], instances[candidate]);
                     underlying_type::swap(pos, candidate);
                 }

+ 42 - 0
test/entt/entity/registry.cpp

@@ -1,5 +1,7 @@
+#include <unordered_map>
 #include <unordered_set>
 #include <functional>
+#include <type_traits>
 #include <gtest/gtest.h>
 #include <entt/entity/registry.hpp>
 
@@ -431,3 +433,43 @@ TEST(DefaultRegistry, ConstructWithComponents) {
     const auto value = 0;
     registry.create(value);
 }
+
+TEST(DefaultRegistry, MergeTwoRegistries) {
+    using entity_type = typename entt::DefaultRegistry::entity_type;
+
+    entt::DefaultRegistry src;
+    entt::DefaultRegistry dst;
+
+    std::unordered_map<entity_type, entity_type> ref;
+
+    auto merge = [&ref](const auto &view, auto &dst) {
+        view.each([&](auto entity, const auto &component) {
+            if(ref.find(entity) == ref.cend()) {
+                ref.emplace(entity, dst.create(component));
+            } else {
+                using component_type = std::decay_t<decltype(component)>;
+                dst.template assign<component_type>(ref[entity], component);
+            }
+        });
+    };
+
+    src.create<int, float, double>();
+    src.create<char, float, int>();
+
+    dst.create<int, char, double>();
+    dst.create<float, int>();
+
+    auto eq = [](auto begin, auto end) { ASSERT_EQ(begin, end); };
+    auto ne = [](auto begin, auto end) { ASSERT_NE(begin, end); };
+
+    eq(dst.view<int, float, double>().begin(), dst.view<int, float, double>().end());
+    eq(dst.view<char, float, int>().begin(), dst.view<char, float, int>().end());
+
+    merge(src.view<int>(), dst);
+    merge(src.view<char>(), dst);
+    merge(src.view<double>(), dst);
+    merge(src.view<float>(), dst);
+
+    ne(dst.view<int, float, double>().begin(), dst.view<int, float, double>().end());
+    ne(dst.view<char, float, int>().begin(), dst.view<char, float, int>().end());
+}