signal on replace
This commit is contained in:
@@ -348,7 +348,8 @@ registry.construction<position>().disconnect<&my_class::member>(&instance);
|
||||
```
|
||||
|
||||
To be notified when components are destroyed, use the `destruction` member
|
||||
function instead.
|
||||
function instead. Finally, the `update` 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:
|
||||
@@ -361,8 +362,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.<br/>
|
||||
The function type of a listener for the destruction signal is the same, except
|
||||
for the `Component` parameter:
|
||||
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:
|
||||
|
||||
```cpp
|
||||
void(registry &, entt::entity);
|
||||
@@ -375,8 +377,13 @@ this case, the registry is made available for the purpose.
|
||||
|
||||
Note also that:
|
||||
|
||||
* Listeners are invoked **after** components have been assigned to entities.
|
||||
* Listeners are invoked **before** components have been removed from entities.
|
||||
* Listeners for the construction signal are invoked **after** components have
|
||||
been assigned to entities.
|
||||
* Listeners designed to observe changes are invoked **before** components have
|
||||
been replaced and therefore before newly created instances have been assigned
|
||||
to entities.
|
||||
* Listeners for the destruction signal are invoked **before** components have
|
||||
been removed from entities.
|
||||
* The order of invocation of the listeners isn't guaranteed in any case.
|
||||
|
||||
There are also some limitations on what a listener can and cannot do. In
|
||||
|
||||
@@ -91,14 +91,15 @@ class basic_registry {
|
||||
|
||||
template<typename... Args>
|
||||
Component & replace(const Entity entt, Args &&... args) {
|
||||
destruction.publish(*owner, entt);
|
||||
auto &component = sparse_set<Entity, Component>::get(entt);
|
||||
component = Component{std::forward<Args>(args)...};
|
||||
construction.publish(*owner, entt, component);
|
||||
return component;
|
||||
Component component{std::forward<Args>(args)...};
|
||||
update.publish(*owner, entt, component);
|
||||
auto &other = sparse_set<Entity, Component>::get(entt);
|
||||
std::swap(other, component);
|
||||
return other;
|
||||
}
|
||||
|
||||
sigh<void(basic_registry &, const Entity, Component &)> construction;
|
||||
sigh<void(basic_registry &, const Entity, Component &)> update;
|
||||
sigh<void(basic_registry &, const Entity)> destruction;
|
||||
basic_registry *owner;
|
||||
};
|
||||
@@ -394,12 +395,6 @@ public:
|
||||
using size_type = typename sparse_set<Entity>::size_type;
|
||||
/*! @brief Unsigned integer type. */
|
||||
using component_type = ENTT_ID_TYPE;
|
||||
/*! @brief Destruction sink type. */
|
||||
using destruction_sink_type = typename sigh<void(basic_registry &, const Entity)>::sink_type;
|
||||
|
||||
/*! @brief Construction sink type for the given component. */
|
||||
template<typename Component>
|
||||
using construction_sink_type = typename sigh<void(basic_registry &, const Entity, Component &)>::sink_type;
|
||||
|
||||
/*! @brief Default constructor. */
|
||||
basic_registry() ENTT_NOEXCEPT = default;
|
||||
@@ -1052,10 +1047,37 @@ public:
|
||||
* @return A temporary sink object.
|
||||
*/
|
||||
template<typename Component>
|
||||
construction_sink_type<Component> construction() ENTT_NOEXCEPT {
|
||||
auto construction() ENTT_NOEXCEPT {
|
||||
return assure<Component>()->construction.sink();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a sink object for the given component.
|
||||
*
|
||||
* A sink is an opaque object used to connect listeners to components.<br/>
|
||||
* The sink returned by this function can be used to receive notifications
|
||||
* whenever an instance of the given component is updated.
|
||||
*
|
||||
* The function type for a listener is equivalent to:
|
||||
* @code{.cpp}
|
||||
* void(registry<Entity> &, Entity, Component &);
|
||||
* @endcode
|
||||
*
|
||||
* Listeners are invoked **before** the component has been replaced. The
|
||||
* order of invocation of the listeners isn't guaranteed.<br/>
|
||||
* Note also that the greater the number of listeners, the greater the
|
||||
* performance hit when a new component is created.
|
||||
*
|
||||
* @sa sink
|
||||
*
|
||||
* @tparam Component Type of component of which to get the sink.
|
||||
* @return A temporary sink object.
|
||||
*/
|
||||
template<typename Component>
|
||||
auto update() ENTT_NOEXCEPT {
|
||||
return assure<Component>()->update.sink();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a sink object for the given component.
|
||||
*
|
||||
@@ -1080,7 +1102,7 @@ public:
|
||||
* @return A temporary sink object.
|
||||
*/
|
||||
template<typename Component>
|
||||
destruction_sink_type destruction() ENTT_NOEXCEPT {
|
||||
auto destruction() ENTT_NOEXCEPT {
|
||||
return assure<Component>()->destruction.sink();
|
||||
}
|
||||
|
||||
|
||||
@@ -912,19 +912,18 @@ TEST(Registry, Signals) {
|
||||
registry.destruction<int>().disconnect<&listener::decr<int>>(&listener);
|
||||
registry.assign_or_replace<int>(e0);
|
||||
|
||||
ASSERT_EQ(listener.counter, 2);
|
||||
ASSERT_EQ(listener.counter, 1);
|
||||
ASSERT_EQ(listener.last, e0);
|
||||
|
||||
registry.construction<int>().disconnect<&listener::incr<int>>(&listener);
|
||||
registry.destruction<int>().connect<&listener::decr<int>>(&listener);
|
||||
registry.update<int>().connect<&listener::incr<int>>(&listener);
|
||||
registry.assign_or_replace<int>(e0);
|
||||
|
||||
ASSERT_EQ(listener.counter, 1);
|
||||
ASSERT_EQ(listener.counter, 2);
|
||||
ASSERT_EQ(listener.last, e0);
|
||||
|
||||
registry.replace<int>(e0);
|
||||
|
||||
ASSERT_EQ(listener.counter, 0);
|
||||
ASSERT_EQ(listener.counter, 3);
|
||||
ASSERT_EQ(listener.last, e0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user