Helios Engine
A modular ECS based data-oriented C++23 game engine framework
Loading...
Searching...
No Matches
system.hpp
Go to the documentation of this file.
1#pragma once
2
6
7#include <compare>
8#include <concepts>
9#include <cstddef>
10#include <string_view>
11#include <type_traits>
12
13namespace helios::ecs {
14
15/// @brief Type id for systems.
17
18/// @brief Type index for systems.
20
21namespace details {
22
23/// @brief Extracts the argument types of a member function pointer.
24template <typename F>
26
27template <typename R, typename C, typename... Args>
28struct MemberFnArgs<R (C::*)(Args...)> {
29 using ArgsTuple = std::tuple<Args...>;
30};
31
32template <typename R, typename C, typename... Args>
33struct MemberFnArgs<R (C::*)(Args...) const> {
34 using ArgsTuple = std::tuple<Args...>;
35};
36
37/// @brief True if every Arg in the pack satisfies `SystemParam`.
38template <typename... Args>
39inline constexpr bool kAllAreSystemParams =
41
42/// @brief Concept: a type's `operator()` arguments all have
43/// `SystemParamTraits`.
44template <typename R, typename... Args>
45struct MemberFnArgs<R (*)(Args...)> {
46 using ArgsTuple = std::tuple<Args...>;
47};
48
49template <typename R, typename... Args>
50struct MemberFnArgs<R(Args...)> {
51 using ArgsTuple = std::tuple<Args...>;
52};
53
54template <typename F>
55concept HasValidSystemParams = requires {
57} && []<typename... Args>(std::tuple<Args...>*) {
58 return kAllAreSystemParams<Args...>;
59}(static_cast<typename MemberFnArgs<F>::ArgsTuple*>(nullptr));
60
61template <typename T>
63 static constexpr bool kValue = [] {
64 using Decayed = std::remove_cvref_t<T>;
65 if constexpr (std::is_class_v<Decayed> &&
66 requires { &Decayed::operator(); }) {
67 return HasValidSystemParams<decltype(&Decayed::operator())>;
68 } else {
70 }
71 }();
72};
73
74template <typename T>
77
78} // namespace details
79
80/**
81 * @brief Concept for systems that declare all data access via parameter types.
82 * @details A system must be destructible, move or copy constructible, not
83 * polymorphic, an object type, and its `operator()` parameters must all have
84 * `SystemParamTraits` specialisations.
85 */
86template <typename T>
87concept SystemTrait =
88 std::destructible<T> &&
89 (std::move_constructible<T> || std::copy_constructible<T>) &&
90 !std::is_polymorphic_v<std::remove_cvref_t<T>> &&
91 std::is_object_v<std::remove_cvref_t<T>> &&
93
94/**
95 * @brief Concept for lambda closure types that satisfy `SystemTrait`.
96 * @details Lambdas are detected via `utils::IsLambda<T>()`. They should always
97 * be registered with an explicit human-readable name.
98 */
99template <typename T>
102
103/// @brief Concept for system types that are not lambda closures.
104template <typename T>
106
107/**
108 * @brief Concept for systems that declare all data access via parameter types.
109 * @details A system must be destructible, move or copy constructible, not
110 * polymorphic, an object type, and its `operator()` parameters must all have
111 * `SystemParamTraits` specialisations.
112 */
113template <typename T>
114concept SystemWithNameTrait = SystemTrait<T> && requires {
115 { std::remove_cvref_t<T>::kName } -> std::convertible_to<std::string_view>;
116};
117
118/**
119 * @brief Gets the name of a system.
120 * @details Returns provided name or type name as fallback.
121 * @tparam T System type
122 * @return System name
123 */
124template <SystemTrait T>
125[[nodiscard]] constexpr std::string_view SystemNameOf() noexcept {
126 if constexpr (SystemWithNameTrait<T>) {
127 return T::kName;
128 } else {
130 }
131}
132
133/**
134 * @brief Gets the name of a system.
135 * @tparam T System type
136 * @param instance System instance
137 * @return System name
138 */
139template <SystemTrait T>
140[[nodiscard]] constexpr std::string_view SystemNameOf(
141 const T& /*instance*/) noexcept {
143}
144
145/// @brief Id for systems.
146struct SystemId {
147 size_t id = 0;
148
149 /**
150 * @brief Creates system id from a name.
151 * @param name System name
152 * @return System id
153 */
154 [[nodiscard]] static constexpr SystemId From(std::string_view name) noexcept {
155 return SystemId{.id = utils::Fnv1aHash(name)};
156 }
157
158 /**
159 * @brief Creates system id from a system type index.
160 * @param index System type index
161 * @return System id
162 */
163 [[nodiscard]] static constexpr SystemId From(SystemTypeIndex index) noexcept {
164 return SystemId{.id = index.Hash()};
165 }
166
167 /**
168 * @brief Creates system id from a system type id.
169 * @param id System type id
170 * @return System id
171 */
172 [[nodiscard]] static constexpr SystemId From(SystemTypeId id) noexcept {
173 return From(id.Index());
174 }
175
176 /**
177 * @brief Creates system id from a system type.
178 * @tparam T System type
179 * @return System id
180 */
181 template <SystemTrait T>
182 [[nodiscard]] static constexpr SystemId From() noexcept {
184 }
185
186 /**
187 * @brief Creates system id from a system type.
188 * @tparam T System type
189 * @param instance System instance
190 * @return System id
191 */
192 template <SystemTrait T>
193 [[nodiscard]] static constexpr SystemId From(const T& /*instance*/) noexcept {
195 }
196
197 constexpr std::strong_ordering operator<=>(const SystemId&) const noexcept =
198 default;
199};
200
201} // namespace helios::ecs
202
203namespace std {
204
205template <>
206struct hash<helios::ecs::SystemId> {
207 constexpr size_t operator()(helios::ecs::SystemId id) const noexcept {
208 return id.id;
209 }
210};
211
212} // namespace std
static constexpr TypeIndex From() noexcept
Constructs a TypeIndex from a type T.
Concept for system types that are not lambda closures.
Definition system.hpp:105
Concept for lambda closure types that satisfy SystemTrait.
Definition system.hpp:100
Concept for types usable as system function parameters.
Concept for systems that declare all data access via parameter types.
Definition system.hpp:87
Concept for systems that declare all data access via parameter types.
Definition system.hpp:114
Concept for lambda closure types.
constexpr bool kAllAreSystemParams
True if every Arg in the pack satisfies SystemParam.
Definition system.hpp:39
constexpr std::string_view SystemNameOf() noexcept
Gets the name of a system.
Definition system.hpp:125
utils::TypeId SystemTypeId
Type id for systems.
Definition system.hpp:16
utils::TypeIndex SystemTypeIndex
Type index for systems.
Definition system.hpp:19
constexpr std::string_view QualifiedTypeNameOf() noexcept
Retrieves the fully qualified type name of T.
constexpr HashType Fnv1aHash(std::string_view str, HashType hash=kFnvBasis) noexcept
Computes the FNV-1a hash of a string.
Definition hash.hpp:26
STL namespace.
Id for systems.
Definition system.hpp:146
static constexpr SystemId From() noexcept
Creates system id from a system type.
Definition system.hpp:182
constexpr std::strong_ordering operator<=>(const SystemId &) const noexcept=default
static constexpr SystemId From(SystemTypeIndex index) noexcept
Creates system id from a system type index.
Definition system.hpp:163
static constexpr SystemId From(std::string_view name) noexcept
Creates system id from a name.
Definition system.hpp:154
static constexpr SystemId From(SystemTypeId id) noexcept
Creates system id from a system type id.
Definition system.hpp:172
static constexpr SystemId From(const T &) noexcept
Creates system id from a system type.
Definition system.hpp:193
Extracts the argument types of a member function pointer.
Definition system.hpp:25
constexpr size_t operator()(helios::ecs::SystemId id) const noexcept
Definition system.hpp:207