Michele Caini 7 лет назад
Родитель
Сommit
a8838fc611
3 измененных файлов с 27 добавлено и 11 удалено
  1. 0 5
      TODO
  2. 14 6
      src/entt/entity/registry.hpp
  3. 13 0
      test/entt/entity/registry.cpp

+ 0 - 5
TODO

@@ -23,9 +23,4 @@
   - non-owning groups can iterate pages and skip empty ones, this should mitigate the lack of the packed array
 * review 64 bit id: user defined area + dedicated member on the registry to set it
 * add NIO to the EnTT in Action list (link to my CV/LinkedIN)
-
 * reactive systems
-  - add exclusion lists to views (part of signature in this case)
-  - add entt::opt for optional components both to views and groups
-  - add try_get both to views and groups (for optional components)
-  - setup support for reactive systems, something like: registry.reactive(entt:get<A...>, entt::opt<B...>, entt::exclude<C...>)

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

@@ -66,7 +66,7 @@ class basic_registry {
     template<typename Component>
     struct pool_wrapper: sparse_set<Entity, Component> {
         template<typename... Args>
-        Component & construct(Entity entt, Args &&... args) {
+        Component & construct(const Entity entt, Args &&... args) {
             auto &component = sparse_set<Entity, Component>::construct(entt, std::forward<Args>(args)...);
             construction.publish(*owner, entt);
             return component;
@@ -85,11 +85,20 @@ class basic_registry {
             return component;
         }
 
-        void destroy(Entity entt) override {
+        void destroy(const Entity entt) override {
             destruction.publish(*owner, entt);
             sparse_set<Entity, Component>::destroy(entt);
         }
 
+        template<typename... Args>
+        Component & replace(const Entity entt, Args &&... args) {
+            destruction.publish(*owner, entt);
+            auto &component = sparse_set<Entity, Component>::get(entt);
+            component = Component{std::forward<Args>(args)...};
+            construction.publish(*owner, entt);
+            return component;
+        }
+
         signal_type construction;
         signal_type destruction;
         basic_registry *owner;
@@ -855,7 +864,7 @@ public:
      */
     template<typename Component, typename... Args>
     Component & replace(const entity_type entity, Args &&... args) {
-        return pool<Component>()->get(entity) = Component{std::forward<Args>(args)...};
+        return pool<Component>()->replace(entity, std::forward<Args>(args)...);
     }
 
     /**
@@ -887,10 +896,9 @@ public:
     template<typename Component, typename... Args>
     Component & assign_or_replace(const entity_type entity, Args &&... args) {
         auto *cpool = assure<Component>();
-        auto *component = cpool->try_get(entity);
 
-        return component
-                ? (*component = Component{std::forward<Args>(args)...})
+        return cpool->has(entity)
+                ? cpool->replace(entity, std::forward<Args>(args)...)
                 : cpool->construct(entity, std::forward<Args>(args)...);
     }
 

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

@@ -909,10 +909,23 @@ TEST(Registry, Signals) {
     ASSERT_EQ(listener.counter, 1);
     ASSERT_EQ(listener.last, e0);
 
+    registry.destruction<int>().disconnect<&listener::decr<int>>(&listener);
+    registry.assign_or_replace<int>(e0);
+
+    ASSERT_EQ(listener.counter, 2);
+    ASSERT_EQ(listener.last, e0);
+
+    registry.construction<int>().disconnect<&listener::incr<int>>(&listener);
+    registry.destruction<int>().connect<&listener::decr<int>>(&listener);
     registry.assign_or_replace<int>(e0);
 
     ASSERT_EQ(listener.counter, 1);
     ASSERT_EQ(listener.last, e0);
+
+    registry.replace<int>(e0);
+
+    ASSERT_EQ(listener.counter, 0);
+    ASSERT_EQ(listener.last, e0);
 }
 
 TEST(Registry, DestroyByComponents) {