Helios Engine 0.1.0
A modular ECS based data-oriented C++23 game engine
 
Loading...
Searching...
No Matches
schedules.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <helios/core_pch.hpp>
4
6
7#include <array>
8#include <string_view>
9
10namespace helios::app {
11
12//==============================================================================
13// STAGE SCHEDULES (Hardcoded)
14//==============================================================================
15// These are the four core execution stages that establish the application lifecycle.
16// All other schedules are executed within these stages based on Before/After relationships.
17
18/**
19 * @brief StartUpStage - application initialization phase.
20 * @details This is the first stage executed during application initialization.
21 * Runs once at application start. Systems in this stage initialize resources,
22 * load configuration, and prepare the application for the main loop.
23 *
24 * Schedules in this stage: PreStartup, Startup, PostStartup
25 */
27 static constexpr bool IsStage() noexcept { return true; }
28 static constexpr std::string_view GetName() noexcept { return "StartUpStage"; }
29};
30
31/**
32 * @brief MainStage - main thread execution phase.
33 * @details Executes synchronously on the main thread for tasks that require
34 * main thread context (e.g., window events, input polling).
35 * This stage runs on every frame before the UpdateStage.
36 *
37 * Schedules in this stage: Main
38 */
39struct MainStage {
40 static constexpr bool IsStage() noexcept { return true; }
41 static constexpr std::string_view GetName() noexcept { return "MainStage"; }
42};
43
44/**
45 * @brief UpdateStage - main update logic phase.
46 * @details This is where most game/simulation logic runs on every frame.
47 * Executes after MainStage and can run systems in parallel on worker threads.
48 *
49 * Schedules in this stage: First, PreUpdate, Update, PostUpdate, Last
50 */
52 static constexpr bool IsStage() noexcept { return true; }
53 static constexpr std::string_view GetName() noexcept { return "UpdateStage"; }
54};
55
56/**
57 * @brief CleanUpStage - cleanup/shutdown phase.
58 * @details This is the final stage executed during application shutdown.
59 * Runs once at application exit. Systems in this stage release resources,
60 * save state, and perform cleanup operations.
61 *
62 * Schedules in this stage: PreCleanUp, CleanUp, PostCleanUp
63 */
65 static constexpr bool IsStage() noexcept { return true; }
66 static constexpr std::string_view GetName() noexcept { return "CleanUpStage"; }
67};
68
69//==============================================================================
70// STARTUP STAGE SCHEDULES
71//==============================================================================
72
73// Forward declarations
74struct PreStartup;
75struct Startup;
76struct PostStartup;
77
78/**
79 * @brief PreStartup schedule - runs before startup initialization.
80 * @details First schedule in the StartUpStage.
81 * Used for early initialization tasks that must complete before main startup.
82 * Executes: Before(Startup)
83 */
84struct PreStartup {
85 static constexpr ScheduleId GetStage() noexcept { return ScheduleIdOf<StartUpStage>(); }
86 static constexpr auto Before() noexcept -> std::array<ScheduleId, 1>;
87 static constexpr auto After() noexcept -> std::array<ScheduleId, 0> { return {}; }
88 static constexpr std::string_view GetName() noexcept { return "PreStartup"; }
89};
90
91/**
92 * @brief Startup schedule - main initialization.
93 * @details Main initialization schedule in the StartUpStage.
94 * Used for setting up systems and resources.
95 * Executes: After(PreStartup) and Before(PostStartup)
96 */
97struct Startup {
98 static constexpr ScheduleId GetStage() noexcept { return ScheduleIdOf<StartUpStage>(); }
99 static constexpr auto Before() noexcept -> std::array<ScheduleId, 1>;
100 static constexpr auto After() noexcept -> std::array<ScheduleId, 1> { return {ScheduleIdOf<PreStartup>()}; }
101 static constexpr std::string_view GetName() noexcept { return "Startup"; }
102};
103
104/**
105 * @brief PostStartup schedule - runs after startup initialization.
106 * @details Final schedule in the StartUpStage.
107 * Used for tasks that depend on main startup completion.
108 * Executes: After(Startup)
109 */
111 static constexpr ScheduleId GetStage() noexcept { return ScheduleIdOf<StartUpStage>(); }
112 static constexpr auto Before() noexcept -> std::array<ScheduleId, 0> { return {}; }
113 static constexpr auto After() noexcept -> std::array<ScheduleId, 1> { return {ScheduleIdOf<Startup>()}; }
114 static constexpr std::string_view GetName() noexcept { return "PostStartup"; }
115};
116
117constexpr auto PreStartup::Before() noexcept -> std::array<ScheduleId, 1> {
118 return {ScheduleIdOf<Startup>()};
119}
120
121constexpr auto Startup::Before() noexcept -> std::array<ScheduleId, 1> {
122 return {ScheduleIdOf<PostStartup>()};
123}
124
125//==============================================================================
126// MAIN STAGE SCHEDULES
127//==============================================================================
128
129/**
130 * @brief Main schedule - main thread execution.
131 * @details Main schedule in the MainStage (executes every frame).
132 * Used for tasks that must run on the main thread.
133 * Examples: window event handling, input polling, main thread UI updates.
134 */
135struct Main {
136 static constexpr ScheduleId GetStage() noexcept { return ScheduleIdOf<MainStage>(); }
137 static constexpr auto Before() noexcept -> std::array<ScheduleId, 0> { return {}; }
138 static constexpr auto After() noexcept -> std::array<ScheduleId, 0> { return {}; }
139 static constexpr std::string_view GetName() noexcept { return "Main"; }
140};
141
142//==============================================================================
143// UPDATE STAGE SCHEDULES
144//==============================================================================
145
146// Forward declarations for Update stage schedules
147struct First;
148struct PreUpdate;
149struct Update;
150struct PostUpdate;
151struct Last;
152
153/**
154 * @brief First schedule - runs first in the UpdateStage.
155 * @details First schedule in the UpdateStage (executes every frame).
156 * Runs after the MainStage and before PreUpdate.
157 * Used for tasks that need to run at the very beginning of the update phase.
158 * Executes: Before(PreUpdate)
159 */
160struct First {
161 static constexpr ScheduleId GetStage() noexcept { return ScheduleIdOf<UpdateStage>(); }
162 static constexpr auto Before() noexcept -> std::array<ScheduleId, 1>;
163 static constexpr auto After() noexcept -> std::array<ScheduleId, 0> { return {}; }
164 static constexpr std::string_view GetName() noexcept { return "First"; }
165};
166
167/**
168 * @brief PreUpdate schedule - runs before the main update.
169 * @details Runs after First schedule in the UpdateStage (executes every frame).
170 * Used for pre-processing tasks that must complete before main update logic.
171 * Executes: After(First) and Before(Update)
172 */
173struct PreUpdate {
174 static constexpr ScheduleId GetStage() noexcept { return ScheduleIdOf<UpdateStage>(); }
175 static constexpr auto Before() noexcept -> std::array<ScheduleId, 1>;
176 static constexpr auto After() noexcept -> std::array<ScheduleId, 1> { return {ScheduleIdOf<First>()}; }
177 static constexpr std::string_view GetName() noexcept { return "PreUpdate"; }
178};
179
180/**
181 * @brief Update schedule - main update logic.
182 * @details Main update schedule in the UpdateStage (executes every frame).
183 * Used for core game/simulation logic.
184 * Executes: After(PreUpdate) and Before(PostUpdate)
185 */
186struct Update {
187 static constexpr ScheduleId GetStage() noexcept { return ScheduleIdOf<UpdateStage>(); }
188 static constexpr auto Before() noexcept -> std::array<ScheduleId, 1>;
189 static constexpr auto After() noexcept -> std::array<ScheduleId, 1> { return {ScheduleIdOf<PreUpdate>()}; }
190 static constexpr std::string_view GetName() noexcept { return "Update"; }
191};
192
193/**
194 * @brief PostUpdate schedule - runs after the main update.
195 * @details Runs after Update schedule in the UpdateStage (executes every frame).
196 * Used for post-processing tasks after main update logic.
197 * Examples: physics cleanup, constraint resolution, late transforms, data extraction.
198 * Executes: After(Update) and Before(Last)
199 */
201 static constexpr ScheduleId GetStage() noexcept { return ScheduleIdOf<UpdateStage>(); }
202 static constexpr auto Before() noexcept -> std::array<ScheduleId, 1>;
203 static constexpr auto After() noexcept -> std::array<ScheduleId, 1> { return {ScheduleIdOf<Update>()}; }
204 static constexpr std::string_view GetName() noexcept { return "PostUpdate"; }
205};
206
207/**
208 * @brief Last schedule - runs last in the UpdateStage.
209 * @details Final schedule in the UpdateStage (executes every frame).
210 * Runs after PostUpdate and before the CleanUpStage.
211 * Used for tasks that need to run at the very end of the update phase.
212 * Executes: After(PostUpdate)
213 */
214struct Last {
215 static constexpr ScheduleId GetStage() noexcept { return ScheduleIdOf<UpdateStage>(); }
216 static constexpr auto Before() noexcept -> std::array<ScheduleId, 0> { return {}; }
217 static constexpr auto After() noexcept -> std::array<ScheduleId, 1> { return {ScheduleIdOf<PostUpdate>()}; }
218 static constexpr std::string_view GetName() noexcept { return "Last"; }
219};
220
221// Define deferred Before() implementations for Update stage schedules
222constexpr auto First::Before() noexcept -> std::array<ScheduleId, 1> {
223 return {ScheduleIdOf<PreUpdate>()};
224}
225
226constexpr auto PreUpdate::Before() noexcept -> std::array<ScheduleId, 1> {
227 return {ScheduleIdOf<Update>()};
228}
229
230constexpr auto Update::Before() noexcept -> std::array<ScheduleId, 1> {
231 return {ScheduleIdOf<PostUpdate>()};
232}
233
234constexpr auto PostUpdate::Before() noexcept -> std::array<ScheduleId, 1> {
235 return {ScheduleIdOf<Last>()};
236}
237
238//==============================================================================
239// CLEANUP STAGE SCHEDULES
240//==============================================================================
241
242/**
243 * @brief CleanUp schedule - main cleanup.
244 * @details Main cleanup schedule in the CleanUpStage.
245 * Used for releasing resources and shutting down systems.
246 * Executes: After(PreCleanUp) and Before(PostCleanUp)
247 */
248struct CleanUp {
249 static constexpr ScheduleId GetStage() noexcept { return ScheduleIdOf<CleanUpStage>(); }
250 static constexpr auto Before() noexcept -> std::array<ScheduleId, 0> { return {}; }
251 static constexpr auto After() noexcept -> std::array<ScheduleId, 0> { return {}; }
252 static constexpr std::string_view GetName() noexcept { return "CleanUp"; }
253};
254
255/**
256 * @brief PreCleanUp schedule - runs before cleanup/shutdown.
257 * @details First schedule in the CleanUpStage.
258 * Used for tasks that must run before main cleanup.
259 * Examples: saving state, flushing caches, disconnecting from servers.
260 * Executes: Before(CleanUp)
261 */
263 static constexpr ScheduleId GetStage() noexcept { return ScheduleIdOf<CleanUpStage>(); }
264 static constexpr auto Before() noexcept -> std::array<ScheduleId, 1> { return {ScheduleIdOf<CleanUp>()}; }
265 static constexpr auto After() noexcept -> std::array<ScheduleId, 0> { return {}; }
266 static constexpr std::string_view GetName() noexcept { return "PreCleanUp"; }
267};
268
269/**
270 * @brief PostCleanUp schedule - runs after cleanup/shutdown.
271 * @details Final schedule in the CleanUpStage.
272 * Used for tasks that must run after main cleanup.
273 * Examples: final resource deallocation, logger shutdown, profiler finalization.
274 * Executes: After(CleanUp)
275 */
277 static constexpr ScheduleId GetStage() noexcept { return ScheduleIdOf<CleanUpStage>(); }
278 static constexpr auto Before() noexcept -> std::array<ScheduleId, 0> { return {}; }
279 static constexpr auto After() noexcept -> std::array<ScheduleId, 1> { return {ScheduleIdOf<CleanUp>()}; }
280 static constexpr std::string_view GetName() noexcept { return "PostCleanUp"; }
281};
282
283/**
284 * @brief Constexpr instances of schedules for easier user interface.
285 * @details These instances can be used directly without having to construct the schedule types.
286 *
287 * @example
288 * @code
289 * scheduler.AddSystem(kPreStartup, my_system);
290 * @endcode
291 */
292
293inline constexpr Main kMain{};
294
295inline constexpr PreStartup kPreStartup{};
296inline constexpr Startup kStartup{};
297inline constexpr PostStartup kPostStartup{};
298
299inline constexpr First kFirst{};
300inline constexpr PreUpdate kPreUpdate{};
301inline constexpr Update kUpdate{};
302inline constexpr PostUpdate kPostUpdate{};
303inline constexpr Last kLast{};
304
305inline constexpr PreCleanUp kPreCleanUp{};
306inline constexpr CleanUp kCleanUp{};
307inline constexpr PostCleanUp kPostCleanUp{};
308
309} // namespace helios::app
constexpr PostUpdate kPostUpdate
constexpr PostCleanUp kPostCleanUp
constexpr Startup kStartup
constexpr Last kLast
constexpr Update kUpdate
constexpr CleanUp kCleanUp
constexpr PreStartup kPreStartup
constexpr PreCleanUp kPreCleanUp
constexpr PreUpdate kPreUpdate
constexpr First kFirst
size_t ScheduleId
Type alias for schedule type IDs.
Definition schedule.hpp:20
constexpr PostStartup kPostStartup
constexpr Main kMain
STL namespace.
CleanUpStage - cleanup/shutdown phase.
Definition schedules.hpp:64
static constexpr std::string_view GetName() noexcept
Definition schedules.hpp:66
static constexpr bool IsStage() noexcept
Definition schedules.hpp:65
CleanUp schedule - main cleanup.
static constexpr std::string_view GetName() noexcept
static constexpr ScheduleId GetStage() noexcept
static constexpr auto Before() noexcept -> std::array< ScheduleId, 0 >
static constexpr auto After() noexcept -> std::array< ScheduleId, 0 >
First schedule - runs first in the UpdateStage.
static constexpr auto After() noexcept -> std::array< ScheduleId, 0 >
static constexpr std::string_view GetName() noexcept
static constexpr auto Before() noexcept -> std::array< ScheduleId, 1 >
static constexpr ScheduleId GetStage() noexcept
Last schedule - runs last in the UpdateStage.
static constexpr auto After() noexcept -> std::array< ScheduleId, 1 >
static constexpr std::string_view GetName() noexcept
static constexpr auto Before() noexcept -> std::array< ScheduleId, 0 >
static constexpr ScheduleId GetStage() noexcept
MainStage - main thread execution phase.
Definition schedules.hpp:39
static constexpr bool IsStage() noexcept
Definition schedules.hpp:40
static constexpr std::string_view GetName() noexcept
Definition schedules.hpp:41
Main schedule - main thread execution.
static constexpr ScheduleId GetStage() noexcept
static constexpr auto Before() noexcept -> std::array< ScheduleId, 0 >
static constexpr auto After() noexcept -> std::array< ScheduleId, 0 >
static constexpr std::string_view GetName() noexcept
PostCleanUp schedule - runs after cleanup/shutdown.
static constexpr auto After() noexcept -> std::array< ScheduleId, 1 >
static constexpr ScheduleId GetStage() noexcept
static constexpr std::string_view GetName() noexcept
static constexpr auto Before() noexcept -> std::array< ScheduleId, 0 >
PostStartup schedule - runs after startup initialization.
static constexpr auto After() noexcept -> std::array< ScheduleId, 1 >
static constexpr ScheduleId GetStage() noexcept
static constexpr auto Before() noexcept -> std::array< ScheduleId, 0 >
static constexpr std::string_view GetName() noexcept
PostUpdate schedule - runs after the main update.
static constexpr ScheduleId GetStage() noexcept
static constexpr auto Before() noexcept -> std::array< ScheduleId, 1 >
static constexpr auto After() noexcept -> std::array< ScheduleId, 1 >
static constexpr std::string_view GetName() noexcept
PreCleanUp schedule - runs before cleanup/shutdown.
static constexpr ScheduleId GetStage() noexcept
static constexpr auto After() noexcept -> std::array< ScheduleId, 0 >
static constexpr auto Before() noexcept -> std::array< ScheduleId, 1 >
static constexpr std::string_view GetName() noexcept
PreStartup schedule - runs before startup initialization.
Definition schedules.hpp:84
static constexpr auto Before() noexcept -> std::array< ScheduleId, 1 >
static constexpr ScheduleId GetStage() noexcept
Definition schedules.hpp:85
static constexpr auto After() noexcept -> std::array< ScheduleId, 0 >
Definition schedules.hpp:87
static constexpr std::string_view GetName() noexcept
Definition schedules.hpp:88
PreUpdate schedule - runs before the main update.
static constexpr std::string_view GetName() noexcept
static constexpr auto Before() noexcept -> std::array< ScheduleId, 1 >
static constexpr auto After() noexcept -> std::array< ScheduleId, 1 >
static constexpr ScheduleId GetStage() noexcept
StartUpStage - application initialization phase.
Definition schedules.hpp:26
static constexpr std::string_view GetName() noexcept
Definition schedules.hpp:28
static constexpr bool IsStage() noexcept
Definition schedules.hpp:27
Startup schedule - main initialization.
Definition schedules.hpp:97
static constexpr auto After() noexcept -> std::array< ScheduleId, 1 >
static constexpr ScheduleId GetStage() noexcept
Definition schedules.hpp:98
static constexpr std::string_view GetName() noexcept
static constexpr auto Before() noexcept -> std::array< ScheduleId, 1 >
UpdateStage - main update logic phase.
Definition schedules.hpp:51
static constexpr std::string_view GetName() noexcept
Definition schedules.hpp:53
static constexpr bool IsStage() noexcept
Definition schedules.hpp:52
Update schedule - main update logic.
static constexpr auto Before() noexcept -> std::array< ScheduleId, 1 >
static constexpr auto After() noexcept -> std::array< ScheduleId, 1 >
static constexpr ScheduleId GetStage() noexcept
static constexpr std::string_view GetName() noexcept