registry: callbacks receive the registry as first argument (better dependencies)
This commit is contained in:
1
TODO
1
TODO
@@ -19,6 +19,7 @@
|
||||
* any-of rule for views/groups (eg entity has A and any of B/C/D)
|
||||
- get -> all, exclude -> none
|
||||
* deprecate sigh::publish, use operator()
|
||||
* merge entity/helper and entt/utility
|
||||
|
||||
* WIP: snapshot rework/deprecation
|
||||
- remove snapshot/loader from registry, make them external (faster) tools
|
||||
|
||||
@@ -333,7 +333,7 @@ The function type of a listener for the construction and destruction signals
|
||||
should be equivalent to the following:
|
||||
|
||||
```cpp
|
||||
void(entt::entity, entt::registry &);
|
||||
void(entt::registry &, entt::entity);
|
||||
```
|
||||
|
||||
In both cases, listeners are provided with the registry that triggered the
|
||||
@@ -342,7 +342,7 @@ The function type of a listener that observes changes to components is slightly
|
||||
different instead:
|
||||
|
||||
```cpp
|
||||
void(entt::entity, entt::registry &, Component &);
|
||||
void(entt::registry &, entt::entity, Component &);
|
||||
```
|
||||
|
||||
In this case, `Component` is intuitively the type of component of interest. The
|
||||
@@ -600,26 +600,27 @@ the other things.
|
||||
|
||||
### Dependencies
|
||||
|
||||
The `registry` class is designed to create short circuits between its functions.
|
||||
This makes easy to define dependencies between different operations.<br/>
|
||||
The `registry` class is designed to be able to create short circuits between its
|
||||
functions. This simplifies the definition of _dependencies_ between different
|
||||
operations.<br/>
|
||||
For example, the following adds (or replaces) the component `a_type` whenever
|
||||
`my_type` is assigned to an entity:
|
||||
|
||||
```cpp
|
||||
registry.on_construct<my_type>().connect<&entt::registry::assign_or_replace<a_type>>(registry);
|
||||
registry.on_construct<my_type>().connect<&entt::registry::assign_or_replace<a_type>>();
|
||||
```
|
||||
|
||||
Similarly, the code shown below removes `a_type` from an entity whenever
|
||||
`my_type` is assigned to it:
|
||||
|
||||
```cpp
|
||||
registry.on_construct<my_type>().connect<&entt::registry::remove<a_type>>(registry);
|
||||
registry.on_construct<my_type>().connect<&entt::registry::remove<a_type>>();
|
||||
```
|
||||
|
||||
A dependency can also be easily broken as follows:
|
||||
|
||||
```cpp
|
||||
registry.on_construct<my_type>().disconnect<&entt::registry::assign_or_replace<a_type>>(registry);
|
||||
registry.on_construct<my_type>().disconnect<&entt::registry::assign_or_replace<a_type>>();
|
||||
```
|
||||
|
||||
There are many other types of dependencies. In general, all functions that
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include <type_traits>
|
||||
#include "../config/config.h"
|
||||
#include "../signal/sigh.hpp"
|
||||
#include "registry.hpp"
|
||||
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ class basic_observer {
|
||||
template<typename... Reject, typename... Require, typename AnyOf>
|
||||
struct matcher_handler<matcher<type_list<Reject...>, type_list<Require...>, AnyOf>> {
|
||||
template<std::size_t Index>
|
||||
static void maybe_valid_if(basic_observer &obs, const Entity entt, const basic_registry<Entity> ®) {
|
||||
static void maybe_valid_if(basic_observer &obs, const basic_registry<Entity> ®, const Entity entt) {
|
||||
if(reg.template has<Require...>(entt) && !(reg.template has<Reject>(entt) || ...)) {
|
||||
if(auto *comp = obs.view.try_get(entt); !comp) {
|
||||
obs.view.construct(entt);
|
||||
@@ -188,7 +188,7 @@ class basic_observer {
|
||||
}
|
||||
|
||||
template<std::size_t Index>
|
||||
static void discard_if(basic_observer &obs, const Entity entt) {
|
||||
static void discard_if(basic_observer &obs, const basic_registry<Entity> &, const Entity entt) {
|
||||
if(auto *value = obs.view.try_get(entt); value && !(*value &= (~(1 << Index)))) {
|
||||
obs.view.destroy(entt);
|
||||
}
|
||||
@@ -213,7 +213,7 @@ class basic_observer {
|
||||
template<typename... Reject, typename... Require, typename... NoneOf, typename... AllOf>
|
||||
struct matcher_handler<matcher<type_list<Reject...>, type_list<Require...>, type_list<NoneOf...>, AllOf...>> {
|
||||
template<std::size_t Index>
|
||||
static void maybe_valid_if(basic_observer &obs, const Entity entt, const basic_registry<Entity> ®) {
|
||||
static void maybe_valid_if(basic_observer &obs, const basic_registry<Entity> ®, const Entity entt) {
|
||||
if(reg.template has<AllOf..., Require...>(entt) && !(reg.template has<NoneOf>(entt) || ...) && !(reg.template has<Reject>(entt) || ...)) {
|
||||
if(auto *comp = obs.view.try_get(entt); !comp) {
|
||||
obs.view.construct(entt);
|
||||
@@ -224,7 +224,7 @@ class basic_observer {
|
||||
}
|
||||
|
||||
template<std::size_t Index>
|
||||
static void discard_if(basic_observer &obs, const Entity entt) {
|
||||
static void discard_if(basic_observer &obs, const basic_registry<Entity> &, const Entity entt) {
|
||||
if(auto *value = obs.view.try_get(entt); value && !(*value &= (~(1 << Index)))) {
|
||||
obs.view.destroy(entt);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ class basic_registry {
|
||||
template<typename... Args>
|
||||
decltype(auto) assign(basic_registry &owner, const Entity entt, Args &&... args) {
|
||||
this->construct(entt, std::forward<Args>(args)...);
|
||||
construction.publish(entt, owner);
|
||||
construction.publish(owner, entt);
|
||||
return this->get(entt);
|
||||
}
|
||||
|
||||
@@ -80,12 +80,12 @@ class basic_registry {
|
||||
(func(this->raw() + this->size() - std::distance(first, last)), ...);
|
||||
|
||||
if(!construction.empty()) {
|
||||
std::for_each(first, last, [this, &owner](const auto entt) { construction.publish(entt, owner); });
|
||||
std::for_each(first, last, [this, &owner](const auto entt) { construction.publish(owner, entt); });
|
||||
}
|
||||
}
|
||||
|
||||
void remove(basic_registry &owner, const Entity entt) {
|
||||
destruction.publish(entt, owner);
|
||||
destruction.publish(owner, entt);
|
||||
this->destroy(entt);
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ class basic_registry {
|
||||
void remove(basic_registry &owner, It first, It last) {
|
||||
if(std::distance(first, last) == std::distance(this->begin(), this->end())) {
|
||||
if(!destruction.empty()) {
|
||||
std::for_each(first, last, [this, &owner](const auto entt) { destruction.publish(entt, owner); });
|
||||
std::for_each(first, last, [this, &owner](const auto entt) { destruction.publish(owner, entt); });
|
||||
}
|
||||
|
||||
this->clear();
|
||||
@@ -106,14 +106,14 @@ class basic_registry {
|
||||
template<typename... Args>
|
||||
decltype(auto) replace(basic_registry &owner, const Entity entt, Args &&... args) {
|
||||
Component component{std::forward<Args>(args)...};
|
||||
update.publish(entt, owner, component);
|
||||
update.publish(owner, entt, component);
|
||||
return (this->get(entt) = std::move(component));
|
||||
}
|
||||
|
||||
private:
|
||||
sigh<void(const Entity, basic_registry &)> construction{};
|
||||
sigh<void(const Entity, basic_registry &)> destruction{};
|
||||
sigh<void(const Entity, basic_registry &, decltype(std::declval<storage<Entity, Component>>().get({})))> update{};
|
||||
sigh<void(basic_registry &, const Entity)> construction{};
|
||||
sigh<void(basic_registry &, const Entity)> destruction{};
|
||||
sigh<void(basic_registry &, const Entity, decltype(std::declval<storage<Entity, Component>>().get({})))> update{};
|
||||
};
|
||||
|
||||
struct pool_data {
|
||||
@@ -133,7 +133,7 @@ class basic_registry {
|
||||
std::conditional_t<sizeof...(Owned) == 0, sparse_set<Entity>, std::size_t> current{};
|
||||
|
||||
template<typename Component>
|
||||
void maybe_valid_if(const Entity entt, basic_registry &owner) {
|
||||
void maybe_valid_if(basic_registry &owner, const Entity entt) {
|
||||
static_assert(std::disjunction_v<std::is_same<Owned, std::decay_t<Owned>>..., std::is_same<Get, std::decay_t<Get>>..., std::is_same<Exclude, std::decay_t<Exclude>>...>);
|
||||
[[maybe_unused]] const auto cpools = std::forward_as_tuple(owner.assure<Owned>()...);
|
||||
|
||||
@@ -153,7 +153,7 @@ class basic_registry {
|
||||
}
|
||||
}
|
||||
|
||||
void discard_if(const Entity entt, basic_registry &owner) {
|
||||
void discard_if([[maybe_unused]] basic_registry &owner, const Entity entt) {
|
||||
if constexpr(sizeof...(Owned) == 0) {
|
||||
if(current.has(entt)) {
|
||||
current.destroy(entt);
|
||||
@@ -1021,7 +1021,7 @@ public:
|
||||
* The function type for a listener is equivalent to:
|
||||
*
|
||||
* @code{.cpp}
|
||||
* void(Entity, registry<Entity> &);
|
||||
* void(registry<Entity> &, Entity);
|
||||
* @endcode
|
||||
*
|
||||
* Listeners are invoked **after** the component has been assigned to the
|
||||
@@ -1052,7 +1052,7 @@ public:
|
||||
* The function type for a listener is equivalent to:
|
||||
*
|
||||
* @code{.cpp}
|
||||
* void(Entity, registry<Entity> &, Component &);
|
||||
* void(registry<Entity> &, Entity, Component &);
|
||||
* @endcode
|
||||
*
|
||||
* Listeners are invoked **before** the component has been replaced.
|
||||
@@ -1083,7 +1083,7 @@ public:
|
||||
* The function type for a listener is equivalent to:
|
||||
*
|
||||
* @code{.cpp}
|
||||
* void(Entity, registry<Entity> &);
|
||||
* void(registry<Entity> &, Entity);
|
||||
* @endcode
|
||||
*
|
||||
* Listeners are invoked **before** the component has been removed from the
|
||||
|
||||
@@ -492,7 +492,7 @@ TEST(NonOwningGroup, Less) {
|
||||
|
||||
TEST(NonOwningGroup, SignalRace) {
|
||||
entt::registry registry;
|
||||
registry.on_construct<double>().connect<&entt::registry::assign_or_replace<int>>(registry);
|
||||
registry.on_construct<double>().connect<&entt::registry::assign_or_replace<int>>();
|
||||
registry.group(entt::get<int, double>);
|
||||
|
||||
auto entity = registry.create();
|
||||
@@ -1068,7 +1068,7 @@ TEST(OwningGroup, Less) {
|
||||
|
||||
TEST(OwningGroup, SignalRace) {
|
||||
entt::registry registry;
|
||||
registry.on_construct<double>().connect<&entt::registry::assign_or_replace<int>>(registry);
|
||||
registry.on_construct<double>().connect<&entt::registry::assign_or_replace<int>>();
|
||||
registry.group<int>(entt::get<double>);
|
||||
|
||||
auto entity = registry.create();
|
||||
|
||||
@@ -14,12 +14,12 @@ struct empty_type {};
|
||||
|
||||
struct listener {
|
||||
template<typename Component>
|
||||
static void sort(entt::entity, entt::registry ®istry) {
|
||||
static void sort(entt::registry ®istry) {
|
||||
registry.sort<Component>([](auto lhs, auto rhs) { return lhs < rhs; });
|
||||
}
|
||||
|
||||
template<typename Component>
|
||||
void incr(entt::entity entity, entt::registry ®istry) {
|
||||
void incr(const entt::registry ®istry, entt::entity entity) {
|
||||
ASSERT_TRUE(registry.valid(entity));
|
||||
ASSERT_TRUE(registry.has<Component>(entity));
|
||||
last = entity;
|
||||
@@ -27,7 +27,7 @@ struct listener {
|
||||
}
|
||||
|
||||
template<typename Component>
|
||||
void decr(entt::entity entity, entt::registry ®istry) {
|
||||
void decr(const entt::registry ®istry, entt::entity entity) {
|
||||
ASSERT_TRUE(registry.valid(entity));
|
||||
ASSERT_TRUE(registry.has<Component>(entity));
|
||||
last = entity;
|
||||
@@ -1562,8 +1562,8 @@ TEST(Registry, Dependencies) {
|
||||
constexpr auto assign_or_replace = &entt::registry::assign_or_replace<double>;
|
||||
constexpr auto remove = &entt::registry::remove<double>;
|
||||
|
||||
registry.on_construct<int>().connect<assign_or_replace>(registry);
|
||||
registry.on_destroy<int>().connect<remove>(registry);
|
||||
registry.on_construct<int>().connect<assign_or_replace>();
|
||||
registry.on_destroy<int>().connect<remove>();
|
||||
registry.assign<double>(entity, .3);
|
||||
|
||||
ASSERT_FALSE(registry.has<int>(entity));
|
||||
@@ -1579,8 +1579,8 @@ TEST(Registry, Dependencies) {
|
||||
ASSERT_FALSE(registry.has<int>(entity));
|
||||
ASSERT_FALSE(registry.has<double>(entity));
|
||||
|
||||
registry.on_construct<int>().disconnect<assign_or_replace>(registry);
|
||||
registry.on_destroy<int>().disconnect<remove>(registry);
|
||||
registry.on_construct<int>().disconnect<assign_or_replace>();
|
||||
registry.on_destroy<int>().disconnect<remove>();
|
||||
registry.assign<int>(entity);
|
||||
|
||||
ASSERT_TRUE(registry.has<int>(entity));
|
||||
|
||||
Reference in New Issue
Block a user