Michele Caini 7 anni fa
parent
commit
3e6ded8823
4 ha cambiato i file con 104 aggiunte e 3 eliminazioni
  1. 11 0
      README.md
  2. 0 2
      TODO
  3. 42 1
      src/entt/entity/registry.hpp
  4. 51 0
      test/entt/entity/registry.cpp

+ 11 - 0
README.md

@@ -407,6 +407,17 @@ auto entity = registry.create();
 registry.destroy(entity);
 ```
 
+Entities can also be destroyed _by type_, that is by specifying the types of the
+tags or components that identify them:
+
+```cpp
+// destroys the entity that owns the given tag, if any
+registry.destroy<MyTag>(entt::tag_t{});
+
+// destroys the entities that own the given components, if any
+registry.destroy<AComponent, AnotherComponent>();
+```
+
 When an entity is destroyed, the registry can freely reuse it internally with a
 slightly different identifier. In particular, the version of an entity is
 increased each and every time it's discarded.<br/>

+ 0 - 2
TODO

@@ -7,8 +7,6 @@
 * define systems as composable mixins (initializazion, reactive, update, whatever) with flexible auto-detected arguments (registry, views, etc)
 * create dedicated flat map based on types implementation (sort of "type map") for types to use within the registry and so on...
 * ease the assignment of tags as string (use a template class with a non-type template parameter behind the scene)
-* "singleton mode" for tags (see #66)
-* add a shortcut to destroy all the entities that have components X, Y, Z (view and registry?)
 * is it possible to use EASTL instead of the standard library?
 * C++17. That's all.
 * AOB

+ 42 - 1
src/entt/entity/registry.hpp

@@ -383,7 +383,7 @@ public:
      * function can be used to know if they are still valid or the entity has
      * been destroyed and potentially recycled.
      *
-     * The returned entity has no components assigned.
+     * The returned entity has no components nor tags assigned.
      *
      * @return A valid entity identifier.
      */
@@ -408,6 +408,25 @@ public:
         return entity;
     }
 
+    /**
+     * @brief Destroys the entity that owns the given tag, if any.
+     *
+     * Convenient shortcut to destroy an entity by means of a tag type.<br/>
+     * Syntactic sugar for the following snippet:
+     *
+     * @code{.cpp}
+     * if(registry.has<Tag>()) {
+     *     registry.destroy(registry.attachee<Tag>());
+     * }
+     * @endcode
+     *
+     * @tparam Tag Type of tag to use to search for the entity.
+     */
+    template<typename Tag>
+    void destroy(tag_t) {
+        return has<Tag>() ? destroy(attachee<Tag>()) : void();
+    }
+
     /**
      * @brief Destroys an entity and lets the registry recycle the identifier.
      *
@@ -465,6 +484,28 @@ public:
         ++available;
     }
 
+    /**
+     * @brief Destroys the entities that own he given components, if any.
+     *
+     * Convenient shortcut to destroy a set of entities at once.<br/>
+     * Syntactic sugar for the following snippet:
+     *
+     * @code{.cpp}
+     * for(const auto entity: registry.view<Component...>(Type{}...)) {
+     *     registry.destroy(entity);
+     * }
+     * @endcode
+     *
+     * @tparam Component Types of components to use to search for the entities.
+     * @tparam Type Type of view to use or empty to use a standard view.
+     */
+    template<typename... Component, typename... Type>
+    void destroy(Type...) {
+        for(const auto entity: view<Component...>(Type{}...)) {
+            destroy(entity);
+        }
+    }
+
     /**
      * @brief Attaches the given tag to an entity.
      *

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

@@ -741,3 +741,54 @@ TEST(DefaultRegistry, TagSignals) {
     ASSERT_EQ(listener.counter, 0);
     ASSERT_EQ(listener.last, e0);
 }
+
+TEST(DefaultRegistry, DestroyByTagAndComponents) {
+    entt::DefaultRegistry registry;
+
+    const auto e0 = registry.create();
+    const auto e1 = registry.create();
+    const auto e2 = registry.create();
+    const auto e3 = registry.create();
+
+    registry.assign<int>(e0);
+    registry.assign<char>(e0);
+    registry.assign<double>(e0);
+
+    registry.assign<int>(e1);
+    registry.assign<char>(e1);
+
+    registry.assign<int>(e2);
+
+    registry.assign<float>(entt::tag_t{}, e3);
+
+    ASSERT_TRUE(registry.valid(e0));
+    ASSERT_TRUE(registry.valid(e1));
+    ASSERT_TRUE(registry.valid(e2));
+    ASSERT_TRUE(registry.valid(e3));
+
+    registry.destroy<int, char, double>(entt::persistent_t{});
+
+    ASSERT_FALSE(registry.valid(e0));
+    ASSERT_TRUE(registry.valid(e1));
+    ASSERT_TRUE(registry.valid(e2));
+    ASSERT_TRUE(registry.valid(e3));
+
+    registry.destroy<int, char>();
+
+    ASSERT_FALSE(registry.valid(e0));
+    ASSERT_FALSE(registry.valid(e1));
+    ASSERT_TRUE(registry.valid(e2));
+    ASSERT_TRUE(registry.valid(e3));
+
+    registry.destroy<int>();
+
+    ASSERT_FALSE(registry.valid(e0));
+    ASSERT_FALSE(registry.valid(e1));
+    ASSERT_FALSE(registry.valid(e2));
+    ASSERT_TRUE(registry.valid(e3));
+
+    registry.destroy<int>(entt::tag_t{});
+    registry.destroy<char>(entt::tag_t{});
+    registry.destroy<double>(entt::tag_t{});
+    registry.destroy<float>(entt::tag_t{});
+}