Add entity_container to ECS system arguments; make both entity_container and entity_handle optional arguments

This commit is contained in:
Nikita Lisitsa 2023-08-23 12:22:50 +03:00
parent 0f621a9f3f
commit 0b562a26c1
5 changed files with 44 additions and 13 deletions

View file

@ -3,20 +3,31 @@
#include <psemek/ecs/detail/table.hpp>
#include <psemek/ecs/detail/entity_list.hpp>
#include <concepts>
namespace psemek::ecs
{
struct entity_container;
}
namespace psemek::ecs::detail
{
template <typename ... Components>
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_id const> entity_ids, util::span<entity_data const> entities)
: row_count(entity_ids.size())
static_apply_helper(entity_container & parent, util::span<entity_id const> entity_ids, util::span<entity_data const> 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<Components *>(pointers[I].data) ...);
entity_handle handle{id, epoch};
if constexpr (std::invocable<Function, entity_container &, entity_handle, Components & ...>)
{
function(parent, handle, *reinterpret_cast<Components *>(pointers[I].data) ...);
}
else if constexpr (std::invocable<Function, entity_container &, Components & ...>)
{
function(parent, *reinterpret_cast<Components *>(pointers[I].data) ...);
}
else if constexpr (std::invocable<Function, entity_handle, Components & ...>)
{
function(handle, *reinterpret_cast<Components *>(pointers[I].data) ...);
}
else
{
function(*reinterpret_cast<Components *>(pointers[I].data) ...);
}
}
std::size_t size() const

View file

@ -120,7 +120,7 @@ namespace psemek::ecs
for (auto const & entry : cache->tables)
{
detail::static_apply_helper<Components...> apply_helper(entry.table->get_entity_ids(), entity_list_.get_entities());
detail::static_apply_helper<Components...> 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]];

View file

@ -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<component_1>([&](ecs::entity_handle const &, component_1 const & component){
container.apply<component_1>([&](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<component_1>([&](ecs::entity_handle const &, component_1 const & component){
container.apply<component_1>([&](component_1 const & component){
++count;
sum += component.value;
});
container.apply<component_2>([&](ecs::entity_handle const &, component_2 const & component){
container.apply<component_2>([&](component_2 const & component){
++count;
sum += component.value;
});
container.apply<component_1, component_2>([&](ecs::entity_handle const &, component_1 const & component1, component_2 const &){
container.apply<component_1, component_2>([&](component_1 const & component1, component_2 const &){
--count;
sum -= component1.value;
});

View file

@ -98,7 +98,7 @@ test_case(ecs_cache_apply)
auto cache = container.cache<component_1>();
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;

View file

@ -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<int>(42)}));
container.apply<component_counter>([&](entity_handle const &, component_counter const & component){
container.apply<component_counter>([&](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<component_counter>([&](entity_handle const &, component_counter const & component){
container.apply<component_counter>([&](component_counter const & component){
expect_equal(component.value.use_count(), 1);
});
}