diff --git a/libs/ecs/include/psemek/ecs/system_set.hpp b/libs/ecs/include/psemek/ecs/system_set.hpp new file mode 100644 index 00000000..41376039 --- /dev/null +++ b/libs/ecs/include/psemek/ecs/system_set.hpp @@ -0,0 +1,92 @@ +#pragma once + +#include + +#include + +#include + +namespace psemek::ecs +{ + + struct system_set + { + /** Add a function to this system set. + * + * When `system_set::apply()` is called, this function is applied to + * the container by calling `container.apply(function)`. + * + * The system set automatically manages the query cache for this function. + * + * @tparam Components The component types, as in `container::apply` + * @param function The function to be applied to a container + */ + template + void add(Function && function); + + /** Add a batch function to this system set. + * + * When `system_set::apply()` is called, this function is applied to + * the container by calling `container.batch_apply(function)`. + * + * The system set automatically manages the query cache for this function. + * + * @tparam Components The component types, as in `container::apply` + * @param function The function to be applied to a container + */ + template + void add_batch(Function && function); + + /** Apply this system set to a container. + * + * The functions added to the set via `add` or `add_batch` are applied + * to the container in the order in which they were added. + * + * @param container The container to apply the system set to + */ + void apply(container & container); + + /** Clear this system set, removing all previously added functions. + */ + void clear(); + + private: + + struct system_data + { + util::function apply; + query_cache cache = nullptr; + }; + + std::vector systems_; + }; + + template + void system_set::add(Function && function) + { + systems_.push_back({[function = std::move(function)](container & container, query_cache cache) -> query_cache { + return container.apply(function, cache); + }}); + } + + template + void system_set::add_batch(Function && function) + { + systems_.push_back({[function = std::move(function)](container & container, query_cache cache) -> query_cache { + return container.batch_apply(function, cache); + }}); + } + + inline void system_set::apply(container & container) + { + for (auto & system : systems_) + system.cache = system.apply(container, system.cache); + } + + inline void system_set::clear() + { + systems_.clear(); + } + + +}