Helios Engine 0.1.0
A modular ECS based data-oriented C++23 game engine
 
Loading...
Searching...
No Matches
schedule.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <helios/core_pch.hpp>
4
5#include <ctti/name.hpp>
6#include <ctti/type_id.hpp>
7
8#include <array>
9#include <concepts>
10#include <cstddef>
11#include <string_view>
12#include <type_traits>
13
14namespace helios::app {
15
16/**
17 * @brief Type alias for schedule type IDs.
18 * @details Used to uniquely identify schedule types at runtime.
19 */
20using ScheduleId = size_t;
21
22/**
23 * @brief Trait to identify valid schedule types.
24 * @details A valid schedule type must be an empty struct or class.
25 * This ensures schedules are zero-cost type markers with no runtime overhead.
26 * @tparam T Type to check
27 *
28 * @example
29 * @code
30 * struct MySchedule {}; // Valid - empty type
31 * static_assert(ScheduleTrait<MySchedule>);
32 * @endcode
33 */
34template <typename T>
35concept ScheduleTrait = std::is_empty_v<std::remove_cvref_t<T>>;
36
37/**
38 * @brief Trait to identify schedules with custom names.
39 * @details A schedule with name trait must satisfy ScheduleTrait and provide:
40 * - `static constexpr std::string_view GetName() noexcept`
41 *
42 * @tparam T Type to check
43 *
44 * @example
45 * @code
46 * struct MySchedule {
47 * static constexpr std::string_view GetName() noexcept { return "MySchedule"; }
48 * };
49 * static_assert(ScheduleWithNameTrait<MySchedule>);
50 * @endcode
51 */
52template <typename T>
54 { T::GetName() } -> std::same_as<std::string_view>;
55};
56
57/**
58 * @brief Gets unique type ID for a schedule type.
59 * @details Uses CTTI to generate a unique hash for the schedule type.
60 * The ID is consistent across compilation units.
61 * @tparam T Schedule type
62 * @return Unique type ID for the schedule
63 *
64 * @example
65 * @code
66 * struct UpdateSchedule {};
67 * constexpr ScheduleId id = ScheduleIdOf<UpdateSchedule>();
68 * @endcode
69 */
70template <ScheduleTrait T>
71constexpr ScheduleId ScheduleIdOf() noexcept {
72 return ctti::type_index_of<T>().hash();
73}
74
75/**
76 * @brief Gets the name of a schedule type.
77 * @details Returns the custom name if GetName() is provided, otherwise returns the CTTI-generated type name.
78 * @tparam T Schedule type
79 * @return Name of the schedule
80 *
81 * @example
82 * @code
83 * struct Update {
84 * static constexpr std::string_view GetName() noexcept { return "Update"; }
85 * };
86 * constexpr auto name = ScheduleNameOf<Update>(); // "Update"
87 * @endcode
88 */
89template <ScheduleTrait T>
90constexpr std::string_view ScheduleNameOf() noexcept {
91 if constexpr (ScheduleWithNameTrait<T>) {
92 return T::GetName();
93 } else {
94 return ctti::name_of<T>();
95 }
96}
97
98/**
99 * @brief Concept for schedules that provide Before() ordering constraints.
100 * @details A schedule with Before trait must provide:
101 * - `static constexpr auto Before() noexcept -> std::array<ScheduleId, N>` or similar span-like type
102 */
103template <typename T>
105 { T::Before() };
106};
107
108/**
109 * @brief Concept for schedules that provide After() ordering constraints.
110 * @details A schedule with After trait must provide:
111 * - `static constexpr auto After() noexcept -> std::array<ScheduleId, N>` or similar span-like type
112 */
113template <typename T>
115 { T::After() };
116};
117
118/**
119 * @brief Gets the Before() ordering constraints for a schedule.
120 * @details Returns schedules that must run before this schedule.
121 * If the schedule doesn't provide Before(), returns empty array.
122 * @tparam T Schedule type
123 * @return Array of schedule IDs that must run before T
124 */
125template <ScheduleTrait T>
126constexpr auto ScheduleBeforeOf() noexcept {
127 if constexpr (ScheduleWithBeforeTrait<T>) {
128 return T::Before();
129 } else {
130 return std::array<ScheduleId, 0>{};
131 }
132}
133
134/**
135 * @brief Gets the After() ordering constraints for a schedule.
136 * @details Returns schedules that must run after this schedule.
137 * If the schedule doesn't provide After(), returns empty array.
138 * @tparam T Schedule type
139 * @return Array of schedule IDs that must run after T
140 */
141template <ScheduleTrait T>
142constexpr auto ScheduleAfterOf() noexcept {
143 if constexpr (ScheduleWithAfterTrait<T>) {
144 return T::After();
145 } else {
146 return std::array<ScheduleId, 0>{};
147 }
148}
149
150/**
151 * @brief Concept for schedules that declare stage membership.
152 * @details A schedule with stage trait must provide:
153 * - `static constexpr ScheduleId GetStage() noexcept`
154 *
155 * This indicates which stage the schedule belongs to for execution grouping.
156 *
157 * @tparam T Type to check
158 */
159template <typename T>
161 { T::GetStage() } -> std::same_as<ScheduleId>;
162};
163
164/**
165 * @brief Concept for schedules that represent stages.
166 * @details A stage schedule must provide:
167 * - `static constexpr bool IsStage() noexcept` that returns true
168 *
169 * Stages are the four core execution phases: StartUp, Main, Update, CleanUp
170 * All other schedules are executed within these stages based on Before/After relationships.
171 *
172 * @tparam T Type to check
173 */
174template <typename T>
175concept StageTrait = ScheduleTrait<T> && requires {
176 { T::IsStage() } -> std::same_as<bool>;
177};
178
179/**
180 * @brief Checks if a schedule type is a stage.
181 * @tparam T Schedule type
182 * @return True if the schedule is a stage, false otherwise
183 */
184template <ScheduleTrait T>
185constexpr bool IsStage() noexcept {
186 if constexpr (StageTrait<T>) {
187 return T::IsStage();
188 } else {
189 return false;
190 }
191}
192
193/**
194 * @brief Gets the stage ID that a schedule belongs to.
195 * @details If the schedule declares a stage via GetStage(), returns that stage ID.
196 * If the schedule is itself a stage, returns its own ID.
197 * Otherwise, returns 0 to indicate it's not associated with any stage.
198 *
199 * @tparam T Schedule type
200 * @return Stage ID that this schedule belongs to, or 0 if not in a stage
201 */
202template <ScheduleTrait T>
203constexpr ScheduleId ScheduleStageOf() noexcept {
204 if constexpr (ScheduleWithStageTrait<T>) {
205 return T::GetStage();
206 } else if constexpr (IsStage<T>()) {
207 return ScheduleIdOf<T>();
208 } else {
209 return 0;
210 }
211}
212
213} // namespace helios::app
Concept for schedules that provide After() ordering constraints.
Definition schedule.hpp:114
Concept for schedules that provide Before() ordering constraints.
Definition schedule.hpp:104
Concept for schedules that declare stage membership.
Definition schedule.hpp:160
Concept for schedules that represent stages.
Definition schedule.hpp:175
constexpr bool IsStage() noexcept
Checks if a schedule type is a stage.
Definition schedule.hpp:185
constexpr auto ScheduleBeforeOf() noexcept
Gets the Before() ordering constraints for a schedule.
Definition schedule.hpp:126
constexpr ScheduleId ScheduleStageOf() noexcept
Gets the stage ID that a schedule belongs to.
Definition schedule.hpp:203
constexpr std::string_view ScheduleNameOf() noexcept
Definition schedule.hpp:90
constexpr auto ScheduleAfterOf() noexcept
Gets the After() ordering constraints for a schedule.
Definition schedule.hpp:142
constexpr ScheduleId ScheduleIdOf() noexcept
Definition schedule.hpp:71
size_t ScheduleId
Type alias for schedule type IDs.
Definition schedule.hpp:20