瀏覽代碼

registry: fixed a bug that affects late group initialization (close #436)

Michele Caini 6 年之前
父節點
當前提交
709d1c93a4
共有 3 個文件被更改,包括 20 次插入5 次删除
  1. 2 0
      TODO
  2. 5 5
      src/entt/entity/registry.hpp
  3. 13 0
      test/entt/entity/group.cpp

+ 2 - 0
TODO

@@ -16,6 +16,8 @@
 * any-of rule for views/groups (eg entity has A and any of B/C/D)
   - get -> all, exclude -> none
 * review prepare after clone and the others have been removed
+* !(has<T>(e) || ...) -> !any<T...>(e)
+* review pool<T>::remove, ::assign
 
 * WIP:
  - deprecate snapshot, loader, ...

+ 5 - 5
src/entt/entity/registry.hpp

@@ -1404,12 +1404,12 @@ public:
                     handler->current.construct(entity);
                 }
             } else {
-                const auto curr = view<Owned..., Get...>(exclude<Exclude...>);
-
                 // we cannot iterate backwards because we want to leave behind valid entities in case of owned types
-                std::for_each(std::make_reverse_iterator(curr.end()), std::make_reverse_iterator(curr.begin()), [cpools, handler](const auto entity) {
-                    if(const auto pos = handler->current; !(std::get<0>(cpools).index(entity) < ++handler->current)) {
-                        (std::get<pool_handler<std::decay_t<Owned>> &>(cpools).swap(std::get<pool_handler<std::decay_t<Owned>> &>(cpools).data()[pos], entity), ...);
+                std::for_each(std::get<0>(cpools).data(), std::get<0>(cpools).data() + std::get<0>(cpools).size(), [this, cpools, handler](const auto entity) {
+                    if(has<std::decay_t<Owned>..., std::decay_t<Get>...>(entity) && !any<Exclude...>(entity)) {
+                        if(const auto pos = handler->current; !(std::get<0>(cpools).index(entity) < ++handler->current)) {
+                            (std::get<pool_handler<std::decay_t<Owned>> &>(cpools).swap(std::get<pool_handler<std::decay_t<Owned>> &>(cpools).data()[pos], entity), ...);
+                        }
                     }
                 });
             }

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

@@ -1120,3 +1120,16 @@ TEST(OwningGroup, SignalRace) {
 
     ASSERT_EQ(registry.group<int>(entt::get<double>).size(), 1u);
 }
+
+TEST(OwningGroup, AfterFact) {
+    entt::registry registry;
+
+    for(std::size_t i{}; i < 30u; ++i) {
+        auto entity = registry.create();
+        if(!(i % 2u)) registry.assign<int>(entity);
+        if(!(i % 3u)) registry.assign<char>(entity);
+    }
+
+    // thanks to @pgruenbacher for pointing out this corner case
+    ASSERT_EQ((registry.group<int, char>().size()), 5u);
+}