1
0
Michele Caini 6 жил өмнө
parent
commit
b72cf5d364

+ 16 - 12
src/entt/entity/observer.hpp

@@ -52,7 +52,7 @@ struct basic_collector<> {
      */
     template<typename... AllOf, typename... NoneOf>
     static constexpr auto group(exclude_t<NoneOf...> = {}) ENTT_NOEXCEPT {
-        return basic_collector<matcher<matcher<type_list<>, type_list<>>, type_list<NoneOf...>, type_list<AllOf...>>>{};
+        return basic_collector<matcher<type_list<>, type_list<>, type_list<NoneOf...>, AllOf...>>{};
     }
 
     /**
@@ -62,18 +62,23 @@ struct basic_collector<> {
      */
     template<typename AnyOf>
     static constexpr auto replace() ENTT_NOEXCEPT {
-        return basic_collector<matcher<matcher<type_list<>, type_list<>>, AnyOf>>{};
+        return basic_collector<matcher<type_list<>, type_list<>, AnyOf>>{};
     }
 };
 
 /**
  * @brief Collector.
  * @copydetails basic_collector<>
- * @tparam AnyOf Types of components for which changes should be detected.
- * @tparam Matcher Types of grouping matchers.
+ * @tparam Reject Untracked types used to filter out entities.
+ * @tparam Require Untracked types required by the matcher.
+ * @tparam Rule Specific details of the current matcher.
+ * @tparam Other Other matchers.
  */
 template<typename... Reject, typename... Require, typename... Rule, typename... Other>
-struct basic_collector<matcher<matcher<type_list<Reject...>, type_list<Require...>>, Rule...>, Other...> {
+struct basic_collector<matcher<type_list<Reject...>, type_list<Require...>, Rule...>, Other...> {
+    /*! @brief Current matcher. */
+    using current_type = matcher<type_list<Reject...>, type_list<Require...>, Rule...>;
+
     /**
      * @brief Adds a grouping matcher to the collector.
      * @tparam AllOf Types of components tracked by the matcher.
@@ -82,8 +87,7 @@ struct basic_collector<matcher<matcher<type_list<Reject...>, type_list<Require..
      */
     template<typename... AllOf, typename... NoneOf>
     static constexpr auto group(exclude_t<NoneOf...> = {}) ENTT_NOEXCEPT {
-        using first = matcher<matcher<type_list<Reject...>, type_list<Require...>>, Rule...>;
-        return basic_collector<matcher<matcher<type_list<>, type_list<>>, type_list<NoneOf...>, type_list<AllOf...>>, first, Other...>{};
+        return basic_collector<matcher<type_list<>, type_list<>, type_list<NoneOf...>, AllOf...>, current_type, Other...>{};
     }
 
     /**
@@ -93,8 +97,7 @@ struct basic_collector<matcher<matcher<type_list<Reject...>, type_list<Require..
      */
     template<typename AnyOf>
     static constexpr auto replace() ENTT_NOEXCEPT {
-        using first = matcher<matcher<type_list<Reject...>, type_list<Require...>>, Rule...>;
-        return basic_collector<matcher<matcher<type_list<>, type_list<>>, AnyOf>, first, Other...>{};
+        return basic_collector<matcher<type_list<>, type_list<>, AnyOf>, current_type, Other...>{};
     }
 
     /**
@@ -105,7 +108,8 @@ struct basic_collector<matcher<matcher<type_list<Reject...>, type_list<Require..
      */
     template<typename... AllOf, typename... NoneOf>
     static constexpr auto where(exclude_t<NoneOf...> = {}) ENTT_NOEXCEPT {
-        return basic_collector<matcher<matcher<type_list<Reject..., NoneOf...>, type_list<Require..., AllOf...>>, Rule...>, Other...>{};
+        using extended_type = matcher<type_list<Reject..., NoneOf...>, type_list<Require..., AllOf...>, Rule...>;
+        return basic_collector<extended_type, Other...>{};
     }
 };
 
@@ -171,7 +175,7 @@ class basic_observer {
     struct matcher_handler;
 
     template<typename... Reject, typename... Require, typename AnyOf>
-    struct matcher_handler<matcher<matcher<type_list<Reject...>, type_list<Require...>>, AnyOf>> {
+    struct matcher_handler<matcher<type_list<Reject...>, type_list<Require...>, AnyOf>> {
         template<std::size_t Index>
         static void maybe_valid_if(basic_observer &obs, const Entity entt, const basic_registry<Entity> &reg) {
             if(reg.template has<Require...>(entt) && !(reg.template has<Reject>(entt) || ...)) {
@@ -204,7 +208,7 @@ class basic_observer {
     };
 
     template<typename... Reject, typename... Require, typename... NoneOf, typename... AllOf>
-    struct matcher_handler<matcher<matcher<type_list<Reject...>, type_list<Require...>>, type_list<NoneOf...>, type_list<AllOf...>>> {
+    struct matcher_handler<matcher<type_list<Reject...>, type_list<Require...>, type_list<NoneOf...>, AllOf...>> {
         template<std::size_t Index>
         static void maybe_valid_if(basic_observer &obs, const Entity entt, const basic_registry<Entity> &reg) {
             if(reg.template has<AllOf...>(entt) && !(reg.template has<NoneOf>(entt) || ...)

+ 71 - 80
test/entt/entity/observer.cpp

@@ -1,4 +1,5 @@
 #include <tuple>
+#include <cstddef>
 #include <type_traits>
 #include <gtest/gtest.h>
 #include <entt/entity/observer.hpp>
@@ -8,14 +9,14 @@ TEST(Observer, Functionalities) {
     entt::registry registry;
     entt::observer observer{registry, entt::collector.group<int>()};
 
-    ASSERT_EQ(observer.size(), entt::observer::size_type{});
+    ASSERT_EQ(observer.size(), 0u);
     ASSERT_TRUE(observer.empty());
     ASSERT_EQ(observer.data(), nullptr);
     ASSERT_EQ(observer.begin(), observer.end());
 
     const auto entity = std::get<0>(registry.create<int>());
 
-    ASSERT_EQ(observer.size(), entt::observer::size_type{1});
+    ASSERT_EQ(observer.size(), 1u);
     ASSERT_FALSE(observer.empty());
     ASSERT_NE(observer.data(), nullptr);
     ASSERT_EQ(*observer.data(), entity);
@@ -25,14 +26,14 @@ TEST(Observer, Functionalities) {
 
     observer.clear();
 
-    ASSERT_EQ(observer.size(), entt::observer::size_type{});
+    ASSERT_EQ(observer.size(), 0u);
     ASSERT_TRUE(observer.empty());
 
     observer.disconnect();
     registry.remove<int>(entity);
     registry.assign<int>(entity);
 
-    ASSERT_EQ(observer.size(), entt::observer::size_type{});
+    ASSERT_EQ(observer.size(), 0u);
     ASSERT_TRUE(observer.empty());
 }
 
@@ -50,7 +51,7 @@ TEST(Observer, AllOf) {
     registry.assign<int>(entity);
     registry.assign<char>(entity);
 
-    ASSERT_EQ(observer.size(), entt::observer::size_type{1});
+    ASSERT_EQ(observer.size(), 1u);
     ASSERT_FALSE(observer.empty());
     ASSERT_EQ(*observer.data(), entity);
 
@@ -96,7 +97,7 @@ TEST(Observer, AllOfFiltered) {
 
     registry.assign<int>(entity);
 
-    ASSERT_EQ(observer.size(), entt::observer::size_type{});
+    ASSERT_EQ(observer.size(), 0u);
     ASSERT_TRUE(observer.empty());
     ASSERT_EQ(observer.data(), nullptr);
 
@@ -111,7 +112,7 @@ TEST(Observer, AllOfFiltered) {
     registry.remove<double>(entity);
     registry.assign<int>(entity);
 
-    ASSERT_EQ(observer.size(), entt::observer::size_type{1});
+    ASSERT_EQ(observer.size(), 1u);
     ASSERT_FALSE(observer.empty());
     ASSERT_EQ(*observer.data(), entity);
 
@@ -130,72 +131,6 @@ TEST(Observer, AllOfFiltered) {
     ASSERT_TRUE(observer.empty());
 }
 
-TEST(Observer, WhereChain) {
-    constexpr auto collector =  entt::collector
-            .replace<int>().where<char>()
-            .replace<double>().where<float>();
-
-    entt::registry registry;
-    entt::observer observer{registry, collector};
-    const auto entity = registry.create();
-
-    ASSERT_TRUE(observer.empty());
-
-    registry.assign<int>(entity);
-
-    ASSERT_TRUE(observer.empty());
-
-    registry.assign_or_replace<int>(entity);
-
-    ASSERT_TRUE(observer.empty());
-
-    registry.assign<char>(entity);
-
-    ASSERT_TRUE(observer.empty());
-
-    registry.assign_or_replace<int>(entity);
-
-    ASSERT_EQ(observer.size(), entt::observer::size_type{ 1 });
-    ASSERT_FALSE(observer.empty());
-    ASSERT_EQ(*observer.data(), entity);
-
-    observer.clear();
-    registry.assign<double>(entity);
-
-    ASSERT_TRUE(observer.empty());
-
-    registry.assign_or_replace<double>(entity);
-
-    ASSERT_TRUE(observer.empty());
-
-    registry.assign<float>(entity);
-
-    ASSERT_TRUE(observer.empty());
-
-    registry.assign_or_replace<double>(entity);
-
-    ASSERT_EQ(observer.size(), entt::observer::size_type{ 1 });
-    ASSERT_FALSE(observer.empty());
-    ASSERT_EQ(*observer.data(), entity);
-
-    registry.remove<float>(entity);
-
-    ASSERT_TRUE(observer.empty());
-
-    registry.assign_or_replace<int>(entity);
-
-    ASSERT_EQ(observer.size(), entt::observer::size_type{ 1 });
-    ASSERT_FALSE(observer.empty());
-    ASSERT_EQ(*observer.data(), entity);
-
-    observer.clear();
-    observer.disconnect();
-
-    registry.assign_or_replace<int>(entity);
-
-    ASSERT_TRUE(observer.empty());
-}
-
 TEST(Observer, Observe) {
     entt::registry registry;
     entt::observer observer{registry, entt::collector.replace<int>().replace<char>()};
@@ -210,7 +145,7 @@ TEST(Observer, Observe) {
 
     registry.assign_or_replace<int>(entity);
 
-    ASSERT_EQ(observer.size(), entt::observer::size_type{1});
+    ASSERT_EQ(observer.size(), 1u);
     ASSERT_FALSE(observer.empty());
     ASSERT_EQ(*observer.data(), entity);
 
@@ -243,7 +178,7 @@ TEST(Observer, ObserveFiltered) {
     registry.assign<int>(entity);
     registry.replace<int>(entity);
 
-    ASSERT_EQ(observer.size(), entt::observer::size_type{});
+    ASSERT_EQ(observer.size(), 0u);
     ASSERT_TRUE(observer.empty());
     ASSERT_EQ(observer.data(), nullptr);
 
@@ -256,7 +191,7 @@ TEST(Observer, ObserveFiltered) {
     registry.remove<double>(entity);
     registry.replace<int>(entity);
 
-    ASSERT_EQ(observer.size(), entt::observer::size_type{1});
+    ASSERT_EQ(observer.size(), 1u);
     ASSERT_FALSE(observer.empty());
     ASSERT_EQ(*observer.data(), entity);
 
@@ -288,7 +223,7 @@ TEST(Observer, AllOfObserve) {
     registry.replace<char>(entity);
     registry.remove<int>(entity);
 
-    ASSERT_EQ(observer.size(), entt::observer::size_type{1});
+    ASSERT_EQ(observer.size(), 1u);
     ASSERT_FALSE(observer.empty());
     ASSERT_EQ(*observer.data(), entity);
 
@@ -331,19 +266,75 @@ TEST(Observer, Each) {
     const auto entity = std::get<0>(registry.create<int>());
 
     ASSERT_FALSE(observer.empty());
-    ASSERT_EQ(observer.size(), entt::observer::size_type{1});
+    ASSERT_EQ(observer.size(), 1u);
 
     std::as_const(observer).each([entity](const auto entt) {
         ASSERT_EQ(entity, entt);
     });
 
     ASSERT_FALSE(observer.empty());
-    ASSERT_EQ(observer.size(), entt::observer::size_type{1});
+    ASSERT_EQ(observer.size(), 1u);
 
     observer.each([entity](const auto entt) {
         ASSERT_EQ(entity, entt);
     });
 
     ASSERT_TRUE(observer.empty());
-    ASSERT_EQ(observer.size(), entt::observer::size_type{});
+    ASSERT_EQ(observer.size(), 0u);
+}
+
+TEST(Observer, MultipleFilters) {
+    constexpr auto collector =  entt::collector
+            .replace<int>().where<char>()
+            .replace<double>().where<float>();
+
+    entt::registry registry;
+    entt::observer observer{registry, collector};
+    const auto entity = registry.create();
+
+    ASSERT_TRUE(observer.empty());
+
+    registry.assign_or_replace<int>(entity);
+    registry.assign<char>(entity);
+
+    ASSERT_TRUE(observer.empty());
+
+    registry.assign_or_replace<int>(entity);
+
+    ASSERT_EQ(observer.size(), 1u);
+    ASSERT_FALSE(observer.empty());
+    ASSERT_EQ(*observer.data(), entity);
+
+    observer.clear();
+    registry.assign<double>(entity);
+
+    ASSERT_TRUE(observer.empty());
+
+    registry.assign_or_replace<double>(entity);
+    registry.assign<float>(entity);
+
+    ASSERT_TRUE(observer.empty());
+
+    registry.assign_or_replace<double>(entity);
+
+    ASSERT_EQ(observer.size(), 1u);
+    ASSERT_FALSE(observer.empty());
+    ASSERT_EQ(*observer.data(), entity);
+
+    registry.remove<float>(entity);
+
+    ASSERT_TRUE(observer.empty());
+
+    registry.assign_or_replace<int>(entity);
+
+    ASSERT_EQ(observer.size(), 1u);
+    ASSERT_FALSE(observer.empty());
+    ASSERT_EQ(*observer.data(), entity);
+
+    observer.clear();
+    observer.disconnect();
+
+    registry.assign_or_replace<int>(entity);
+
+    ASSERT_TRUE(observer.empty());
 }