diff --git a/libs/ecs/include/psemek/ecs/detail/apply_helper.hpp b/libs/ecs/include/psemek/ecs/detail/apply_helper.hpp index 09f2627d..401125c6 100644 --- a/libs/ecs/include/psemek/ecs/detail/apply_helper.hpp +++ b/libs/ecs/include/psemek/ecs/detail/apply_helper.hpp @@ -3,20 +3,31 @@ #include #include +#include + +namespace psemek::ecs +{ + + struct entity_container; + +} + namespace psemek::ecs::detail { template struct static_apply_helper { + entity_container & parent; std::size_t row_count; entity_id const * entity_id_pointer; entity_data const * entity_data_pointer; // (+1) to prevent zero-sized array table::component_pointer pointers[sizeof...(Components) + 1]; - static_apply_helper(util::span entity_ids, util::span entities) - : row_count(entity_ids.size()) + static_apply_helper(entity_container & parent, util::span entity_ids, util::span entities) + : parent(parent) + , row_count(entity_ids.size()) , entity_id_pointer(entity_ids.data()) , entity_data_pointer(entities.data()) {} @@ -32,7 +43,24 @@ namespace psemek::ecs::detail { auto id = *entity_id_pointer; auto epoch = entity_data_pointer[id].epoch; - function(entity_handle{id, epoch}, *reinterpret_cast(pointers[I].data) ...); + entity_handle handle{id, epoch}; + + if constexpr (std::invocable) + { + function(parent, handle, *reinterpret_cast(pointers[I].data) ...); + } + else if constexpr (std::invocable) + { + function(parent, *reinterpret_cast(pointers[I].data) ...); + } + else if constexpr (std::invocable) + { + function(handle, *reinterpret_cast(pointers[I].data) ...); + } + else + { + function(*reinterpret_cast(pointers[I].data) ...); + } } std::size_t size() const diff --git a/libs/ecs/include/psemek/ecs/entity_container.hpp b/libs/ecs/include/psemek/ecs/entity_container.hpp index e2dc6c81..b61085ba 100644 --- a/libs/ecs/include/psemek/ecs/entity_container.hpp +++ b/libs/ecs/include/psemek/ecs/entity_container.hpp @@ -120,7 +120,7 @@ namespace psemek::ecs for (auto const & entry : cache->tables) { - detail::static_apply_helper apply_helper(entry.table->get_entity_ids(), entity_list_.get_entities()); + detail::static_apply_helper apply_helper(*this, entry.table->get_entity_ids(), entity_list_.get_entities()); for (std::size_t i = 0; i < sizeof...(Components); ++i) apply_helper.pointers[i] = entry.table->get_component_pointers()[entry.column_ids[i]]; diff --git a/libs/ecs/tests/apply.cpp b/libs/ecs/tests/apply.cpp index 35d25cc1..ae8ad25d 100644 --- a/libs/ecs/tests/apply.cpp +++ b/libs/ecs/tests/apply.cpp @@ -36,8 +36,11 @@ test_case(ecs_apply_empty) container.create(); int call_count = 0; - container.apply<>([&](ecs::entity_handle const &){ ++call_count; }); - expect_equal(count, call_count); + container.apply<>([&](entity_container &, entity_handle const &){ ++call_count; }); + container.apply<>([&](entity_container &){ ++call_count; }); + container.apply<>([&](entity_handle const &){ ++call_count; }); + container.apply<>([&]{ ++call_count; }); + expect_equal(count * 4, call_count); } test_case(ecs_apply_components_1) @@ -57,7 +60,7 @@ test_case(ecs_apply_components_1) int count = 0; int sum = 0; - container.apply([&](ecs::entity_handle const &, component_1 const & component){ + container.apply([&](component_1 const & component){ ++count; sum += component.value; }); @@ -90,15 +93,15 @@ test_case(ecs_apply_components_2) int count = 0; int sum = 0; - container.apply([&](ecs::entity_handle const &, component_1 const & component){ + container.apply([&](component_1 const & component){ ++count; sum += component.value; }); - container.apply([&](ecs::entity_handle const &, component_2 const & component){ + container.apply([&](component_2 const & component){ ++count; sum += component.value; }); - container.apply([&](ecs::entity_handle const &, component_1 const & component1, component_2 const &){ + container.apply([&](component_1 const & component1, component_2 const &){ --count; sum -= component1.value; }); diff --git a/libs/ecs/tests/cache.cpp b/libs/ecs/tests/cache.cpp index ce452b22..536832f4 100644 --- a/libs/ecs/tests/cache.cpp +++ b/libs/ecs/tests/cache.cpp @@ -98,7 +98,7 @@ test_case(ecs_cache_apply) auto cache = container.cache(); int call_count = 0; - auto counter = [&](entity_handle const &, component_1 const &){ ++call_count; }; + auto counter = [&](component_1 const &){ ++call_count; }; int count_0 = 16; int count_1 = 32; diff --git a/libs/ecs/tests/component.cpp b/libs/ecs/tests/component.cpp index 91e694d7..11b65da5 100644 --- a/libs/ecs/tests/component.cpp +++ b/libs/ecs/tests/component.cpp @@ -94,7 +94,7 @@ test_case(ecs_component_lifetime) for (int i = 0; i < 1024 * 1024; ++i) entities.push_back(container.create(component_counter{std::make_shared(42)})); - container.apply([&](entity_handle const &, component_counter const & component){ + container.apply([&](component_counter const & component){ expect_equal(component.value.use_count(), 1); }); @@ -103,7 +103,7 @@ test_case(ecs_component_lifetime) for (int i = 0; i < entities.size() / 2; ++i) container.destroy(entities[i]); - container.apply([&](entity_handle const &, component_counter const & component){ + container.apply([&](component_counter const & component){ expect_equal(component.value.use_count(), 1); }); }