Helios Engine
A modular ECS based data-oriented C++23 game engine framework
Loading...
Searching...
No Matches
single_threaded.cpp
Go to the documentation of this file.
1#include <pch.hpp>
2
4
5#include <helios/assert.hpp>
6#include <helios/ecs/details/profile.hpp>
9
10#include <cstddef>
11
12namespace helios::ecs {
13
14void SingleThreadedExecutor::BuildGraph(Schedule& schedule, World& world) {
15 HELIOS_ECS_PROFILE_SCOPE_N("helios::ecs::SingleThreadedExecutor::Execute");
16
17 HELIOS_ASSERT(schedule.plan_.has_value(),
18 "SingleThreadedExecutor: schedule has no compiled plan!");
19
20 const auto& plan = *schedule.plan_;
21 const auto& execution_order = plan.execution_order;
22 if (execution_order.empty()) {
23 return;
24 }
25
26 const size_t size = execution_order.size();
27
28 task_graph_.Clear();
29 tasks_.clear();
30 tasks_.reserve(size);
31
32 for (size_t i = 0; i < size; ++i) {
33 tasks_.push_back(task_graph_.CreatePlaceholder());
34 }
35
36 for (size_t exec_idx = 0; exec_idx < size; ++exec_idx) {
37 const SystemId id = execution_order[exec_idx];
38
39 const auto it = plan.system_id_to_entry_idx.find(id.id);
40 if (it == plan.system_id_to_entry_idx.end()) {
41 tasks_[exec_idx].Work([]() {});
42 tasks_[exec_idx].Name("SyncPoint");
43 continue;
44 }
45
46 auto& entries = schedule.system_entries_;
47 const size_t entry_idx = it->second;
48 HELIOS_ASSERT(entry_idx < entries.size(),
49 "System index out of bounds in SingleThreadedExecutor!");
50
51 tasks_[exec_idx].Work([&world, &schedule, entry_idx, exec_idx]() {
52 auto& conditions = schedule.conditions_cache_;
53 if (exec_idx < conditions.size()) {
54 bool should_run = true;
55 for (RunConditionStorage* cond_storage : conditions[exec_idx]) {
56 HELIOS_ECS_PROFILE_SCOPE();
57 HELIOS_ECS_PROFILE_ZONE_NAME(cond_storage->name);
58 if (!cond_storage->run_condition(world, cond_storage->local_data)) {
59 should_run = false;
60 break;
61 }
62 }
63 if (!should_run) {
64 return;
65 }
66 }
67
68 auto& storage = schedule.system_entries_[entry_idx].storage;
69 HELIOS_ECS_PROFILE_SCOPE();
70 HELIOS_ECS_PROFILE_ZONE_NAME(storage.name);
71 storage.system(world, storage.local_data);
72 });
73
74 auto& storage = entries[entry_idx].storage;
75 tasks_[exec_idx].Name(storage.name);
76 }
77
78 task_graph_.Linearize(tasks_);
79}
80
82 BuildGraph(schedule, world);
83 future_ = executor_.get().Run(task_graph_);
84}
85
87 BuildGraph(schedule, world);
88
89 if (executor_.get().IsWorkerThread()) {
90 executor_.get().CoRun(task_graph_);
91 return;
92 }
93
94 executor_.get().Run(task_graph_).Wait();
95}
96
97} // namespace helios::ecs
#define HELIOS_ASSERT(condition,...)
Assertion macro that aborts execution in debug builds.
Definition assert.hpp:259
A collection of systems, sets, and run conditions with ordering constraints.
Definition schedule.hpp:182
void ExecuteAndWait(Schedule &schedule, World &world) override
Executes all systems in the schedule and blocks until completion.
void Execute(Schedule &schedule, World &world) override
Executes the schedule using the single-threaded executor.
The World class manages entities with their components and systems.
Definition world.hpp:39