|
|
@@ -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).
|