浏览代码

storage: split sigh_storage_mixin

Michele Caini 4 年之前
父节点
当前提交
1a62338349
共有 4 个文件被更改,包括 180 次插入167 次删除
  1. 1 0
      CMakeLists.txt
  2. 177 0
      src/entt/entity/sigh_storage_mixin.hpp
  3. 1 167
      src/entt/entity/storage.hpp
  4. 1 0
      src/entt/entt.hpp

+ 1 - 0
CMakeLists.txt

@@ -142,6 +142,7 @@ if(ENTT_INCLUDE_HEADERS)
             $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/organizer.hpp>
             $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/registry.hpp>
             $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/runtime_view.hpp>
+            $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/sigh_storage_mixin.hpp>
             $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/snapshot.hpp>
             $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/sparse_set.hpp>
             $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/storage.hpp>

+ 177 - 0
src/entt/entity/sigh_storage_mixin.hpp

@@ -0,0 +1,177 @@
+#ifndef ENTT_ENTITY_SIGH_STORAGE_MIXIN_HPP
+#define ENTT_ENTITY_SIGH_STORAGE_MIXIN_HPP
+
+#include <utility>
+#include "../config/config.h"
+#include "../core/any.hpp"
+#include "../signal/sigh.hpp"
+#include "fwd.hpp"
+
+namespace entt {
+
+/**
+ * @brief Mixin type used to add signal support to storage types.
+ *
+ * The function type of a listener is equivalent to:
+ *
+ * @code{.cpp}
+ * void(basic_registry<entity_type> &, entity_type);
+ * @endcode
+ *
+ * This applies to all signals made available.
+ *
+ * @tparam Type The type of the underlying storage.
+ */
+template<typename Type>
+class sigh_storage_mixin final: public Type {
+    template<typename Func>
+    void notify_destruction(typename Type::basic_iterator first, typename Type::basic_iterator last, Func func) {
+        ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
+
+        for(; first != last; ++first) {
+            const auto entt = *first;
+            destruction.publish(*owner, entt);
+            const auto it = Type::find(entt);
+            func(it, it + 1u);
+        }
+    }
+
+    void swap_and_pop(typename Type::basic_iterator first, typename Type::basic_iterator last) final {
+        notify_destruction(std::move(first), std::move(last), [this](auto... args) { Type::swap_and_pop(args...); });
+    }
+
+    void in_place_pop(typename Type::basic_iterator first, typename Type::basic_iterator last) final {
+        notify_destruction(std::move(first), std::move(last), [this](auto... args) { Type::in_place_pop(args...); });
+    }
+
+    typename Type::basic_iterator try_emplace(const typename Type::entity_type entt, const bool force_back, const void *value) final {
+        ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
+        Type::try_emplace(entt, force_back, value);
+        construction.publish(*owner, entt);
+        return Type::find(entt);
+    }
+
+public:
+    /*! @brief Underlying value type. */
+    using value_type = typename Type::value_type;
+    /*! @brief Underlying entity identifier. */
+    using entity_type = typename Type::entity_type;
+
+    /*! @brief Inherited constructors. */
+    using Type::Type;
+
+    /**
+     * @brief Returns a sink object.
+     *
+     * The sink returned by this function can be used to receive notifications
+     * whenever a new instance is created and assigned to an entity.<br/>
+     * Listeners are invoked after the object has been assigned to the entity.
+     *
+     * @sa sink
+     *
+     * @return A temporary sink object.
+     */
+    [[nodiscard]] auto on_construct() ENTT_NOEXCEPT {
+        return sink{construction};
+    }
+
+    /**
+     * @brief Returns a sink object.
+     *
+     * The sink returned by this function can be used to receive notifications
+     * whenever an instance is explicitly updated.<br/>
+     * Listeners are invoked after the object has been updated.
+     *
+     * @sa sink
+     *
+     * @return A temporary sink object.
+     */
+    [[nodiscard]] auto on_update() ENTT_NOEXCEPT {
+        return sink{update};
+    }
+
+    /**
+     * @brief Returns a sink object.
+     *
+     * The sink returned by this function can be used to receive notifications
+     * whenever an instance is removed from an entity and thus destroyed.<br/>
+     * Listeners are invoked before the object has been removed from the entity.
+     *
+     * @sa sink
+     *
+     * @return A temporary sink object.
+     */
+    [[nodiscard]] auto on_destroy() ENTT_NOEXCEPT {
+        return sink{destruction};
+    }
+
+    /**
+     * @brief Assigns entities to a storage.
+     * @tparam Args Types of arguments to use to construct the object.
+     * @param entt A valid identifier.
+     * @param args Parameters to use to initialize the object.
+     * @return A reference to the newly created object.
+     */
+    template<typename... Args>
+    decltype(auto) emplace(const entity_type entt, Args &&...args) {
+        ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
+        Type::emplace(entt, std::forward<Args>(args)...);
+        construction.publish(*owner, entt);
+        return this->get(entt);
+    }
+
+    /**
+     * @brief Patches the given instance for an entity.
+     * @tparam Func Types of the function objects to invoke.
+     * @param entt A valid identifier.
+     * @param func Valid function objects.
+     * @return A reference to the patched instance.
+     */
+    template<typename... Func>
+    decltype(auto) patch(const entity_type entt, Func &&...func) {
+        ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
+        Type::patch(entt, std::forward<Func>(func)...);
+        update.publish(*owner, entt);
+        return this->get(entt);
+    }
+
+    /**
+     * @brief Assigns entities to a storage.
+     * @tparam It Type of input iterator.
+     * @tparam Args Types of arguments to use to construct the objects assigned
+     * to the entities.
+     * @param first An iterator to the first element of the range of entities.
+     * @param last An iterator past the last element of the range of entities.
+     * @param args Parameters to use to initialize the objects assigned to the
+     * entities.
+     */
+    template<typename It, typename... Args>
+    void insert(It first, It last, Args &&...args) {
+        ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
+        Type::insert(first, last, std::forward<Args>(args)...);
+
+        for(auto it = construction.empty() ? last : first; it != last; ++it) {
+            construction.publish(*owner, *it);
+        }
+    }
+
+    /**
+     * @brief Forwards variables to mixins, if any.
+     * @param value A variable wrapped in an opaque container.
+     */
+    void bind(any value) ENTT_NOEXCEPT final {
+        auto *reg = any_cast<basic_registry<entity_type>>(&value);
+        owner = reg ? reg : owner;
+        Type::bind(std::move(value));
+    }
+
+private:
+    sigh<void(basic_registry<entity_type> &, const entity_type)> construction{};
+    sigh<void(basic_registry<entity_type> &, const entity_type)> destruction{};
+    sigh<void(basic_registry<entity_type> &, const entity_type)> update{};
+    basic_registry<entity_type> *owner{};
+};
+
+} // namespace entt
+
+#endif

+ 1 - 167
src/entt/entity/storage.hpp

@@ -9,17 +9,14 @@
 #include <utility>
 #include <vector>
 #include "../config/config.h"
-#include "../core/algorithm.hpp"
-#include "../core/any.hpp"
 #include "../core/compressed_pair.hpp"
 #include "../core/iterator.hpp"
 #include "../core/memory.hpp"
 #include "../core/type_info.hpp"
-#include "../core/type_traits.hpp"
-#include "../signal/sigh.hpp"
 #include "component.hpp"
 #include "entity.hpp"
 #include "fwd.hpp"
+#include "sigh_storage_mixin.hpp"
 #include "sparse_set.hpp"
 
 namespace entt {
@@ -897,169 +894,6 @@ public:
     }
 };
 
-/**
- * @brief Mixin type used to add signal support to storage types.
- *
- * The function type of a listener is equivalent to:
- *
- * @code{.cpp}
- * void(basic_registry<entity_type> &, entity_type);
- * @endcode
- *
- * This applies to all signals made available.
- *
- * @tparam Type The type of the underlying storage.
- */
-template<typename Type>
-class sigh_storage_mixin final: public Type {
-    template<typename Func>
-    void notify_destruction(typename Type::basic_iterator first, typename Type::basic_iterator last, Func func) {
-        ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
-
-        for(; first != last; ++first) {
-            const auto entt = *first;
-            destruction.publish(*owner, entt);
-            const auto it = Type::find(entt);
-            func(it, it + 1u);
-        }
-    }
-
-    void swap_and_pop(typename Type::basic_iterator first, typename Type::basic_iterator last) final {
-        notify_destruction(std::move(first), std::move(last), [this](auto... args) { Type::swap_and_pop(args...); });
-    }
-
-    void in_place_pop(typename Type::basic_iterator first, typename Type::basic_iterator last) final {
-        notify_destruction(std::move(first), std::move(last), [this](auto... args) { Type::in_place_pop(args...); });
-    }
-
-    typename Type::basic_iterator try_emplace(const typename Type::entity_type entt, const bool force_back, const void *value) final {
-        ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
-        Type::try_emplace(entt, force_back, value);
-        construction.publish(*owner, entt);
-        return Type::find(entt);
-    }
-
-public:
-    /*! @brief Underlying value type. */
-    using value_type = typename Type::value_type;
-    /*! @brief Underlying entity identifier. */
-    using entity_type = typename Type::entity_type;
-
-    /*! @brief Inherited constructors. */
-    using Type::Type;
-
-    /**
-     * @brief Returns a sink object.
-     *
-     * The sink returned by this function can be used to receive notifications
-     * whenever a new instance is created and assigned to an entity.<br/>
-     * Listeners are invoked after the object has been assigned to the entity.
-     *
-     * @sa sink
-     *
-     * @return A temporary sink object.
-     */
-    [[nodiscard]] auto on_construct() ENTT_NOEXCEPT {
-        return sink{construction};
-    }
-
-    /**
-     * @brief Returns a sink object.
-     *
-     * The sink returned by this function can be used to receive notifications
-     * whenever an instance is explicitly updated.<br/>
-     * Listeners are invoked after the object has been updated.
-     *
-     * @sa sink
-     *
-     * @return A temporary sink object.
-     */
-    [[nodiscard]] auto on_update() ENTT_NOEXCEPT {
-        return sink{update};
-    }
-
-    /**
-     * @brief Returns a sink object.
-     *
-     * The sink returned by this function can be used to receive notifications
-     * whenever an instance is removed from an entity and thus destroyed.<br/>
-     * Listeners are invoked before the object has been removed from the entity.
-     *
-     * @sa sink
-     *
-     * @return A temporary sink object.
-     */
-    [[nodiscard]] auto on_destroy() ENTT_NOEXCEPT {
-        return sink{destruction};
-    }
-
-    /**
-     * @brief Assigns entities to a storage.
-     * @tparam Args Types of arguments to use to construct the object.
-     * @param entt A valid identifier.
-     * @param args Parameters to use to initialize the object.
-     * @return A reference to the newly created object.
-     */
-    template<typename... Args>
-    decltype(auto) emplace(const entity_type entt, Args &&...args) {
-        ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
-        Type::emplace(entt, std::forward<Args>(args)...);
-        construction.publish(*owner, entt);
-        return this->get(entt);
-    }
-
-    /**
-     * @brief Patches the given instance for an entity.
-     * @tparam Func Types of the function objects to invoke.
-     * @param entt A valid identifier.
-     * @param func Valid function objects.
-     * @return A reference to the patched instance.
-     */
-    template<typename... Func>
-    decltype(auto) patch(const entity_type entt, Func &&...func) {
-        ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
-        Type::patch(entt, std::forward<Func>(func)...);
-        update.publish(*owner, entt);
-        return this->get(entt);
-    }
-
-    /**
-     * @brief Assigns entities to a storage.
-     * @tparam It Type of input iterator.
-     * @tparam Args Types of arguments to use to construct the objects assigned
-     * to the entities.
-     * @param first An iterator to the first element of the range of entities.
-     * @param last An iterator past the last element of the range of entities.
-     * @param args Parameters to use to initialize the objects assigned to the
-     * entities.
-     */
-    template<typename It, typename... Args>
-    void insert(It first, It last, Args &&...args) {
-        ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
-        Type::insert(first, last, std::forward<Args>(args)...);
-
-        for(auto it = construction.empty() ? last : first; it != last; ++it) {
-            construction.publish(*owner, *it);
-        }
-    }
-
-    /**
-     * @brief Forwards variables to mixins, if any.
-     * @param value A variable wrapped in an opaque container.
-     */
-    void bind(any value) ENTT_NOEXCEPT final {
-        auto *reg = any_cast<basic_registry<entity_type>>(&value);
-        owner = reg ? reg : owner;
-        Type::bind(std::move(value));
-    }
-
-private:
-    sigh<void(basic_registry<entity_type> &, const entity_type)> construction{};
-    sigh<void(basic_registry<entity_type> &, const entity_type)> destruction{};
-    sigh<void(basic_registry<entity_type> &, const entity_type)> update{};
-    basic_registry<entity_type> *owner{};
-};
-
 /**
  * @brief Provides a common way to access certain properties of storage types.
  * @tparam Entity A valid entity type (see entt_traits for more details).

+ 1 - 0
src/entt/entt.hpp

@@ -27,6 +27,7 @@
 #include "entity/organizer.hpp"
 #include "entity/registry.hpp"
 #include "entity/runtime_view.hpp"
+#include "entity/sigh_storage_mixin.hpp"
 #include "entity/snapshot.hpp"
 #include "entity/sparse_set.hpp"
 #include "entity/storage.hpp"