diff --git a/docs/md/entity.md b/docs/md/entity.md index 5f91c3a29..09e4dbd58 100644 --- a/docs/md/entity.md +++ b/docs/md/entity.md @@ -324,32 +324,33 @@ the component owned by an entity if any, a null pointer otherwise. ## Observe changes -Because of how the registry works internally, it stores a couple of signal +Because of how the registry works internally, it stores a bunch of signal handlers for each pool in order to notify some of its data structures on the -construction and destruction of components.
+construction and destruction of components or when an instance of a component is +explicitly replaced by the user.
These signal handlers are also exposed and made available to users. These are the basic bricks to build fancy things like dependencies and reactive systems. To get a sink to be used to connect and disconnect listeners so as to be -notified on the creation of a component, use the `construction` member function: +notified on the creation of a component, use the `on_construct` member function: ```cpp // connects a free function -registry.construction().connect<&my_free_function>(); +registry.on_construct().connect<&my_free_function>(); // connects a member function -registry.construction().connect<&my_class::member>(&instance); +registry.on_construct().connect<&my_class::member>(&instance); // disconnects a free function -registry.construction().disconnect<&my_free_function>(); +registry.on_construct().disconnect<&my_free_function>(); // disconnects a member function -registry.construction().disconnect<&my_class::member>(&instance); +registry.on_construct().disconnect<&my_class::member>(&instance); ``` -To be notified when components are destroyed, use the `destruction` member -function instead. Finally, the `update` member function will return a sink to -which to connect listeners to observe changes on components. +To be notified when components are destroyed, use the `on_destroy` member +function instead. Finally, the `on_replace` member function will return a sink +to which to connect listeners to observe changes on components. The function type of a listener for the construction signal should be equivalent to the following: @@ -362,9 +363,9 @@ Where `Component` is intuitively the type of component of interest. In other words, a listener is provided with the registry that triggered the notification and the entity affected by the change, in addition to the newly created instance.
-The function type of a listener to be notified about changes is the same of that -of the construction signal. The one the destruction signal is also similar, -except for the `Component` parameter: +The sink returned by the `on_replace` member function accepts listeners the +signature of which is the same of that of the construction signal. The one of +the destruction signal is also similar, except for the `Component` parameter: ```cpp void(registry &, entt::entity); @@ -817,7 +818,7 @@ The following adds components `a_type` and `another_type` whenever `my_type` is assigned to an entity: ```cpp -entt::connnect(registry.construction()); +entt::connnect(registry.on_construct()); ``` A component is assigned to an entity and thus default initialized only in case @@ -826,7 +827,7 @@ be overriden.
A dependency can easily be broken by means of the following function template: ```cpp -entt::disconnect(registry.construction()); +entt::disconnect(registry.on_construct()); ``` ### Tags diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index 8be6b657c..ccaad14e9 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -67,7 +67,7 @@ class basic_registry { template Component & construct(const Entity entt, Args &&... args) { auto &component = sparse_set::construct(entt, std::forward(args)...); - construction.publish(*owner, entt, component); + on_construct.publish(*owner, entt, component); return component; } @@ -75,9 +75,9 @@ class basic_registry { Component * batch(It first, It last) { auto *component = sparse_set::batch(first, last); - if(!construction.empty()) { + if(!on_construct.empty()) { std::for_each(first, last, [component, this](const auto entt) mutable { - construction.publish(*owner, entt, *(component++)); + on_construct.publish(*owner, entt, *(component++)); }); } @@ -85,22 +85,22 @@ class basic_registry { } void destroy(const Entity entt) override { - destruction.publish(*owner, entt); + on_destroy.publish(*owner, entt); sparse_set::destroy(entt); } template Component & replace(const Entity entt, Args &&... args) { Component component{std::forward(args)...}; - update.publish(*owner, entt, component); + on_replace.publish(*owner, entt, component); auto &other = sparse_set::get(entt); std::swap(other, component); return other; } - sigh construction; - sigh update; - sigh destruction; + sigh on_construct; + sigh on_replace; + sigh on_destroy; basic_registry *owner; }; @@ -316,11 +316,11 @@ class basic_registry { auto *curr = static_cast(gdata.data.get()); const auto cpools = std::make_tuple(assure()..., assure()...); - (std::get *>(cpools)->destruction.sink().template connect<&group_type::template destroy_if<>>(curr), ...); - (std::get *>(cpools)->construction.sink().template connect<&group_type::template maybe_valid_if>(curr), ...); + (std::get *>(cpools)->on_destroy.sink().template connect<&group_type::template destroy_if<>>(curr), ...); + (std::get *>(cpools)->on_construct.sink().template connect<&group_type::template maybe_valid_if>(curr), ...); - (std::get *>(cpools)->destruction.sink().template connect<&group_type::template maybe_valid_if>(curr), ...); - (std::get *>(cpools)->construction.sink().template connect<&group_type::template destroy_if>(curr), ...); + (std::get *>(cpools)->on_destroy.sink().template connect<&group_type::template maybe_valid_if>(curr), ...); + (std::get *>(cpools)->on_construct.sink().template connect<&group_type::template destroy_if>(curr), ...); for(const auto entity: view()) { if(!(has(entity) || ...)) { @@ -354,14 +354,14 @@ class basic_registry { auto *curr = static_cast(gdata.data.get()); const auto cpools = std::make_tuple(assure()..., assure()..., assure()...); - (std::get *>(cpools)->construction.sink().template connect<&group_type::template maybe_valid_if>(curr), ...); - (std::get *>(cpools)->destruction.sink().template connect<&group_type::template discard_if<>>(curr), ...); + (std::get *>(cpools)->on_construct.sink().template connect<&group_type::template maybe_valid_if>(curr), ...); + (std::get *>(cpools)->on_destroy.sink().template connect<&group_type::template discard_if<>>(curr), ...); - (std::get *>(cpools)->construction.sink().template connect<&group_type::template maybe_valid_if>(curr), ...); - (std::get *>(cpools)->destruction.sink().template connect<&group_type::template discard_if<>>(curr), ...); + (std::get *>(cpools)->on_construct.sink().template connect<&group_type::template maybe_valid_if>(curr), ...); + (std::get *>(cpools)->on_destroy.sink().template connect<&group_type::template discard_if<>>(curr), ...); - (std::get *>(cpools)->destruction.sink().template connect<&group_type::template maybe_valid_if>(curr), ...); - (std::get *>(cpools)->construction.sink().template connect<&group_type::template discard_if>(curr), ...); + (std::get *>(cpools)->on_destroy.sink().template connect<&group_type::template maybe_valid_if>(curr), ...); + (std::get *>(cpools)->on_construct.sink().template connect<&group_type::template discard_if>(curr), ...); const auto *cpool = std::min({ static_cast *>(std::get *>(cpools))... }, [](const auto *lhs, const auto *rhs) { return lhs->size() < rhs->size(); @@ -1047,8 +1047,8 @@ public: * @return A temporary sink object. */ template - auto construction() ENTT_NOEXCEPT { - return assure()->construction.sink(); + auto on_construct() ENTT_NOEXCEPT { + return assure()->on_construct.sink(); } /** @@ -1056,7 +1056,7 @@ public: * * A sink is an opaque object used to connect listeners to components.
* The sink returned by this function can be used to receive notifications - * whenever an instance of the given component is updated. + * whenever an instance of the given component is explicitly replaced. * * The function type for a listener is equivalent to: * @code{.cpp} @@ -1074,8 +1074,8 @@ public: * @return A temporary sink object. */ template - auto update() ENTT_NOEXCEPT { - return assure()->update.sink(); + auto on_replace() ENTT_NOEXCEPT { + return assure()->on_replace.sink(); } /** @@ -1102,8 +1102,8 @@ public: * @return A temporary sink object. */ template - auto destruction() ENTT_NOEXCEPT { - return assure()->destruction.sink(); + auto on_destroy() ENTT_NOEXCEPT { + return assure()->on_destroy.sink(); } /** @@ -1236,7 +1236,7 @@ public: */ template void reset() { - if(auto *cpool = assure(); cpool->destruction.empty()) { + if(auto *cpool = assure(); cpool->on_destroy.empty()) { // no group set, otherwise the signal wouldn't be empty cpool->reset(); } else { diff --git a/test/entt/entity/helper.cpp b/test/entt/entity/helper.cpp index 088e03ec6..a75b58640 100644 --- a/test/entt/entity/helper.cpp +++ b/test/entt/entity/helper.cpp @@ -25,7 +25,7 @@ TEST(Helper, AsGroup) { TEST(Helper, Dependency) { entt::registry registry; const auto entity = registry.create(); - entt::connect(registry.construction()); + entt::connect(registry.on_construct()); ASSERT_FALSE(registry.has(entity)); ASSERT_FALSE(registry.has(entity)); @@ -61,7 +61,7 @@ TEST(Helper, Dependency) { registry.remove(entity); registry.remove(entity); registry.remove(entity); - entt::disconnect(registry.construction()); + entt::disconnect(registry.on_construct()); registry.assign(entity); ASSERT_FALSE(registry.has(entity)); @@ -70,8 +70,8 @@ TEST(Helper, Dependency) { TEST(Dependency, MultipleListenersOnTheSameType) { entt::registry registry; - entt::connect(registry.construction()); - entt::connect(registry.construction()); + entt::connect(registry.on_construct()); + entt::connect(registry.on_construct()); const auto entity = registry.create(); registry.assign(entity); diff --git a/test/entt/entity/registry.cpp b/test/entt/entity/registry.cpp index e6ba514ce..22cb7e4e0 100644 --- a/test/entt/entity/registry.cpp +++ b/test/entt/entity/registry.cpp @@ -854,8 +854,8 @@ TEST(Registry, Signals) { entt::registry registry; listener listener; - registry.construction().connect<&listener::incr>(&listener); - registry.destruction().connect<&listener::decr>(&listener); + registry.on_construct().connect<&listener::incr>(&listener); + registry.on_destroy().connect<&listener::decr>(&listener); auto e0 = registry.create(); auto e1 = registry.create(); @@ -871,20 +871,20 @@ TEST(Registry, Signals) { ASSERT_EQ(listener.counter, 1); ASSERT_EQ(listener.last, e0); - registry.destruction().disconnect<&listener::decr>(&listener); + registry.on_destroy().disconnect<&listener::decr>(&listener); registry.remove(e1); ASSERT_EQ(listener.counter, 1); ASSERT_EQ(listener.last, e0); - registry.construction().disconnect<&listener::incr>(&listener); + registry.on_construct().disconnect<&listener::incr>(&listener); registry.assign(e1); ASSERT_EQ(listener.counter, 1); ASSERT_EQ(listener.last, e0); - registry.construction().connect<&listener::incr>(&listener); - registry.destruction().connect<&listener::decr>(&listener); + registry.on_construct().connect<&listener::incr>(&listener); + registry.on_destroy().connect<&listener::decr>(&listener); registry.assign(e0); registry.reset(e1); @@ -909,13 +909,13 @@ TEST(Registry, Signals) { ASSERT_EQ(listener.counter, 1); ASSERT_EQ(listener.last, e0); - registry.destruction().disconnect<&listener::decr>(&listener); + registry.on_destroy().disconnect<&listener::decr>(&listener); registry.assign_or_replace(e0); ASSERT_EQ(listener.counter, 1); ASSERT_EQ(listener.last, e0); - registry.update().connect<&listener::incr>(&listener); + registry.on_replace().connect<&listener::incr>(&listener); registry.assign_or_replace(e0); ASSERT_EQ(listener.counter, 2); @@ -1069,7 +1069,7 @@ TEST(Registry, CreateManyEntitiesWithComponentsAtOnceWithListener) { entt::entity entities[3]; listener listener; - registry.construction().connect<&listener::incr>(&listener); + registry.on_construct().connect<&listener::incr>(&listener); registry.create(std::begin(entities), std::end(entities)); ASSERT_EQ(listener.counter, 3); @@ -1246,8 +1246,8 @@ TEST(Registry, Clone) { ASSERT_NE(e1, entity); ASSERT_EQ(registry.entity(e1), registry.entity(entity)); - registry.construction().connect<&listener::incr>(&listener); - registry.destruction().connect<&listener::decr>(&listener); + registry.on_construct().connect<&listener::incr>(&listener); + registry.on_destroy().connect<&listener::decr>(&listener); registry.assign(entity, 'e'); registry.assign(e0, '0'); registry.remove(e0);