فهرست منبع

entity: sigh_helper utility with tests (close #928)

Michele Caini 3 سال پیش
والد
کامیت
66e1a05652
2فایلهای تغییر یافته به همراه124 افزوده شده و 0 حذف شده
  1. 98 0
      src/entt/entity/helper.hpp
  2. 26 0
      test/entt/entity/helper.cpp

+ 98 - 0
src/entt/entity/helper.hpp

@@ -139,6 +139,104 @@ typename Registry::entity_type to_entity(const Registry &reg, const Component &i
     return null;
 }
 
+/*! @brief Primary template isn't defined on purpose. */
+template<typename...>
+struct sigh_helper;
+
+/**
+ * @brief Signal connection helper for registries.
+ * @tparam Registry Basic registry type.
+ */
+template<typename Registry>
+struct sigh_helper<Registry> {
+    /*! @brief Registry type. */
+    using registry_type = Registry;
+
+    /**
+     * @brief Constructs a helper for a given registry.
+     * @param ref A valid reference to a registry.
+     */
+    sigh_helper(registry_type &ref)
+        : bucket{&ref} {}
+
+    /**
+     * @brief Binds a properly initialized helper to a given signal type.
+     * @tparam Type Type of signal to bind the helper to.
+     * @return A helper for a given registry and signal type.
+     */
+    template<typename Type>
+    auto with() noexcept {
+        return sigh_helper<registry_type, Type>{*bucket};
+    }
+
+    /**
+     * @brief Returns a reference to the underlying registry.
+     * @return A reference to the underlying registry.
+     */
+    [[nodiscard]] registry_type &registry() noexcept {
+        return *bucket;
+    }
+
+private:
+    registry_type *bucket;
+};
+
+/**
+ * @brief Signal connection helper for registries.
+ * @tparam Registry Basic registry type.
+ * @tparam Type Type of signal to connect listeners to.
+ */
+template<typename Registry, typename Type>
+struct sigh_helper<Registry, Type> final: sigh_helper<Registry> {
+    using sigh_helper<Registry>::sigh_helper;
+
+    /**
+     * @brief Forwards the call to `on_construct` on the underlying registry.
+     * @tparam Candidate Function or member to connect.
+     * @tparam Args Type of class or type of payload, if any.
+     * @param args A valid object that fits the purpose, if any.
+     * @return This helper.
+     */
+    template<auto Candidate, typename... Args>
+    auto on_construct(Args &&...args) {
+        this->registry().on_construct<Type>().connect<Candidate>(std::forward<Args>(args)...);
+        return *this;
+    }
+
+    /**
+     * @brief Forwards the call to `on_update` on the underlying registry.
+     * @tparam Candidate Function or member to connect.
+     * @tparam Args Type of class or type of payload, if any.
+     * @param args A valid object that fits the purpose, if any.
+     * @return This helper.
+     */
+    template<auto Candidate, typename... Args>
+    auto on_update(Args &&...args) {
+        this->registry().on_update<Type>().connect<Candidate>(std::forward<Args>(args)...);
+        return *this;
+    }
+
+    /**
+     * @brief Forwards the call to `on_destroy` on the underlying registry.
+     * @tparam Candidate Function or member to connect.
+     * @tparam Args Type of class or type of payload, if any.
+     * @param args A valid object that fits the purpose, if any.
+     * @return This helper.
+     */
+    template<auto Candidate, typename... Args>
+    auto on_destroy(Args &&...args) {
+        this->registry().on_destroy<Type>().connect<Candidate>(std::forward<Args>(args)...);
+        return *this;
+    }
+};
+
+/**
+ * @brief Deduction guide.
+ * @tparam Registry Basic registry type.
+ */
+template<typename Registry>
+sigh_helper(Registry &) -> sigh_helper<Registry>;
+
 } // namespace entt
 
 #endif

+ 26 - 0
test/entt/entity/helper.cpp

@@ -16,6 +16,10 @@ struct stable_type {
     int value;
 };
 
+void sigh_callback(int &value) {
+    ++value;
+}
+
 TEST(Helper, AsView) {
     entt::registry registry;
     const entt::registry cregistry;
@@ -124,3 +128,25 @@ TEST(Helper, ToEntityStableType) {
     ASSERT_EQ(entt::to_entity(registry, stable_type{42}), null);
     ASSERT_EQ(entt::to_entity(registry, value), null);
 }
+
+TEST(Helper, SighHelper) {
+    entt::registry registry{};
+    const auto entt = registry.create();
+    entt::sigh_helper helper{registry};
+    int counter{};
+
+    ASSERT_EQ(&helper.registry(), &registry);
+
+    helper.with<int>()
+        .on_construct<&sigh_callback>(counter)
+        .on_update<&sigh_callback>(counter)
+        .on_destroy<&sigh_callback>(counter);
+
+    ASSERT_EQ(counter, 0);
+
+    registry.emplace<int>(entt, 42);
+    registry.replace<int>(entt, 0);
+    registry.erase<int>(entt);
+
+    ASSERT_EQ(counter, 3);
+}