1#ifndef ENTT_ENTITY_MIXIN_HPP
2#define ENTT_ENTITY_MIXIN_HPP
6#include "../config/config.h"
7#include "../core/any.hpp"
8#include "../signal/sigh.hpp"
28template<
typename Type,
typename Registry>
30 using underlying_type = Type;
31 using owner_type = Registry;
34 using sigh_type =
sigh<void(owner_type &,
const typename underlying_type::entity_type),
typename underlying_type::allocator_type>;
35 using underlying_iterator =
typename underlying_type::base_type::basic_iterator;
37 static_assert(std::is_base_of_v<basic_registry_type, owner_type>,
"Invalid registry type");
39 owner_type &owner_or_assert()
const noexcept {
40 ENTT_ASSERT(owner !=
nullptr,
"Invalid pointer to registry");
41 return static_cast<owner_type &
>(*owner);
44 void pop(underlying_iterator first, underlying_iterator last)
final {
45 if(
auto ® = owner_or_assert(); destruction.empty()) {
46 underlying_type::pop(first, last);
48 for(; first != last; ++first) {
49 const auto entt = *first;
50 destruction.publish(reg,
entt);
51 const auto it = underlying_type::find(
entt);
52 underlying_type::pop(it, it + 1u);
57 void pop_all()
final {
58 if(
auto ® = owner_or_assert(); !destruction.empty()) {
59 for(
auto it = underlying_type::base_type::begin(0), last = underlying_type::base_type::end(0); it != last; ++it) {
60 if constexpr(std::is_same_v<typename underlying_type::value_type, typename underlying_type::entity_type>) {
61 destruction.publish(reg, *it);
63 if constexpr(underlying_type::traits_type::in_place_delete) {
65 destruction.publish(reg,
entt);
68 destruction.publish(reg, *it);
74 underlying_type::pop_all();
77 underlying_iterator try_emplace(
const typename underlying_type::entity_type
entt,
const bool force_back,
const void *value)
final {
78 const auto it = underlying_type::try_emplace(
entt, force_back, value);
80 if(
auto ® = owner_or_assert(); it != underlying_type::base_type::end()) {
81 construction.publish(reg, *it);
104 : underlying_type{allocator},
106 construction{allocator},
107 destruction{allocator},
115 : underlying_type{std::move(other)},
117 construction{std::move(other.construction)},
118 destruction{std::move(other.destruction)},
119 update{std::move(other.update)} {}
127 : underlying_type{std::move(other), allocator},
129 construction{std::move(other.construction), allocator},
130 destruction{std::move(other.destruction), allocator},
131 update{std::move(other.update), allocator} {}
139 underlying_type::operator=(std::move(other));
141 construction = std::move(other.construction);
142 destruction = std::move(other.destruction);
143 update = std::move(other.update);
153 underlying_type::swap(other);
154 swap(owner, other.owner);
155 swap(construction, other.construction);
156 swap(destruction, other.destruction);
157 swap(update, other.update);
172 return sink{construction};
202 return sink{destruction};
215 const auto entt = underlying_type::emplace();
216 construction.publish(owner_or_assert(),
entt);
232 template<
typename... Args>
234 if constexpr(std::is_same_v<typename underlying_type::value_type, typename underlying_type::entity_type>) {
235 const auto entt = underlying_type::emplace(hint, std::forward<Args>(args)...);
236 construction.publish(owner_or_assert(),
entt);
239 underlying_type::emplace(hint, std::forward<Args>(args)...);
240 construction.publish(owner_or_assert(), hint);
241 return this->
get(hint);
252 template<
typename... Func>
254 underlying_type::patch(
entt, std::forward<Func>(func)...);
255 update.publish(owner_or_assert(),
entt);
256 return this->
get(entt);
272 template<
typename It,
typename... Args>
273 void insert(It first, It last, Args &&...args) {
274 underlying_type::insert(first, last, std::forward<Args>(args)...);
276 if(
auto ® = owner_or_assert(); !construction.empty()) {
277 for(; first != last; ++first) {
278 construction.publish(reg, *first);
288 auto *reg = any_cast<basic_registry_type>(&value);
289 owner = reg ? reg : owner;
290 underlying_type::bind(std::move(value));
294 basic_registry_type *owner;
295 sigh_type construction;
296 sigh_type destruction;
Fast and reliable entity-component system.
Mixin type used to add signal support to storage types.
auto on_update() noexcept
Returns a sink object.
typename underlying_type::entity_type entity_type
Underlying entity identifier.
auto on_construct() noexcept
Returns a sink object.
decltype(auto) patch(const entity_type entt, Func &&...func)
Patches the given instance for an entity.
auto emplace()
Emplace elements into a storage.
basic_sigh_mixin(basic_sigh_mixin &&other, const allocator_type &allocator) noexcept
Allocator-extended move constructor.
typename underlying_type::allocator_type allocator_type
Allocator type.
basic_sigh_mixin & operator=(basic_sigh_mixin &&other) noexcept
Move assignment operator.
basic_sigh_mixin(const allocator_type &allocator)
Constructs an empty storage with a given allocator.
owner_type registry_type
Expected registry type.
decltype(auto) emplace(const entity_type hint, Args &&...args)
Emplace elements into a storage.
basic_sigh_mixin()
Default constructor.
void swap(basic_sigh_mixin &other)
Exchanges the contents with those of a given storage.
basic_sigh_mixin(basic_sigh_mixin &&other) noexcept
Move constructor.
void insert(It first, It last, Args &&...args)
Emplace elements into a storage.
auto on_destroy() noexcept
Returns a sink object.
void bind(any value) noexcept final
Forwards variables to derived classes, if any.
constexpr tombstone_t tombstone
Compile-time constant for tombstone entities.
constexpr get_t< Type... > get
Variable template for lists of observed components.