Skip to content

fix: entity created callback called too often #111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions ecsact/entt/wrapper/core.hh
Original file line number Diff line number Diff line change
Expand Up @@ -216,43 +216,43 @@ inline auto _trigger_create_entity_events(
) -> void {
using ecsact::entt::detail::created_entity;

if(!events_collector.has_entity_created_callback()) {
return;
}

auto& reg = ecsact::entt::get_registry(registry_id);

::entt::basic_view created_view{
reg.template storage<created_entity>(),
};
if(events_collector.has_entity_created_callback()) {
::entt::basic_view created_view{
reg.template storage<created_entity>(),
};

for(ecsact::entt::entity_id entity : created_view) {
events_collector.invoke_entity_created_callback(
entity,
created_view.template get<created_entity>(entity).placeholder_entity_id
);
for(ecsact::entt::entity_id entity : created_view) {
events_collector.invoke_entity_created_callback(
entity,
created_view.template get<created_entity>(entity).placeholder_entity_id
);
}
}

reg.clear<created_entity>();
}

inline auto _trigger_destroy_entity_events(
ecsact_registry_id registry_id,
ecsact::entt::detail::execution_events_collector& events_collector
) -> void {
auto& reg = ecsact::entt::get_registry(registry_id);

using ecsact::entt::detail::destroyed_entity;

if(!events_collector.has_entity_destroyed_callback()) {
return;
}
auto& reg = ecsact::entt::get_registry(registry_id);

::entt::basic_view destroy_view{
reg.template storage<destroyed_entity>(),
};
if(events_collector.has_entity_destroyed_callback()) {
::entt::basic_view destroy_view{
reg.template storage<destroyed_entity>(),
};

for(ecsact::entt::entity_id entity : destroy_view) {
events_collector.invoke_entity_destroyed_callback(entity);
for(ecsact::entt::entity_id entity : destroy_view) {
events_collector.invoke_entity_destroyed_callback(entity);
}
}

reg.clear<destroyed_entity>();
}

template<typename C>
Expand Down
38 changes: 26 additions & 12 deletions test/runtime_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,8 @@ TEST(Core, CreateAndDestroyEntity) {
ecsact_placeholder_entity_id placeholder_entity_id;
};

auto info = callback_info{};
auto created_entity = ecsact_invalid_entity_id;
auto info = std::optional<callback_info>{};
auto options = ecsact::core::execution_options{};
auto evc = ecsact::core::execution_events_collector<>{};

Expand All @@ -798,42 +799,55 @@ TEST(Core, CreateAndDestroyEntity) {
ecsact_entity_id entity_id,
ecsact_placeholder_entity_id placeholder_entity_id
) {
info.entity_created = true;
info.entity_id = entity_id;
info.placeholder_entity_id = placeholder_entity_id;
info = callback_info{};
info->entity_created = true;
info->entity_id = entity_id;
info->placeholder_entity_id = placeholder_entity_id;
created_entity = entity_id;
}
);

evc.set_entity_destroyed_callback([&](ecsact_entity_id entity_id) {
info.entity_destroyed = true;
info.entity_id = entity_id;
info = callback_info{};
info->entity_destroyed = true;
info->entity_id = entity_id;
});

options.create_entity(static_cast<ecsact_placeholder_entity_id>(42))
.add_component(&component_a);
auto exec_err = reg.execute_systems(std::array{options}, evc);
EXPECT_EQ(exec_err, ECSACT_EXEC_SYS_OK);

ASSERT_TRUE(info.entity_created);
ASSERT_FALSE(info.entity_destroyed);
ASSERT_TRUE(info.has_value());
ASSERT_TRUE(info->entity_created);
ASSERT_FALSE(info->entity_destroyed);
ASSERT_EQ(info->entity_id, created_entity);
ASSERT_EQ(reg.count_entities(), 1);

EXPECT_EQ(
info.placeholder_entity_id,
info->placeholder_entity_id,
static_cast<ecsact_placeholder_entity_id>(42)
);

auto comp = reg.get_component<runtime_test::EntityTesting>(info.entity_id);
auto comp = reg.get_component<runtime_test::EntityTesting>(info->entity_id);

ASSERT_EQ(comp.a, 6);

options.clear();
options.destroy_entity(info.entity_id);
info = std::nullopt;

// Make sure create doesn't get called again
exec_err = reg.execute_systems(std::array{options}, evc);
ASSERT_EQ(exec_err, ECSACT_EXEC_SYS_OK);
ASSERT_FALSE(info.has_value());

options.destroy_entity(created_entity);
info = std::nullopt;
exec_err = reg.execute_systems(std::array{options}, evc);
ASSERT_EQ(exec_err, ECSACT_EXEC_SYS_OK);
ASSERT_EQ(reg.count_entities(), 0);
ASSERT_TRUE(info.entity_destroyed);
ASSERT_TRUE(info.has_value());
ASSERT_TRUE(info->entity_destroyed);
}

TEST(Core, MultiPkgUpdate) {
Expand Down