co_ecs 0.9.0
Cobalt ECS
Loading...
Searching...
No Matches
stage.hpp
Go to the documentation of this file.
1#pragma once
2
4
5namespace co_ecs {
6
10using vector_of_executors_t = std::vector<std::unique_ptr<system_executor_interface>>;
11
12class stage_executor;
13class schedule;
14
22
25
29class stage {
30private:
31 using self_type = stage;
32
33public:
38 stage(schedule& schedule, std::string_view name = {}) : _schedule(schedule), _name(name) {
39 }
40
44 auto end_stage() noexcept -> schedule& {
45 return _schedule;
46 }
47
53 auto add_system(main_thread_execution_policty_t policy, auto&&... args) -> self_type& {
54 _main_thread_systems.emplace_back(into_system_interface(std::forward<decltype(args)>(args)...));
55 return *this;
56 }
57
62 auto add_system(auto&&... args) -> self_type& {
63 _systems.emplace_back(into_system_interface(std::forward<decltype(args)>(args)...));
64 return *this;
65 }
66
74 auto create_executor(registry& registry, void* user_context = nullptr) -> std::unique_ptr<stage_executor> {
75 std::vector<vector_of_executors_t> executors{};
76
77 while (!_systems.empty()) {
78 access_pattern_t access_pattern;
79 vector_of_executors_t& executor_set = executors.emplace_back();
80
81 for (size_t i = 0; i < _systems.size();) {
82 auto executor = _systems[i]->create_executor(registry, user_context);
83 auto system_access_pattern = executor->access_pattern();
84
85 if (!access_pattern.allows(system_access_pattern)) {
86 ++i;
87 continue;
88 }
89
90 access_pattern &= system_access_pattern;
91 executor_set.emplace_back(std::move(executor));
92 _systems.erase(_systems.begin() + i);
93 }
94 }
95
96 // Main thread systems
97 vector_of_executors_t main_thread_executors;
98 for (auto& system : _main_thread_systems) {
99 main_thread_executors.emplace_back(system->create_executor(registry, user_context));
100 }
101
102 return std::make_unique<stage_executor>(_name, std::move(executors), std::move(main_thread_executors));
103 }
104
105private:
111 template<typename F>
112 static auto into_system_interface(F&& func) -> std::unique_ptr<system_interface> {
113 return std::make_unique<system<F>>(std::forward<F>(func));
114 }
115
121 template<typename S>
122 static auto into_system_interface(std::unique_ptr<S> system) -> std::unique_ptr<system_interface> {
123 return system;
124 }
125
126private:
127 schedule& _schedule;
128 std::string_view _name;
129 std::vector<std::unique_ptr<system_interface>> _systems{};
130 std::vector<std::unique_ptr<system_interface>> _main_thread_systems{};
131};
132
137public:
138 using builder = stage;
139
145 explicit stage_executor(std::string_view name,
146 std::vector<vector_of_executors_t> executor_set,
147 vector_of_executors_t main_thread_executors) :
148 _executor_set(std::move(executor_set)), _main_thread_executors(std::move(main_thread_executors)), _name(name) {
149 }
150
152 void run() {
153 for (auto& executors : _executor_set) {
154 execute_batch(executors);
155 }
156 }
157
158private:
163 template<typename WorkBatch>
164 void execute_batch(WorkBatch&& work_batch) {
165 task_t* parent{};
166 thread_pool& _thread_pool = thread_pool::get();
167
168 for (auto& work_item : work_batch) {
169 auto task = _thread_pool.submit([&work_item]() { work_item->run(); }, parent);
170 if (!parent) {
171 parent = task;
172 }
173 }
174
175 // in the meantime execute main thread systems
176 for (auto& executor : _main_thread_executors) {
177 executor->run();
178 }
179
180 if (parent) {
181 _thread_pool.wait(parent);
182 }
183 }
184
185private:
186 std::vector<vector_of_executors_t> _executor_set;
187 vector_of_executors_t _main_thread_executors;
188 std::string_view _name;
189};
190
191
192} // namespace co_ecs
Class representing an access pattern for components.
Definition access.hpp:19
auto allows(const access_pattern_t &other) const noexcept -> bool
Checks if this access pattern allows another access pattern.
Definition access.hpp:44
Registry is a container for all our entities and components. Components are stored in continuously in...
Definition registry.hpp:13
Manages the execution of systems in different stages.
Definition schedule.hpp:15
Class representing a stage executor.
Definition stage.hpp:136
void run()
Runs all systems in the stage.
Definition stage.hpp:152
stage_executor(std::string_view name, std::vector< vector_of_executors_t > executor_set, vector_of_executors_t main_thread_executors)
Constructs a new stage executor.
Definition stage.hpp:145
Class representing a stage in the schedule.
Definition stage.hpp:29
auto create_executor(registry &registry, void *user_context=nullptr) -> std::unique_ptr< stage_executor >
Creates an executor for the stage.
Definition stage.hpp:74
auto end_stage() noexcept -> schedule &
Ends the current stage and returns the schedule.
Definition stage.hpp:44
stage(schedule &schedule, std::string_view name={})
Constructs a new stage object.
Definition stage.hpp:38
auto add_system(auto &&... args) -> self_type &
Adds a system to the stage.
Definition stage.hpp:62
auto add_system(main_thread_execution_policty_t policy, auto &&... args) -> self_type &
Adds a system to the main thread execution list.
Definition stage.hpp:53
Represents a task that can be executed, monitored for completion, and linked to a parent task.
Definition task.hpp:10
static thread_pool & get()
Get thread pool instance.
Definition thread_pool.hpp:264
Definition archetype.hpp:11
constexpr main_thread_execution_policty_t main_thread_execution_policy
Constant instance of the main thread execution policy.
Definition stage.hpp:24
std::vector< std::unique_ptr< system_executor_interface > > vector_of_executors_t
Vector of systems.
Definition stage.hpp:10
STL namespace.
Structure representing the main thread execution policy.
Definition stage.hpp:18
main_thread_execution_policty_t()=default
Default constructor.