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
|
* detaches components), the behavior is undefined
|
||||||
* @warning If the destructor destroys the entity recursively, the behavior is undefined
|
* @warning If the destructor destroys the entity recursively, the behavior is undefined
|
||||||
*/
|
*/
|
||||||
// TODO: implement
|
|
||||||
template <typename ... Components, typename Function>
|
template <typename ... Components, typename Function>
|
||||||
void destructor(Function && function);
|
void destructor(Function && function);
|
||||||
|
|
||||||
|
|
@ -631,4 +630,30 @@ namespace psemek::ecs
|
||||||
callback_caches_.push_back(cache);
|
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;
|
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 &)> constructor_factory;
|
||||||
|
util::function<table_callback(std::vector<std::uint32_t> const &)> destructor_factory;
|
||||||
|
|
||||||
void add(table * table);
|
void add(table * table);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,10 @@ namespace psemek::ecs::detail
|
||||||
std::vector<std::type_index> const & non_copyable_components() const;
|
std::vector<std::type_index> const & non_copyable_components() const;
|
||||||
|
|
||||||
void add_constructor(table_callback callback);
|
void add_constructor(table_callback callback);
|
||||||
|
void add_destructor(table_callback callback);
|
||||||
|
|
||||||
void trigger_constructors(container & container, std::uint32_t row);
|
void trigger_constructors(container & container, std::uint32_t row);
|
||||||
|
void trigger_destructors(container & container, std::uint32_t row);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::size_t hash_;
|
std::size_t hash_;
|
||||||
|
|
@ -90,6 +92,7 @@ namespace psemek::ecs::detail
|
||||||
std::vector<std::type_index> non_copyable_components_;
|
std::vector<std::type_index> non_copyable_components_;
|
||||||
|
|
||||||
std::shared_ptr<std::vector<table_callback>> constructors_;
|
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 & data = entities[entity.id];
|
||||||
auto & iteration_data = data.table->get_iteration_data();
|
auto & iteration_data = data.table->get_iteration_data();
|
||||||
|
|
||||||
|
data.table->trigger_destructors(*this, data.row);
|
||||||
|
|
||||||
if (!iteration_data || iteration_data->current_row < data.row)
|
if (!iteration_data || iteration_data->current_row < data.row)
|
||||||
remove_row(*data.table, data.row, entities);
|
remove_row(*data.table, data.row, entities);
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ namespace psemek::ecs::detail
|
||||||
|
|
||||||
if (constructor_factory)
|
if (constructor_factory)
|
||||||
table->add_constructor(constructor_factory(entry.columns_indices));
|
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);
|
columns_ = std::move(columns);
|
||||||
|
|
||||||
constructors_ = std::make_shared<std::vector<table_callback>>();
|
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
|
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));
|
auto result = std::make_unique<table>(std::move(columns));
|
||||||
result->constructors_ = constructors_;
|
result->constructors_ = constructors_;
|
||||||
|
result->destructors_ = destructors_;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,12 +148,21 @@ namespace psemek::ecs::detail
|
||||||
constructors_->push_back(std::move(callback));
|
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)
|
void table::trigger_constructors(container & container, std::uint32_t row)
|
||||||
{
|
{
|
||||||
for (auto const & callback : *constructors_)
|
for (auto const & callback : *constructors_)
|
||||||
{
|
|
||||||
callback(container, *this, row);
|
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});
|
container.create(component_1{40}, component_2{200});
|
||||||
expect_equal(value, 40);
|
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