Fix triggering constructor & destructor callbacks when attaching/detaching ecs components
This commit is contained in:
parent
42260d4d7d
commit
e5811b61a0
5 changed files with 42 additions and 20 deletions
|
|
@ -479,6 +479,9 @@ namespace psemek::ecs
|
|||
for (auto const & uuid : attached_uuid_set)
|
||||
uuids.push_back(uuid);
|
||||
|
||||
if (archetype_changed)
|
||||
data->table->trigger_destructors(*this, data->row, attached_uuid_set, {});
|
||||
|
||||
auto table = table_container_.get(uuids);
|
||||
|
||||
if (!table)
|
||||
|
|
@ -508,7 +511,7 @@ namespace psemek::ecs
|
|||
((accessor.get<std::remove_cvref_t<Components>>() = std::forward<Components>(components)), ...);
|
||||
|
||||
if (archetype_changed)
|
||||
table->trigger_constructors(*this, data->row, attached_uuid_set);
|
||||
table->trigger_constructors(*this, data->row, attached_uuid_set, {});
|
||||
|
||||
attached_uuid_set.clear();
|
||||
uuids.clear();
|
||||
|
|
@ -530,10 +533,9 @@ namespace psemek::ecs
|
|||
auto * data = entity_list_.get_entities().begin() + entity.id;
|
||||
for (auto const & column : data->table->columns())
|
||||
{
|
||||
if (detached_uuid_set.contains(column->uuid()))
|
||||
detached_uuid_set.insert(column->uuid());
|
||||
else
|
||||
uuids.push_back(column->uuid());
|
||||
auto const column_uuid = column->uuid();
|
||||
if (!detached_uuid_set.contains(column_uuid))
|
||||
uuids.push_back(column_uuid);
|
||||
}
|
||||
|
||||
bool const archetype_changed = sizeof...(Components) > 0;
|
||||
|
|
@ -541,7 +543,7 @@ namespace psemek::ecs
|
|||
auto table = table_container_.get(uuids);
|
||||
|
||||
if (archetype_changed)
|
||||
data->table->trigger_destructors(*this, data->row, detached_uuid_set);
|
||||
data->table->trigger_destructors(*this, data->row, {}, detached_uuid_set);
|
||||
|
||||
// Destructors could lead to reallocation of entity list
|
||||
data = entity_list_.get_entities().begin() + entity.id;
|
||||
|
|
@ -568,6 +570,9 @@ namespace psemek::ecs
|
|||
data->row = new_row;
|
||||
}
|
||||
|
||||
if (archetype_changed)
|
||||
table->trigger_constructors(*this, data->row, {}, detached_uuid_set);
|
||||
|
||||
detached_uuid_set.clear();
|
||||
uuids.clear();
|
||||
detached_uuid_set.clear();
|
||||
|
|
@ -664,9 +669,12 @@ namespace psemek::ecs
|
|||
auto id = next_constructor_id_++;
|
||||
|
||||
auto constructor_factory = [function = std::move(function)](std::vector<std::uint32_t> const & column_indices) -> detail::table_callback {
|
||||
return [function, column_indices](container & container, detail::table & table, std::uint32_t row, util::hash_set<util::uuid> const & attached_components, bool force){
|
||||
return [function, column_indices](container & container, detail::table & table, std::uint32_t row, util::hash_set<util::uuid> const & attached_components, util::hash_set<util::uuid> const & detached_components, bool force){
|
||||
|
||||
bool const invoke = force || (detail::contains_helper<Components>::contains(attached_components) || ...);
|
||||
bool const invoke = force
|
||||
|| (detail::contains_helper<Components>::contains(attached_components) || ...)
|
||||
|| (detail::contains_helper<Components>::contains_without(detached_components) || ...)
|
||||
;
|
||||
if (!invoke)
|
||||
return;
|
||||
|
||||
|
|
@ -699,9 +707,11 @@ namespace psemek::ecs
|
|||
auto id = next_destructor_id_++;
|
||||
|
||||
auto destructor_factory = [function = std::move(function)](std::vector<std::uint32_t> const & column_indices) -> detail::table_callback {
|
||||
return [function, column_indices](container & container, detail::table & table, std::uint32_t row, util::hash_set<util::uuid> const & detached_components, bool force){
|
||||
|
||||
bool const invoke = force || (detail::contains_helper<Components>::contains(detached_components) || ...);
|
||||
return [function, column_indices](container & container, detail::table & table, std::uint32_t row, util::hash_set<util::uuid> const & attached_components, util::hash_set<util::uuid> const & detached_components, bool force){
|
||||
bool const invoke = force
|
||||
|| (detail::contains_helper<Components>::contains_without(attached_components) || ...)
|
||||
|| (detail::contains_helper<Components>::contains(detached_components) || ...)
|
||||
;
|
||||
if (!invoke)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace psemek::ecs
|
|||
|
||||
struct table;
|
||||
|
||||
using table_callback = util::function<void(container &, table &, std::uint32_t, util::hash_set<util::uuid> const &, bool)>;
|
||||
using table_callback = util::function<void(container &, table &, std::uint32_t, util::hash_set<util::uuid> const &, util::hash_set<util::uuid> const &, bool)>;
|
||||
|
||||
struct ordered_table_callback
|
||||
{
|
||||
|
|
|
|||
|
|
@ -74,10 +74,10 @@ namespace psemek::ecs::detail
|
|||
void add_destructor(ordered_table_callback callback);
|
||||
|
||||
void trigger_constructors(container & container, std::uint32_t row);
|
||||
void trigger_constructors(container & container, std::uint32_t row, util::hash_set<util::uuid> const & attached_components);
|
||||
void trigger_constructors(container & container, std::uint32_t row, util::hash_set<util::uuid> const & attached_components, util::hash_set<util::uuid> const & detached_components);
|
||||
|
||||
void trigger_destructors(container & container, std::uint32_t row);
|
||||
void trigger_destructors(container & container, std::uint32_t row, util::hash_set<util::uuid> const & detached_components);
|
||||
void trigger_destructors(container & container, std::uint32_t row, util::hash_set<util::uuid> const & attached_components, util::hash_set<util::uuid> const & detached_components);
|
||||
|
||||
std::size_t memory_usage() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -87,6 +87,12 @@ namespace psemek::ecs::detail
|
|||
{
|
||||
return container.contains(Component::uuid());
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
static bool contains_without(Container const &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Component>
|
||||
|
|
@ -97,6 +103,12 @@ namespace psemek::ecs::detail
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
static bool contains_without(Container const & container)
|
||||
{
|
||||
return container.contains(Component::uuid());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,25 +161,25 @@ namespace psemek::ecs::detail
|
|||
void table::trigger_constructors(container & container, std::uint32_t row)
|
||||
{
|
||||
for (auto const & callback : *constructors_)
|
||||
callback.callback(container, *this, row, column_uuid_set_, true);
|
||||
callback.callback(container, *this, row, column_uuid_set_, {}, true);
|
||||
}
|
||||
|
||||
void table::trigger_constructors(container & container, std::uint32_t row, util::hash_set<util::uuid> const & attached_components)
|
||||
void table::trigger_constructors(container & container, std::uint32_t row, util::hash_set<util::uuid> const & attached_components, util::hash_set<util::uuid> const & detached_components)
|
||||
{
|
||||
for (auto const & callback : *constructors_)
|
||||
callback.callback(container, *this, row, attached_components, false);
|
||||
callback.callback(container, *this, row, attached_components, detached_components, false);
|
||||
}
|
||||
|
||||
void table::trigger_destructors(container & container, std::uint32_t row)
|
||||
{
|
||||
for (auto const & callback : *destructors_)
|
||||
callback.callback(container, *this, row, column_uuid_set_, true);
|
||||
callback.callback(container, *this, row, {}, column_uuid_set_, true);
|
||||
}
|
||||
|
||||
void table::trigger_destructors(container & container, std::uint32_t row, util::hash_set<util::uuid> const & detached_components)
|
||||
void table::trigger_destructors(container & container, std::uint32_t row, util::hash_set<util::uuid> const & attached_components, util::hash_set<util::uuid> const & detached_components)
|
||||
{
|
||||
for (auto const & callback : *destructors_)
|
||||
callback.callback(container, *this, row, detached_components, false);
|
||||
callback.callback(container, *this, row, attached_components, detached_components, false);
|
||||
}
|
||||
|
||||
std::size_t table::memory_usage() const
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue