From b14edbe1f43eff2ff4bd82a743d2446682fc4f67 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Sun, 16 Jun 2019 18:39:56 +0200 Subject: [PATCH] review: observer --- src/entt/entity/observer.hpp | 102 ++++++++++++++++++---------------- test/entt/entity/observer.cpp | 11 ++++ 2 files changed, 65 insertions(+), 48 deletions(-) diff --git a/src/entt/entity/observer.hpp b/src/entt/entity/observer.hpp index b51d5b85d..31682e794 100644 --- a/src/entt/entity/observer.hpp +++ b/src/entt/entity/observer.hpp @@ -168,40 +168,44 @@ class basic_observer { using traits_type = entt_traits; using payload_type = std::uint32_t; - template + template struct matcher_handler; - template - struct matcher_handler, type_list>, AnyOf>> { + template + struct matcher_handler, type_list>, AnyOf>> { + template static void maybe_valid_if(basic_observer *obs, const basic_registry ®, const Entity entt) { if(reg.template has(entt) && !(reg.template has(entt) || ...)) { (obs->view.has(entt) ? obs->view.get(entt) : obs->view.construct(entt)) |= (1 << Index); } } + template static void discard_if(basic_observer *obs, const basic_registry &, const Entity entt) { if(auto *value = obs->view.try_get(entt); value && !(*value &= (~(1 << Index)))) { obs->view.destroy(entt); } } - static void disconnect(basic_registry ®, const basic_observer &obs) { - reg.template on_replace().disconnect(&obs); - reg.template on_destroy().disconnect(&obs); - (reg.template on_destroy().disconnect(&obs), ...); - (reg.template on_construct().disconnect(&obs), ...); + template + static void connect(basic_observer &obs, basic_registry ®) { + (reg.template on_destroy().template connect<&discard_if>(&obs), ...); + (reg.template on_construct().template connect<&discard_if>(&obs), ...); + reg.template on_replace().template connect<&maybe_valid_if>(&obs); + reg.template on_destroy().template connect<&discard_if>(&obs); } - static void connect(basic_observer &obs, basic_registry ®) { - reg.template on_replace().template connect<&maybe_valid_if>(&obs); - reg.template on_destroy().template connect<&discard_if>(&obs); - (reg.template on_destroy().template connect<&discard_if>(&obs), ...); - (reg.template on_construct().template connect<&discard_if>(&obs), ...); + static void disconnect(basic_observer &obs, basic_registry ®) { + (reg.template on_destroy().disconnect(&obs), ...); + (reg.template on_construct().disconnect(&obs), ...); + reg.template on_replace().disconnect(&obs); + reg.template on_destroy().disconnect(&obs); } }; - template - struct matcher_handler, type_list>, type_list, type_list>> { + template + struct matcher_handler, type_list>, type_list, type_list>> { + template static void maybe_valid_if(basic_observer *obs, const basic_registry ®, const Entity entt) { if(reg.template has(entt) && !(reg.template has(entt) || ...) && reg.template has(entt) && !(reg.template has(entt) || ...)) @@ -210,41 +214,43 @@ class basic_observer { } } + template static void discard_if(basic_observer *obs, const basic_registry &, const Entity entt) { if(auto *value = obs->view.try_get(entt); value && !(*value &= (~(1 << Index)))) { obs->view.destroy(entt); } } - static void disconnect(basic_registry ®, const basic_observer &obs) { - ((reg.template on_construct().disconnect(&obs)), ...); - ((reg.template on_destroy().disconnect(&obs)), ...); - ((reg.template on_construct().disconnect(&obs)), ...); - ((reg.template on_destroy().disconnect(&obs)), ...); - (reg.template on_destroy().disconnect(&obs), ...); - (reg.template on_construct().disconnect(&obs), ...); + template + static void connect(basic_observer &obs, basic_registry ®) { + (reg.template on_destroy().template connect<&discard_if>(&obs), ...); + (reg.template on_construct().template connect<&discard_if>(&obs), ...); + (reg.template on_construct().template connect<&maybe_valid_if>(&obs), ...); + (reg.template on_destroy().template connect<&maybe_valid_if>(&obs), ...); + (reg.template on_destroy().template connect<&discard_if>(&obs), ...); + (reg.template on_construct().template connect<&discard_if>(&obs), ...); } - static void connect(basic_observer &obs, basic_registry ®) { - (reg.template on_construct().template connect<&maybe_valid_if>(&obs), ...); - (reg.template on_destroy().template connect<&maybe_valid_if>(&obs), ...); - (reg.template on_destroy().template connect<&discard_if>(&obs), ...); - (reg.template on_construct().template connect<&discard_if>(&obs), ...); - (reg.template on_destroy().template connect<&discard_if>(&obs), ...); - (reg.template on_construct().template connect<&discard_if>(&obs), ...); + static void disconnect(basic_observer &obs, basic_registry ®) { + (reg.template on_destroy().disconnect(&obs), ...); + (reg.template on_construct().disconnect(&obs), ...); + (reg.template on_construct().disconnect(&obs), ...); + (reg.template on_destroy().disconnect(&obs), ...); + (reg.template on_destroy().disconnect(&obs), ...); + (reg.template on_construct().disconnect(&obs), ...); } }; - template - static void disconnect(basic_registry ®, const basic_observer &obs) { - (Disconnect(reg, obs), ...); + template + static void disconnect(basic_observer &obs, basic_registry ®) { + (matcher_handler::disconnect(obs, reg), ...); } template void connect(basic_registry ®, std::index_sequence) { static_assert(sizeof...(Matcher) < std::numeric_limits::digits); - release = &basic_observer::disconnect<&matcher_handler::disconnect...>; - (matcher_handler::connect(*this, reg), ...); + (matcher_handler::template connect(*this, reg), ...); + release = &basic_observer::disconnect; } public: @@ -265,18 +271,6 @@ public: /*! @brief Default move constructor, deleted on purpose. */ basic_observer(basic_observer &&) = delete; - /** - * @brief Default copy assignment operator, deleted on purpose. - * @return This observer. - */ - basic_observer & operator=(const basic_observer &) = delete; - - /** - * @brief Default move assignment operator, deleted on purpose. - * @return This observer. - */ - basic_observer & operator=(basic_observer &&) = delete; - /** * @brief Creates an observer and connects it to a given registry. * @tparam Matcher Types of matchers to use to initialize the observer. @@ -294,6 +288,18 @@ public: /*! @brief Default destructor. */ ~basic_observer() = default; + /** + * @brief Default copy assignment operator, deleted on purpose. + * @return This observer. + */ + basic_observer & operator=(const basic_observer &) = delete; + + /** + * @brief Default move assignment operator, deleted on purpose. + * @return This observer. + */ + basic_observer & operator=(basic_observer &&) = delete; + /** * @brief Connects an observer to a given registry. * @tparam Matcher Types of matchers to use to initialize the observer. @@ -310,7 +316,7 @@ public: /*! @brief Disconnects an observer from the registry it keeps track of. */ void disconnect() { if(release) { - release(*target, *this); + release(*this, *target); release = nullptr; } } @@ -420,7 +426,7 @@ public: private: basic_registry *target; - void(* release)(basic_registry &, const basic_observer &); + void(* release)(basic_observer &, basic_registry &); storage view; }; diff --git a/test/entt/entity/observer.cpp b/test/entt/entity/observer.cpp index 9562552ed..aa40b5b65 100644 --- a/test/entt/entity/observer.cpp +++ b/test/entt/entity/observer.cpp @@ -122,6 +122,12 @@ TEST(Observer, AllOfFiltered) { registry.remove(entity); ASSERT_TRUE(observer.empty()); + + observer.disconnect(); + registry.remove(entity); + registry.assign(entity); + + ASSERT_TRUE(observer.empty()); } TEST(Observer, Observe) { @@ -195,6 +201,11 @@ TEST(Observer, ObserveFiltered) { registry.remove(entity); ASSERT_TRUE(observer.empty()); + + observer.disconnect(); + registry.replace(entity); + + ASSERT_TRUE(observer.empty()); } TEST(Observer, AllOfObserve) {