Add debug assertions for when an entity's archetype is changed while it is being created/destroyed

This commit is contained in:
Nikita Lisitsa 2025-10-10 15:51:45 +03:00
parent 8d25721d35
commit 4a4f680d0a
2 changed files with 39 additions and 0 deletions

View file

@ -394,6 +394,10 @@ namespace psemek::ecs
std::size_t method_recursion_depth_ = 0;
std::vector<util::function<void(container &)>> finally_callbacks_;
#ifdef PSEMEK_DEBUG
util::hash_set<ecs::handle> currently_changing_archetype_;
#endif
detail::table * insert_table(std::vector<std::unique_ptr<detail::column>> columns);
void do_destroy(handle entity);
void remove_row(detail::table & table, std::uint32_t row, util::span<detail::entity_data> entities);
@ -434,6 +438,9 @@ namespace psemek::ecs
auto row = table->row_count();
auto id = entity_list_.create(table, row);
handle handle{id, entity_list_.get_entities()[id].epoch};
#ifdef PSEMEK_DEBUG
currently_changing_archetype_.insert(handle);
#endif
[[maybe_unused]] accessor accessor = get(handle);
table->push_row(handle);
@ -441,6 +448,10 @@ namespace psemek::ecs
table->trigger_constructors(*this, row);
#ifdef PSEMEK_DEBUG
currently_changing_archetype_.erase(handle);
#endif
finalize_method();
--method_recursion_depth_;
@ -453,6 +464,11 @@ namespace psemek::ecs
{
static_assert(detail::all_different_types_v<std::remove_cvref_t<Components>...>, "all component types must be different");
#ifdef PSEMEK_DEBUG
assert(!currently_changing_archetype_.contains(entity));
currently_changing_archetype_.insert(entity);
#endif
++method_recursion_depth_;
(register_component<Components>(), ...);
@ -510,6 +526,10 @@ namespace psemek::ecs
uuid_set_pool_.put(std::move(attached_uuid_set));
uuid_list_pool_.put(std::move(uuids));
#ifdef PSEMEK_DEBUG
currently_changing_archetype_.erase(entity);
#endif
finalize_method();
--method_recursion_depth_;
@ -520,6 +540,11 @@ namespace psemek::ecs
{
static_assert(detail::all_different_types_v<std::remove_const_t<Components>...>, "all component types must be different");
#ifdef PSEMEK_DEBUG
assert(!currently_changing_archetype_.contains(entity));
currently_changing_archetype_.insert(entity);
#endif
++method_recursion_depth_;
auto detached_uuid_set = uuid_set_pool_.get();
@ -577,6 +602,10 @@ namespace psemek::ecs
uuid_list_pool_.put(std::move(uuids));
uuid_set_pool_.put(std::move(detached_uuid_set));
#ifdef PSEMEK_DEBUG
currently_changing_archetype_.erase(entity);
#endif
finalize_method();
--method_recursion_depth_;

View file

@ -13,6 +13,11 @@ namespace psemek::ecs
void container::destroy(handle entity)
{
#ifdef PSEMEK_DEBUG
assert(!currently_changing_archetype_.contains(entity));
currently_changing_archetype_.insert(entity);
#endif
assert(alive(entity));
++method_recursion_depth_;
@ -23,10 +28,15 @@ namespace psemek::ecs
do_destroy(entity);
entity_list_.destroy(entity.id);
#ifdef PSEMEK_DEBUG
currently_changing_archetype_.erase(entity);
#endif
finalize_method();
--method_recursion_depth_;
}
}
accessor container::get(handle entity)
{