registry: component signals return only the entity
This commit is contained in:
@@ -177,8 +177,8 @@ 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 basic_registry<Entity> ®, const Entity entt) {
|
||||
if(reg.template has<Require...>(entt) && !reg.template any<Reject...>(entt)) {
|
||||
static void maybe_valid_if(basic_observer &obs, const Entity entt) {
|
||||
if(obs.target->template has<Require...>(entt) && !obs.target->template any<Reject...>(entt)) {
|
||||
if(auto *comp = obs.view.try_get(entt); !comp) {
|
||||
obs.view.emplace(entt);
|
||||
}
|
||||
@@ -188,7 +188,7 @@ class basic_observer {
|
||||
}
|
||||
|
||||
template<std::size_t Index>
|
||||
static void discard_if(basic_observer &obs, const basic_registry<Entity> &, const Entity entt) {
|
||||
static void discard_if(basic_observer &obs, const Entity entt) {
|
||||
if(auto *value = obs.view.try_get(entt); value && !(*value &= (~(1 << Index)))) {
|
||||
obs.view.erase(entt);
|
||||
}
|
||||
@@ -213,12 +213,12 @@ 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, typename... Ignore>
|
||||
static void maybe_valid_if(basic_observer &obs, const basic_registry<Entity> ®, const Entity entt) {
|
||||
if([®, entt]() {
|
||||
static void maybe_valid_if(basic_observer &obs, const Entity entt) {
|
||||
if([&obs, entt]() {
|
||||
if constexpr(sizeof...(Ignore) == 0) {
|
||||
return reg.template has<AllOf..., Require...>(entt) && !reg.template any<NoneOf..., Reject...>(entt);
|
||||
return obs.target->template has<AllOf..., Require...>(entt) && !obs.target->template any<NoneOf..., Reject...>(entt);
|
||||
} else {
|
||||
return reg.template has<AllOf..., Require...>(entt) && ((std::is_same_v<Ignore..., NoneOf> || !reg.template any<NoneOf>(entt)) && ...) && !reg.template any<Reject...>(entt);
|
||||
return obs.target->template has<AllOf..., Require...>(entt) && ((std::is_same_v<Ignore..., NoneOf> || !obs.target->template any<NoneOf>(entt)) && ...) && !obs.target->template any<Reject...>(entt);
|
||||
}
|
||||
}())
|
||||
{
|
||||
@@ -231,7 +231,7 @@ class basic_observer {
|
||||
}
|
||||
|
||||
template<std::size_t Index>
|
||||
static void discard_if(basic_observer &obs, const basic_registry<Entity> &, const Entity entt) {
|
||||
static void discard_if(basic_observer &obs, const Entity entt) {
|
||||
if(auto *value = obs.view.try_get(entt); value && !(*value &= (~(1 << Index)))) {
|
||||
obs.view.erase(entt);
|
||||
}
|
||||
|
||||
@@ -60,9 +60,9 @@ class basic_registry {
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
decltype(auto) emplace(basic_registry &owner, const Entity entt, Args &&... args) {
|
||||
decltype(auto) emplace(const Entity entt, Args &&... args) {
|
||||
storage<entity_type, Component>::emplace(entt, std::forward<Args>(args)...);
|
||||
construction.publish(owner, entt);
|
||||
construction.publish(entt);
|
||||
|
||||
if constexpr(!is_eto_eligible_v<Component>) {
|
||||
return this->get(entt);
|
||||
@@ -70,57 +70,57 @@ class basic_registry {
|
||||
}
|
||||
|
||||
template<typename It, typename... Args>
|
||||
void insert(basic_registry &owner, It first, It last, Args &&... args) {
|
||||
void insert(It first, It last, Args &&... args) {
|
||||
storage<entity_type, Component>::insert(first, last, std::forward<Args>(args)...);
|
||||
|
||||
if(!construction.empty()) {
|
||||
while(first != last) { construction.publish(owner, *(first++)); }
|
||||
while(first != last) { construction.publish(*(first++)); }
|
||||
}
|
||||
}
|
||||
|
||||
void remove(basic_registry &owner, const Entity entt) {
|
||||
destruction.publish(owner, entt);
|
||||
void remove(const Entity entt) {
|
||||
destruction.publish(entt);
|
||||
this->erase(entt);
|
||||
}
|
||||
|
||||
template<typename It>
|
||||
void remove(basic_registry &owner, It first, It last) {
|
||||
void remove(It first, It last) {
|
||||
if(std::distance(first, last) == std::distance(this->begin(), this->end())) {
|
||||
if(!destruction.empty()) {
|
||||
while(first != last) { destruction.publish(owner, *(first++)); }
|
||||
while(first != last) { destruction.publish(*(first++)); }
|
||||
}
|
||||
|
||||
this->clear();
|
||||
} else {
|
||||
while(first != last) { this->remove(owner, *(first++)); }
|
||||
while(first != last) { this->remove(*(first++)); }
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Func>
|
||||
decltype(auto) patch(basic_registry &owner, const Entity entt, [[maybe_unused]] Func &&... func) {
|
||||
decltype(auto) patch(const Entity entt, [[maybe_unused]] Func &&... func) {
|
||||
if constexpr(is_eto_eligible_v<Component>) {
|
||||
update.publish(owner, entt);
|
||||
update.publish(entt);
|
||||
} else {
|
||||
(std::forward<Func>(func)(this->get(entt)), ...);
|
||||
update.publish(owner, entt);
|
||||
update.publish(entt);
|
||||
return this->get(entt);
|
||||
}
|
||||
}
|
||||
|
||||
decltype(auto) replace(basic_registry &owner, const Entity entt, Component component) {
|
||||
return patch(owner, entt, [&component](auto &&curr) { curr = std::move(component); });
|
||||
decltype(auto) replace(const Entity entt, Component component) {
|
||||
return patch(entt, [&component](auto &&curr) { curr = std::move(component); });
|
||||
}
|
||||
|
||||
private:
|
||||
sigh<void(basic_registry &, const Entity)> construction{};
|
||||
sigh<void(basic_registry &, const Entity)> destruction{};
|
||||
sigh<void(basic_registry &, const Entity)> update{};
|
||||
sigh<void(const Entity)> construction{};
|
||||
sigh<void(const Entity)> destruction{};
|
||||
sigh<void(const Entity)> update{};
|
||||
};
|
||||
|
||||
struct pool_data {
|
||||
id_type type_id{};
|
||||
std::unique_ptr<sparse_set<Entity>> pool{};
|
||||
void(* remove)(sparse_set<Entity> &, basic_registry &, const Entity){};
|
||||
void(* remove)(sparse_set<Entity> &, const Entity){};
|
||||
};
|
||||
|
||||
template<typename...>
|
||||
@@ -130,14 +130,19 @@ class basic_registry {
|
||||
struct group_handler<exclude_t<Exclude...>, get_t<Get...>, Owned...> {
|
||||
static_assert(std::conjunction_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>>...>, "One or more component types are invalid");
|
||||
std::conditional_t<sizeof...(Owned) == 0, sparse_set<Entity>, std::size_t> current{};
|
||||
basic_registry *owner;
|
||||
|
||||
group_handler(basic_registry &parent)
|
||||
: owner{&parent}
|
||||
{}
|
||||
|
||||
template<typename Component>
|
||||
void maybe_valid_if(basic_registry &owner, const Entity entt) {
|
||||
[[maybe_unused]] const auto cpools = std::forward_as_tuple(owner.assure<Owned>()...);
|
||||
void maybe_valid_if(const Entity entt) {
|
||||
[[maybe_unused]] const auto cpools = std::forward_as_tuple(owner->assure<Owned>()...);
|
||||
|
||||
const auto is_valid = ((std::is_same_v<Component, Owned> || std::get<pool_handler<Owned> &>(cpools).contains(entt)) && ...)
|
||||
&& ((std::is_same_v<Component, Get> || owner.assure<Get>().contains(entt)) && ...)
|
||||
&& ((std::is_same_v<Component, Exclude> || !owner.assure<Exclude>().contains(entt)) && ...);
|
||||
&& ((std::is_same_v<Component, Get> || owner->assure<Get>().contains(entt)) && ...)
|
||||
&& ((std::is_same_v<Component, Exclude> || !owner->assure<Exclude>().contains(entt)) && ...);
|
||||
|
||||
if constexpr(sizeof...(Owned) == 0) {
|
||||
if(is_valid && !current.contains(entt)) {
|
||||
@@ -151,13 +156,13 @@ class basic_registry {
|
||||
}
|
||||
}
|
||||
|
||||
void discard_if([[maybe_unused]] basic_registry &owner, const Entity entt) {
|
||||
void discard_if(const Entity entt) {
|
||||
if constexpr(sizeof...(Owned) == 0) {
|
||||
if(current.contains(entt)) {
|
||||
current.erase(entt);
|
||||
}
|
||||
} else {
|
||||
if(const auto cpools = std::forward_as_tuple(owner.assure<Owned>()...); std::get<0>(cpools).contains(entt) && (std::get<0>(cpools).index(entt) < current)) {
|
||||
if(const auto cpools = std::forward_as_tuple(owner->assure<Owned>()...); std::get<0>(cpools).contains(entt) && (std::get<0>(cpools).index(entt) < current)) {
|
||||
const auto pos = --current;
|
||||
(std::get<pool_handler<Owned> &>(cpools).swap(std::get<pool_handler<Owned> &>(cpools).data()[pos], entt), ...);
|
||||
}
|
||||
@@ -192,8 +197,8 @@ class basic_registry {
|
||||
if(auto &&pdata = pools[index]; !pdata.pool) {
|
||||
pdata.type_id = type_info<Component>::id();
|
||||
pdata.pool.reset(new pool_handler<Component>());
|
||||
pdata.remove = [](sparse_set<entity_type> &target, basic_registry &owner, const entity_type entt) {
|
||||
static_cast<pool_handler<Component> &>(target).remove(owner, entt);
|
||||
pdata.remove = [](sparse_set<entity_type> &target, const entity_type entt) {
|
||||
static_cast<pool_handler<Component> &>(target).remove(entt);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -203,8 +208,8 @@ class basic_registry {
|
||||
cpool = pools.emplace_back(pool_data{
|
||||
type_info<Component>::id(),
|
||||
std::unique_ptr<sparse_set<entity_type>>{new pool_handler<Component>()},
|
||||
[](sparse_set<entity_type> &target, basic_registry &owner, const entity_type entt) {
|
||||
static_cast<pool_handler<Component> &>(target).remove(owner, entt);
|
||||
[](sparse_set<entity_type> &target, const entity_type entt) {
|
||||
static_cast<pool_handler<Component> &>(target).remove(entt);
|
||||
}
|
||||
}).pool.get();
|
||||
} else {
|
||||
@@ -644,7 +649,7 @@ public:
|
||||
template<typename Component, typename... Args>
|
||||
decltype(auto) emplace(const entity_type entity, Args &&... args) {
|
||||
ENTT_ASSERT(valid(entity));
|
||||
return assure<Component>().emplace(*this, entity, std::forward<Args>(args)...);
|
||||
return assure<Component>().emplace(entity, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -661,7 +666,7 @@ public:
|
||||
template<typename Component, typename It>
|
||||
void insert(It first, It last, const Component &value = {}) {
|
||||
ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }));
|
||||
assure<Component>().insert(*this, first, last, value);
|
||||
assure<Component>().insert(first, last, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -681,7 +686,7 @@ public:
|
||||
void insert(EIt first, EIt last, CIt from, CIt to) {
|
||||
static_assert(std::is_constructible_v<Component, typename std::iterator_traits<CIt>::value_type>, "Invalid value type");
|
||||
ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }));
|
||||
assure<Component>().insert(*this, first, last, from, to);
|
||||
assure<Component>().insert(first, last, from, to);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -712,8 +717,8 @@ public:
|
||||
auto &cpool = assure<Component>();
|
||||
|
||||
return cpool.contains(entity)
|
||||
? cpool.replace(*this, entity, Component{std::forward<Args>(args)...})
|
||||
: cpool.emplace(*this, entity, std::forward<Args>(args)...);
|
||||
? cpool.replace(entity, Component{std::forward<Args>(args)...})
|
||||
: cpool.emplace(entity, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -746,7 +751,7 @@ public:
|
||||
template<typename Component, typename... Func>
|
||||
decltype(auto) patch(const entity_type entity, Func &&... func) {
|
||||
ENTT_ASSERT(valid(entity));
|
||||
return assure<Component>().patch(*this, entity, std::forward<Func>(func)...);
|
||||
return assure<Component>().patch(entity, std::forward<Func>(func)...);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -771,7 +776,7 @@ public:
|
||||
*/
|
||||
template<typename Component, typename... Args>
|
||||
decltype(auto) replace(const entity_type entity, Args &&... args) {
|
||||
return assure<Component>().replace(*this, entity, Component{std::forward<Args>(args)...});
|
||||
return assure<Component>().replace(entity, Component{std::forward<Args>(args)...});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -790,7 +795,7 @@ public:
|
||||
template<typename... Component>
|
||||
void remove(const entity_type entity) {
|
||||
ENTT_ASSERT(valid(entity));
|
||||
(assure<Component>().remove(*this, entity), ...);
|
||||
(assure<Component>().remove(entity), ...);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -806,7 +811,7 @@ public:
|
||||
template<typename... Component, typename It>
|
||||
void remove(It first, It last) {
|
||||
ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }));
|
||||
(assure<Component>().remove(*this, first, last), ...);
|
||||
(assure<Component>().remove(first, last), ...);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -834,7 +839,7 @@ public:
|
||||
ENTT_ASSERT(valid(entity));
|
||||
|
||||
return ([this, entity](auto &&cpool) {
|
||||
return cpool.contains(entity) ? (cpool.remove(*this, entity), true) : false;
|
||||
return cpool.contains(entity) ? (cpool.remove(entity), true) : false;
|
||||
}(assure<Component>()) + ... + size_type{});
|
||||
}
|
||||
|
||||
@@ -859,7 +864,7 @@ public:
|
||||
|
||||
for(auto pos = pools.size(); pos; --pos) {
|
||||
if(auto &pdata = pools[pos-1]; pdata.pool && pdata.pool->contains(entity)) {
|
||||
pdata.remove(*pdata.pool, *this, entity);
|
||||
pdata.remove(*pdata.pool, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -966,7 +971,7 @@ public:
|
||||
[[nodiscard]] decltype(auto) get_or_emplace(const entity_type entity, Args &&... args) {
|
||||
ENTT_ASSERT(valid(entity));
|
||||
auto &cpool = assure<Component>();
|
||||
return cpool.contains(entity) ? cpool.get(entity) : cpool.emplace(*this, entity, std::forward<Args>(args)...);
|
||||
return cpool.contains(entity) ? cpool.get(entity) : cpool.emplace(entity, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1015,7 +1020,7 @@ public:
|
||||
each([this](const auto entity) { this->destroy(entity); });
|
||||
} else {
|
||||
([this](auto &&cpool) {
|
||||
cpool.remove(*this, cpool.sparse_set<entity_type>::begin(), cpool.sparse_set<entity_type>::end());
|
||||
cpool.remove(cpool.sparse_set<entity_type>::begin(), cpool.sparse_set<entity_type>::end());
|
||||
}(assure<Component>()), ...);
|
||||
}
|
||||
}
|
||||
@@ -1308,7 +1313,7 @@ public:
|
||||
if(!handler) {
|
||||
group_data candidate = {
|
||||
size,
|
||||
{ new handler_type{}, [](void *instance) { delete static_cast<handler_type *>(instance); } },
|
||||
{ new handler_type{*this}, [](void *instance) { delete static_cast<handler_type *>(instance); } },
|
||||
[]([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_info<std::decay_t<Owned>>::id()) || ...); },
|
||||
[]([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_info<std::decay_t<Get>>::id()) || ...); },
|
||||
[]([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_info<Exclude>::id()) || ...); },
|
||||
@@ -1356,7 +1361,7 @@ public:
|
||||
} else {
|
||||
// we cannot iterate backwards because we want to leave behind valid entities in case of owned types
|
||||
for(auto *first = std::get<0>(cpools).data(), *last = first + std::get<0>(cpools).size(); first != last; ++first) {
|
||||
handler->template maybe_valid_if<std::tuple_element_t<0, std::tuple<std::decay_t<Owned>...>>>(*this, *first);
|
||||
handler->template maybe_valid_if<std::tuple_element_t<0, std::tuple<std::decay_t<Owned>...>>>(*first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -570,7 +570,7 @@ TEST(NonOwningGroup, FrontBack) {
|
||||
|
||||
TEST(NonOwningGroup, SignalRace) {
|
||||
entt::registry registry;
|
||||
registry.on_construct<double>().connect<&entt::registry::emplace_or_replace<int>>();
|
||||
registry.on_construct<double>().connect<&entt::registry::emplace_or_replace<int>>(registry);
|
||||
const auto group = registry.group(entt::get<int, double>);
|
||||
|
||||
auto entity = registry.create();
|
||||
@@ -1227,7 +1227,7 @@ TEST(OwningGroup, FrontBack) {
|
||||
|
||||
TEST(OwningGroup, SignalRace) {
|
||||
entt::registry registry;
|
||||
registry.on_construct<double>().connect<&entt::registry::emplace_or_replace<int>>();
|
||||
registry.on_construct<double>().connect<&entt::registry::emplace_or_replace<int>>(registry);
|
||||
const auto group = registry.group<int>(entt::get<double>);
|
||||
|
||||
auto entity = registry.create();
|
||||
|
||||
@@ -33,7 +33,7 @@ TEST(Helper, Invoke) {
|
||||
entt::registry registry;
|
||||
const auto entity = registry.create();
|
||||
|
||||
registry.on_construct<clazz>().connect<entt::invoke<&clazz::func>>();
|
||||
registry.on_construct<clazz>().connect<entt::invoke<&clazz::func>>(registry);
|
||||
registry.emplace<clazz>(entity);
|
||||
|
||||
ASSERT_EQ(entity, registry.get<clazz>(entity).entt);
|
||||
|
||||
@@ -27,17 +27,13 @@ struct listener {
|
||||
}
|
||||
|
||||
template<typename Component>
|
||||
void incr(const entt::registry ®istry, entt::entity entity) {
|
||||
ASSERT_TRUE(registry.valid(entity));
|
||||
ASSERT_TRUE(registry.has<Component>(entity));
|
||||
void incr(entt::entity entity) {
|
||||
last = entity;
|
||||
++counter;
|
||||
}
|
||||
|
||||
template<typename Component>
|
||||
void decr(const entt::registry ®istry, entt::entity entity) {
|
||||
ASSERT_TRUE(registry.valid(entity));
|
||||
ASSERT_TRUE(registry.has<Component>(entity));
|
||||
void decr(entt::entity entity) {
|
||||
last = entity;
|
||||
--counter;
|
||||
}
|
||||
@@ -1378,8 +1374,8 @@ TEST(Registry, Dependencies) {
|
||||
constexpr auto emplace_or_replace = &entt::registry::emplace_or_replace<double>;
|
||||
constexpr auto remove = &entt::registry::remove<double>;
|
||||
|
||||
registry.on_construct<int>().connect<emplace_or_replace>();
|
||||
registry.on_destroy<int>().connect<remove>();
|
||||
registry.on_construct<int>().connect<emplace_or_replace>(registry);
|
||||
registry.on_destroy<int>().connect<remove>(registry);
|
||||
registry.emplace<double>(entity, .3);
|
||||
|
||||
ASSERT_FALSE(registry.has<int>(entity));
|
||||
@@ -1394,8 +1390,8 @@ TEST(Registry, Dependencies) {
|
||||
|
||||
ASSERT_FALSE((registry.any<int, double>(entity)));
|
||||
|
||||
registry.on_construct<int>().disconnect<emplace_or_replace>();
|
||||
registry.on_destroy<int>().disconnect<remove>();
|
||||
registry.on_construct<int>().disconnect<emplace_or_replace>(registry);
|
||||
registry.on_destroy<int>().disconnect<remove>(registry);
|
||||
registry.emplace<int>(entity);
|
||||
|
||||
ASSERT_TRUE((registry.any<int, double>(entity)));
|
||||
@@ -1404,7 +1400,7 @@ TEST(Registry, Dependencies) {
|
||||
|
||||
TEST(Registry, StableEmplace) {
|
||||
entt::registry registry;
|
||||
registry.on_construct<int>().connect<&listener::sort<int>>();
|
||||
registry.on_construct<int>().connect<&listener::sort<int>>(registry);
|
||||
registry.emplace<int>(registry.create(), 0);
|
||||
|
||||
ASSERT_EQ(registry.emplace<int>(registry.create(), 1), 1);
|
||||
|
||||
Reference in New Issue
Block a user