Support RAII-wrapping the execution of an ECS system into some context (e.g. for profiling)

This commit is contained in:
Nikita Lisitsa 2025-04-13 17:36:43 +03:00
parent c75809aa75
commit 93aa697347

View file

@ -7,6 +7,19 @@
namespace psemek::ecs namespace psemek::ecs
{ {
namespace detail
{
struct default_context_factory
{
int operator()() const noexcept
{
return 0;
}
};
}
struct dispatcher struct dispatcher
{ {
dispatcher() = default; dispatcher() = default;
@ -42,12 +55,14 @@ namespace psemek::ecs
}); });
} }
template <typename Event, typename ... Components, typename System> template <typename Event, typename ... Components, typename System, typename ContextFactory = detail::default_context_factory>
void system(System system) void system(System system, ContextFactory && context_factory = ContextFactory{})
{ {
handlers_[Event::uuid()].push_back([system = std::move(system), this, cache = container_->cache<Components...>()](void const * event_ptr) mutable { handlers_[Event::uuid()].push_back([system = std::move(system), this, cache = container_->cache<Components...>(), context_factory = std::move(context_factory)](void const * event_ptr) mutable {
auto const & event = *reinterpret_cast<Event const *>(event_ptr); auto const & event = *reinterpret_cast<Event const *>(event_ptr);
[[maybe_unused]] auto context = context_factory();
container_->apply<Components...>([&]<typename ... FilteredComponents>(ecs::container & container, ecs::handle entity, FilteredComponents & ... filtered_components){ container_->apply<Components...>([&]<typename ... FilteredComponents>(ecs::container & container, ecs::handle entity, FilteredComponents & ... filtered_components){
if constexpr (std::invocable<System, Event const &, ecs::container &, handle, FilteredComponents & ...>) if constexpr (std::invocable<System, Event const &, ecs::container &, handle, FilteredComponents & ...>)
{ {