co_ecs 0.9.0
Cobalt ECS
Loading...
Searching...
No Matches
system.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <co_ecs/command.hpp>
4#include <co_ecs/registry.hpp>
6#include <co_ecs/view.hpp>
7
9
10namespace co_ecs {
11
14public:
16 virtual ~system_executor_interface() = default;
17
19 virtual void run() = 0;
20
24 virtual auto name() const -> std::string_view = 0;
25
29 virtual auto type_name() const -> std::string_view = 0;
30
34 virtual auto access_pattern() const -> access_pattern_t = 0;
35};
36
39public:
41 virtual ~system_interface() = default;
42
48 virtual std::unique_ptr<system_executor_interface> create_executor(registry& registry, void* user_context) = 0;
49};
50
52
57template<typename T>
58class system_argument_state_trait;
59
63template<typename... Args>
64class system_state {
65public:
67 using system_state_tuple = std::tuple<typename system_argument_state_trait<Args>::state_type...>;
68
73 explicit system_state(registry& registry, void* user_context) :
74 _state(typename system_argument_state_trait<Args>::state_type(registry, user_context)...){};
75
79 [[nodiscard]] system_state_tuple& get() noexcept {
80 return _state;
81 }
82
86 auto access_pattern() const -> access_pattern_t {
87 access_pattern_t pattern;
88 if constexpr (0 < std::tuple_size_v<system_state_tuple>) {
89 pattern &= std::apply([](auto&&... args) { return (args.access_pattern() & ...); }, _state);
90 }
91 return pattern;
92 }
93
94private:
95 system_state_tuple _state;
96};
97
101template<typename T>
102struct system_state_trait;
103
107template<typename... Ts>
108struct system_state_trait<std::tuple<Ts...>> {
109 using type = system_state<Ts...>;
110};
111
115template<typename F>
116class system_executor : public system_executor_interface {
117public:
119 using system_arguments = typename detail::function_traits<F>::arguments_tuple_type;
120
125 explicit system_executor(registry& registry, void* user_context, F func, std::string_view name = {}) :
126 _func(std::move(func)), _state(registry, user_context), _name(name) {
127 }
128
130 void run() override {
131 std::apply([this](auto&&... args) { _func(args.get()...); }, _state.get());
132 }
133
137 auto name() const -> std::string_view override {
138 return _name;
139 }
140
144 auto type_name() const -> std::string_view override {
145 return co_ecs::type_name<F>();
146 }
147
151 auto access_pattern() const -> access_pattern_t override {
152 return _state.access_pattern();
153 }
154
155private:
156 F _func;
157 typename system_state_trait<system_arguments>::type _state;
158 std::string_view _name;
159};
160
164template<typename F>
165class system : public system_interface {
166public:
170 explicit system(F func) : _func(std::move(func)) {
171 }
172
178 std::unique_ptr<system_executor_interface> create_executor(registry& registry, void* user_context) override {
179 return std::make_unique<system_executor<F>>(registry, user_context, _func);
180 }
181
182private:
183 F _func;
184};
185
188class system_registry_state {
189public:
194 explicit system_registry_state(registry& registry, void* user_context) noexcept : _registry(registry) {
195 }
196
200 [[nodiscard]] registry& get() noexcept {
201 return _registry;
202 }
203
207 auto access_pattern() const -> access_pattern_t {
208 return access_pattern_t(access_type::write);
209 }
210
211private:
212 registry& _registry;
213};
214
216template<>
217class system_argument_state_trait<registry&> {
218public:
220 using state_type = system_registry_state;
221};
222
225class system_const_registry_state {
226public:
231 explicit system_const_registry_state(registry& registry, void* user_context) noexcept : _registry(registry) {
232 }
233
237 [[nodiscard]] const registry& get() noexcept {
238 return _registry;
239 }
240
244 auto access_pattern() const -> access_pattern_t {
245 return access_pattern_t(access_type::read);
246 }
247
248private:
249 const registry& _registry;
250};
251
253template<>
254class system_argument_state_trait<const registry&> {
255public:
257 using state_type = system_registry_state;
258};
259
262class system_command_writer_state {
263public:
268 explicit system_command_writer_state(registry& registry, void* user_context) noexcept : _registry(registry) {
269 }
270
274 [[nodiscard]] command_writer get() noexcept {
275 return command_writer(_registry);
276 }
277
281 auto access_pattern() const -> access_pattern_t {
282 return access_pattern_t{};
283 }
284
285private:
286 registry& _registry;
287};
288
290template<>
291class system_argument_state_trait<command_writer> {
292public:
294 using state_type = system_command_writer_state;
295};
296
300template<typename view_t>
301class system_view_state {
302public:
307 explicit system_view_state(registry& registry, void* user_context) noexcept : _view(registry) {
308 }
309
313 [[nodiscard]] view_t& get() noexcept {
314 return _view;
315 }
316
317private:
318 template<typename T>
319 struct access_pattern_helper {};
320
321 template<component_reference... Args>
322 struct access_pattern_helper<view<Args...>> {
323 static auto access_pattern() -> access_pattern_t {
324 return (access_pattern_t(
325 std::is_const_v<std::remove_reference_t<Args>> ? access_type::read : access_type::write,
326 component_meta::of<decay_component_t<Args>>())
327 & ...);
328 }
329 };
330
331public:
335 auto access_pattern() const -> access_pattern_t {
336 return access_pattern_helper<view_t>::access_pattern();
337 }
338
339private:
340 view_t _view;
341};
342
346template<component_reference... Args>
347class system_argument_state_trait<view<Args...>> {
348public:
350 using state_type = system_view_state<view<Args...>>;
351};
352
354
355} // namespace co_ecs
Class representing an access pattern for components.
Definition access.hpp:19
Registry is a container for all our entities and components. Components are stored in continuously in...
Definition registry.hpp:13
System executor interface, a system is a type that implements run() method.
Definition system.hpp:13
virtual auto name() const -> std::string_view=0
Get the name of the entity.
virtual auto type_name() const -> std::string_view=0
Get the type name of the entity.
virtual void run()=0
Execute system logic.
virtual ~system_executor_interface()=default
Destroy the system executor interface object.
virtual auto access_pattern() const -> access_pattern_t=0
Get the access pattern of the entity.
System interface.
Definition system.hpp:38
virtual ~system_interface()=default
Destroy the system interface object.
virtual std::unique_ptr< system_executor_interface > create_executor(registry &registry, void *user_context)=0
Create a system executor object.
Definition archetype.hpp:11
std::decay_t< T > decay_component_t
Decay component; converts component_reference to component by removing cv-qualifiers and reference.
Definition component.hpp:100
access_type
Enumeration representing the type of access.
Definition access.hpp:10
@ write
Write access.
Definition access.hpp:13
STL namespace.