Fix constructors & destructors order
Order of callbacks was affected by the order of caches, which are pretty much arbitrary. For a fix, explicitly order the callbacks globally per-world.
This commit is contained in:
parent
fad1580379
commit
80b4cc938d
5 changed files with 44 additions and 19 deletions
|
|
@ -403,6 +403,9 @@ namespace psemek::ecs
|
|||
detail::component_registry component_registry_;
|
||||
detail::index_container index_container_;
|
||||
|
||||
int next_constructor_id_ = 0;
|
||||
int next_destructor_id_ = 0;
|
||||
|
||||
util::object_pool<std::vector<util::uuid>> uuid_list_pool_;
|
||||
util::object_pool<util::hash_set<util::uuid>> uuid_set_pool_;
|
||||
|
||||
|
|
@ -655,6 +658,8 @@ namespace psemek::ecs
|
|||
|
||||
static_assert(invocable_type::value, "function is not invocable with these components");
|
||||
|
||||
auto id = next_constructor_id_++;
|
||||
|
||||
auto constructor_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, util::hash_set<util::uuid> const & attached_components, bool force){
|
||||
|
||||
|
|
@ -674,9 +679,9 @@ namespace psemek::ecs
|
|||
|
||||
query_cache cache = this->cache<Components...>();
|
||||
|
||||
cache->constructor_factories.push_back(constructor_factory);
|
||||
cache->constructor_factories.push_back([id, constructor_factory](auto const & ... args){ return detail::ordered_table_callback{id, constructor_factory(args...)}; });
|
||||
for (auto const & entry : cache->entries)
|
||||
entry.table->add_constructor(constructor_factory(entry.columns_indices));
|
||||
entry.table->add_constructor({id, constructor_factory(entry.columns_indices)});
|
||||
}
|
||||
|
||||
template <typename ... Components, typename Function>
|
||||
|
|
@ -688,6 +693,8 @@ namespace psemek::ecs
|
|||
|
||||
static_assert(invocable_type::value, "function is not invocable with these components");
|
||||
|
||||
auto id = next_destructor_id_++;
|
||||
|
||||
auto 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, util::hash_set<util::uuid> const & detached_components, bool force){
|
||||
|
||||
|
|
@ -707,9 +714,9 @@ namespace psemek::ecs
|
|||
|
||||
query_cache cache = this->cache<Components...>();
|
||||
|
||||
cache->destructor_factories.push_back(destructor_factory);
|
||||
cache->destructor_factories.push_back([id, destructor_factory](auto const & ... args){ return detail::ordered_table_callback{id, destructor_factory(args...)}; });
|
||||
for (auto const & entry : cache->entries)
|
||||
entry.table->add_destructor(destructor_factory(entry.columns_indices));
|
||||
entry.table->add_destructor({id, destructor_factory(entry.columns_indices)});
|
||||
}
|
||||
|
||||
template <typename Index, typename ... Args>
|
||||
|
|
|
|||
|
|
@ -18,6 +18,22 @@ namespace psemek::ecs
|
|||
|
||||
using table_callback = util::function<void(container &, table &, std::uint32_t, util::hash_set<util::uuid> const &, bool)>;
|
||||
|
||||
struct ordered_table_callback
|
||||
{
|
||||
int id;
|
||||
table_callback callback;
|
||||
|
||||
friend auto operator <=> (ordered_table_callback const & c1, ordered_table_callback const & c2)
|
||||
{
|
||||
return c1.id <=> c2.id;
|
||||
}
|
||||
|
||||
friend bool operator == (ordered_table_callback const & c1, ordered_table_callback const & c2)
|
||||
{
|
||||
return c1.id == c2.id;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace psemek::ecs::detail
|
|||
|
||||
std::list<query_cache_entry> entries;
|
||||
|
||||
using callback_factory = util::function<table_callback(std::vector<std::uint32_t> const &)>;
|
||||
using callback_factory = util::function<ordered_table_callback(std::vector<std::uint32_t> const &)>;
|
||||
|
||||
std::vector<callback_factory> constructor_factories;
|
||||
std::vector<callback_factory> destructor_factories;
|
||||
|
|
|
|||
|
|
@ -70,8 +70,8 @@ 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 add_constructor(ordered_table_callback callback);
|
||||
void add_destructor(ordered_table_callback callback);
|
||||
|
||||
void trigger_constructors(container & container, std::uint32_t row);
|
||||
void trigger_constructors(container & container, std::uint32_t row, util::hash_set<util::uuid> const & attached_components);
|
||||
|
|
@ -97,8 +97,8 @@ 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_;
|
||||
std::shared_ptr<std::vector<ordered_table_callback>> constructors_;
|
||||
std::shared_ptr<std::vector<ordered_table_callback>> destructors_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ namespace psemek::ecs::detail
|
|||
|
||||
columns_ = std::move(columns);
|
||||
|
||||
constructors_ = std::make_shared<std::vector<table_callback>>();
|
||||
destructors_ = std::make_shared<std::vector<table_callback>>();
|
||||
constructors_ = std::make_shared<std::vector<ordered_table_callback>>();
|
||||
destructors_ = std::make_shared<std::vector<ordered_table_callback>>();
|
||||
}
|
||||
|
||||
std::optional<std::size_t> table::column_index(util::uuid const & uuid) const
|
||||
|
|
@ -144,38 +144,40 @@ namespace psemek::ecs::detail
|
|||
return non_copyable_components_;
|
||||
}
|
||||
|
||||
void table::add_constructor(table_callback callback)
|
||||
void table::add_constructor(ordered_table_callback callback)
|
||||
{
|
||||
constructors_->push_back(std::move(callback));
|
||||
auto it = std::upper_bound(constructors_->begin(), constructors_->end(), callback);
|
||||
constructors_->insert(it, std::move(callback));
|
||||
}
|
||||
|
||||
void table::add_destructor(table_callback callback)
|
||||
void table::add_destructor(ordered_table_callback callback)
|
||||
{
|
||||
destructors_->push_back(std::move(callback));
|
||||
auto it = std::upper_bound(destructors_->begin(), destructors_->end(), callback);
|
||||
destructors_->insert(it, std::move(callback));
|
||||
}
|
||||
|
||||
void table::trigger_constructors(container & container, std::uint32_t row)
|
||||
{
|
||||
for (auto const & callback : *constructors_)
|
||||
callback(container, *this, row, column_uuid_set_, true);
|
||||
callback.callback(container, *this, row, column_uuid_set_, true);
|
||||
}
|
||||
|
||||
void table::trigger_constructors(container & container, std::uint32_t row, util::hash_set<util::uuid> const & attached_components)
|
||||
{
|
||||
for (auto const & callback : *constructors_)
|
||||
callback(container, *this, row, attached_components, false);
|
||||
callback.callback(container, *this, row, attached_components, false);
|
||||
}
|
||||
|
||||
void table::trigger_destructors(container & container, std::uint32_t row)
|
||||
{
|
||||
for (auto const & callback : *destructors_)
|
||||
callback(container, *this, row, column_uuid_set_, true);
|
||||
callback.callback(container, *this, row, column_uuid_set_, true);
|
||||
}
|
||||
|
||||
void table::trigger_destructors(container & container, std::uint32_t row, util::hash_set<util::uuid> const & detached_components)
|
||||
{
|
||||
for (auto const & callback : *destructors_)
|
||||
callback(container, *this, row, detached_components, false);
|
||||
callback.callback(container, *this, row, detached_components, false);
|
||||
}
|
||||
|
||||
std::size_t table::memory_usage() const
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue