ECS destructors wip
This commit is contained in:
parent
028b4e1296
commit
a85e72a5b6
7 changed files with 79 additions and 3 deletions
|
|
@ -336,7 +336,6 @@ namespace psemek::ecs
|
|||
* detaches components), the behavior is undefined
|
||||
* @warning If the destructor destroys the entity recursively, the behavior is undefined
|
||||
*/
|
||||
// TODO: implement
|
||||
template <typename ... Components, typename Function>
|
||||
void destructor(Function && function);
|
||||
|
||||
|
|
@ -631,4 +630,30 @@ namespace psemek::ecs
|
|||
callback_caches_.push_back(cache);
|
||||
}
|
||||
|
||||
template <typename ... Components, typename Function>
|
||||
void container::destructor(Function && function)
|
||||
{
|
||||
static_assert(detail::all_different_types_v<std::remove_const_t<Components>...>, "all component types must be different");
|
||||
|
||||
using invocable_type = typename detail::filter_with<detail::invocable, std::tuple<Components ...>, Function>::type;
|
||||
|
||||
static_assert(invocable_type::value, "function is not invocable with these components");
|
||||
|
||||
query_cache cache = this->cache<Components...>();
|
||||
|
||||
cache->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){
|
||||
typename detail::filter_with<detail::static_apply_helper, std::tuple<Components ...>>::type apply_helper(container, table.entity_handles());
|
||||
|
||||
for (std::size_t i = 0; i < apply_helper.column_count; ++i)
|
||||
apply_helper.pointers[i] = table.columns()[column_indices[i]]->data();
|
||||
|
||||
apply_helper.advance(row);
|
||||
apply_helper.apply(function);
|
||||
};
|
||||
};
|
||||
|
||||
callback_caches_.push_back(cache);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ namespace psemek::ecs::detail
|
|||
std::vector<query_cache_entry> entries;
|
||||
|
||||
util::function<table_callback(std::vector<std::uint32_t> const &)> constructor_factory;
|
||||
util::function<table_callback(std::vector<std::uint32_t> const &)> destructor_factory;
|
||||
|
||||
void add(table * table);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -73,8 +73,10 @@ namespace psemek::ecs::detail
|
|||
std::vector<std::type_index> const & non_copyable_components() const;
|
||||
|
||||
void add_constructor(table_callback callback);
|
||||
void add_destructor(table_callback callback);
|
||||
|
||||
void trigger_constructors(container & container, std::uint32_t row);
|
||||
void trigger_destructors(container & container, std::uint32_t row);
|
||||
|
||||
protected:
|
||||
std::size_t hash_;
|
||||
|
|
@ -90,6 +92,7 @@ namespace psemek::ecs::detail
|
|||
std::vector<std::type_index> non_copyable_components_;
|
||||
|
||||
std::shared_ptr<std::vector<table_callback>> constructors_;
|
||||
std::shared_ptr<std::vector<table_callback>> destructors_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ namespace psemek::ecs
|
|||
auto & data = entities[entity.id];
|
||||
auto & iteration_data = data.table->get_iteration_data();
|
||||
|
||||
data.table->trigger_destructors(*this, data.row);
|
||||
|
||||
if (!iteration_data || iteration_data->current_row < data.row)
|
||||
remove_row(*data.table, data.row, entities);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ namespace psemek::ecs::detail
|
|||
|
||||
if (constructor_factory)
|
||||
table->add_constructor(constructor_factory(entry.columns_indices));
|
||||
|
||||
if (destructor_factory)
|
||||
table->add_destructor(destructor_factory(entry.columns_indices));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ namespace psemek::ecs::detail
|
|||
columns_ = std::move(columns);
|
||||
|
||||
constructors_ = std::make_shared<std::vector<table_callback>>();
|
||||
destructors_ = std::make_shared<std::vector<table_callback>>();
|
||||
}
|
||||
|
||||
std::optional<std::size_t> table::column_index(util::uuid const & uuid) const
|
||||
|
|
@ -108,6 +109,7 @@ namespace psemek::ecs::detail
|
|||
|
||||
auto result = std::make_unique<table>(std::move(columns));
|
||||
result->constructors_ = constructors_;
|
||||
result->destructors_ = destructors_;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -146,12 +148,21 @@ namespace psemek::ecs::detail
|
|||
constructors_->push_back(std::move(callback));
|
||||
}
|
||||
|
||||
void table::add_destructor(table_callback callback)
|
||||
{
|
||||
destructors_->push_back(std::move(callback));
|
||||
}
|
||||
|
||||
void table::trigger_constructors(container & container, std::uint32_t row)
|
||||
{
|
||||
for (auto const & callback : *constructors_)
|
||||
{
|
||||
callback(container, *this, row);
|
||||
}
|
||||
}
|
||||
|
||||
void table::trigger_destructors(container & container, std::uint32_t row)
|
||||
{
|
||||
for (auto const & callback : *destructors_)
|
||||
callback(container, *this, row);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,3 +52,34 @@ test_case(ecs_callback_constructor_create)
|
|||
container.create(component_1{40}, component_2{200});
|
||||
expect_equal(value, 40);
|
||||
}
|
||||
|
||||
test_case(ecs_callback_destructor_destroy)
|
||||
{
|
||||
container container;
|
||||
|
||||
int value = 0;
|
||||
container.destructor<component_1>([&value](component_1 const & c1){
|
||||
value = c1.value;
|
||||
});
|
||||
|
||||
auto h1 = container.create(component_1{10});
|
||||
auto h2 = container.create(component_1{20});
|
||||
auto h3 = container.create(component_2{100});
|
||||
auto h4 = container.create();
|
||||
auto h5 = container.create(component_1{30});
|
||||
auto h6 = container.create(component_1{40}, component_2{200});
|
||||
|
||||
expect_equal(value, 0);
|
||||
container.destroy(h1);
|
||||
expect_equal(value, 10);
|
||||
container.destroy(h2);
|
||||
expect_equal(value, 20);
|
||||
container.destroy(h3);
|
||||
expect_equal(value, 20);
|
||||
container.destroy(h4);
|
||||
expect_equal(value, 20);
|
||||
container.destroy(h5);
|
||||
expect_equal(value, 30);
|
||||
container.destroy(h6);
|
||||
expect_equal(value, 40);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue