Skip to content
Flecs v4.1
impl.hpp
Go to the documentation of this file.
1/**
2 * @file addons/cpp/mixins/system/impl.hpp
3 * @brief System module implementation.
4 */
5
6#pragma once
7
8#include "builder.hpp"
9
10namespace flecs
11{
12
13/** Fluent interface for running a system.
14 *
15 * @ingroup cpp_addons_systems
16 */
18 /** Construct a system runner. */
21 entity_t id,
22 int32_t stage_current,
23 int32_t stage_count,
24 ecs_ftime_t delta_time,
25 void *param)
26 : stage_(world)
27 , id_(id)
28 , delta_time_(delta_time)
29 , param_(param)
30 , stage_current_(stage_current)
31 , stage_count_(stage_count) { }
32
33 /** Set the offset for the system runner. */
35 offset_ = offset;
36 return *this;
37 }
38
39 /** Set the limit for the system runner. */
41 limit_ = limit;
42 return *this;
43 }
44
45 /** Set the stage for the system runner. */
47 stage_ = stage.c_ptr();
48 return *this;
49 }
50
51 /** Destructor. Runs the system on destruction. */
53 if (stage_count_) {
55 stage_, id_, stage_current_, stage_count_, delta_time_,
56 param_);
57 } else {
58 ecs_run(stage_, id_, delta_time_, param_);
59 }
60 }
61
62private:
63 world_t *stage_;
64 entity_t id_;
65 ecs_ftime_t delta_time_;
66 void *param_;
67 int32_t offset_;
68 int32_t limit_;
69 int32_t stage_current_;
70 int32_t stage_count_;
71};
72
73/** System.
74 *
75 * @ingroup cpp_addons_systems
76 */
77struct system final : entity
78{
79 using entity::entity;
80
81 /** Default constructor. */
82 explicit system() {
83 id_ = 0;
84 world_ = nullptr;
85 }
86
87 /** Construct from a world and a system descriptor. */
88 explicit system(flecs::world_t *world, const ecs_system_desc_t *desc) {
89 world_ = world;
90 id_ = ecs_system_init(world, desc);
91 }
92
93 /** Set the system context. */
94 system& ctx(void *ctx) {
95 ecs_system_desc_t desc = {};
96 desc.ctx = ctx;
98 return *this;
99 }
100
101 /** Get the system context. */
102 void* ctx() const {
103 return ecs_system_get(world_, id_)->ctx;
104 }
105
106 /** Replace the system's run callback. */
107 template <typename Func>
108 system& run(Func&& func) {
109 using Delegate = typename _::run_delegate<
110 typename std::decay<Func>::type>;
111 ecs_system_desc_t desc = {};
112 _::set_callback<Delegate, Delegate::run, true>(desc, FLECS_FWD(func));
114 return *this;
115 }
116
117 /** Replace the system's each callback. */
118 template <typename Func>
119 system& each(Func&& func) {
120 using CallbackComponents =
122 ecs_system_desc_t desc = {};
123 _::set_each_callback<false>(desc, FLECS_FWD(func), CallbackComponents{});
125 return *this;
126 }
127
128 /** Replace the system's run callback and use an each callback for
129 * iteration. */
130 template <typename Func>
131 system& run_each(Func&& func) {
132 using CallbackComponents =
134 ecs_system_desc_t desc = {};
135 _::set_each_callback<true>(desc, FLECS_FWD(func), CallbackComponents{});
137 return *this;
138 }
139
140 /** Get the query for this system. */
143 }
144
145 /** Set the query group. */
146 system& set_group(uint64_t group_id) {
147 ecs_system_set_group(world_, id_, group_id);
148 return *this;
149 }
150
151 /** Set the query group. */
152 template <typename Group>
155 return *this;
156 }
157
158 /** Run the system. */
159 system_runner_fluent run(ecs_ftime_t delta_time = 0.0f, void *param = nullptr) const {
160 return system_runner_fluent(world_, id_, 0, 0, delta_time, param);
161 }
162
163 /** Run the system on a specific worker stage. */
165 int32_t stage_current,
166 int32_t stage_count,
167 ecs_ftime_t delta_time = 0.0f,
168 void *param = nullptr) const
169 {
171 world_, id_, stage_current, stage_count, delta_time, param);
172 }
173
174# ifdef FLECS_TIMER
176# endif
177
178};
179
180/** Mixin implementation. */
182 return flecs::system(world_, e);
183}
184
185template <typename... Comps, typename... Args>
186inline system_builder<Comps...> world::system(Args &&... args) const {
187 return flecs::system_builder<Comps...>(world_, FLECS_FWD(args)...);
188}
189
190namespace _ {
191
192inline void system_init(flecs::world& world) {
193 world.component<TickSource>("flecs::system::TickSource");
194}
195
196} // namespace _
197
198template <typename ... Components>
199template <typename Func>
200inline system system_builder<Components...>::each(Func&& func) {
201 if constexpr (sizeof...(Components) == 0) {
202 using CallbackComponents =
204 return this->each_callback(CallbackComponents{}, FLECS_FWD(func));
205 } else {
206 // Faster version of each() that iterates the query on the C++ side.
207 return this->run_each(FLECS_FWD(func));
208 }
209}
210
211template <typename ... Components>
212template <typename ... CallbackComponents, typename Func>
213inline system system_builder<Components...>::each_callback(
214 _::arg_list<CallbackComponents...>,
215 Func&& func)
216{
217 this->template prepend_each_callback_signature<CallbackComponents...>();
218
219 _::set_each_callback<true>(this->desc_, FLECS_FWD(func),
220 _::arg_list<CallbackComponents...>{});
221 return system(this->world_, &this->desc_);
222}
223
224template <typename ... Components>
225template <typename ... CallbackComponents>
226inline void system_builder<Components...>::prepend_each_callback_signature() {
227 if constexpr (sizeof...(Components) == 0 && sizeof...(CallbackComponents) != 0) {
228 constexpr int32_t callback_term_count =
229 static_cast<int32_t>(sizeof...(CallbackComponents));
230
231 ecs_assert(this->term_index_ + callback_term_count <= FLECS_TERM_COUNT_MAX,
232 ECS_INVALID_PARAMETER, "maximum number of terms exceeded");
233
234 const int32_t existing_term_count = this->term_index_;
235 this->set_term(nullptr);
236
237 for (int32_t i = existing_term_count - 1; i >= 0; i --) {
238 this->desc_.query.terms[i + callback_term_count] =
239 this->desc_.query.terms[i];
240 }
241
242 for (int32_t i = 0; i < callback_term_count; i ++) {
243 this->desc_.query.terms[i] = ecs_term_t{};
244 }
245
246 this->term_index_ = 0;
247 _::populate_signature<CallbackComponents...>(this->world_, this);
248 this->term_index_ = existing_term_count + callback_term_count;
249 }
250}
251
252} // namespace flecs
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:473
#define ECS_INVALID_PARAMETER
Invalid parameter error code.
Definition log.h:671
FLECS_API const ecs_system_t * ecs_system_get(const ecs_world_t *world, ecs_entity_t system)
Get a system object.
FLECS_API ecs_entity_t ecs_run(ecs_world_t *world, ecs_entity_t system, ecs_ftime_t delta_time, void *param)
Run a specific system manually.
FLECS_API ecs_entity_t ecs_system_init(ecs_world_t *world, const ecs_system_desc_t *desc)
Create a system.
FLECS_API void ecs_system_set_group(ecs_world_t *world, ecs_entity_t system, uint64_t group_id)
Set query group for system.
FLECS_API ecs_entity_t ecs_system_update(ecs_world_t *world, ecs_entity_t system, const ecs_system_desc_t *desc)
Update an existing system.
FLECS_API ecs_entity_t ecs_run_worker(ecs_world_t *world, ecs_entity_t system, int32_t stage_current, int32_t stage_count, ecs_ftime_t delta_time, void *param)
Same as ecs_run(), but subdivides entities across a number of provided stages.
struct ecs_term_t ecs_term_t
A term is a single element in a query.
Definition flecs.h:448
flecs::system system(flecs::entity e) const
Upcast an entity to a system.
Definition impl.hpp:181
EcsTickSource TickSource
Tick source component.
Definition decl.hpp:19
flecs::component< T > component(Args &&... args) const
Find or register a component.
Definition impl.hpp:11
ecs_entity_t entity_t
Entity type.
Definition c_types.hpp:21
ecs_world_t world_t
World type.
Definition c_types.hpp:18
#define ecs_ftime_t
Customizable precision for scalar time values.
Definition flecs.h:59
#define FLECS_TERM_COUNT_MAX
Maximum number of terms in queries.
Definition flecs.h:338
System builder.
Use with ecs_system_init() and ecs_system_update().
Definition system.h:38
void * ctx
Context to be passed to callback (as ecs_iter_t::param).
Definition system.h:70
void * ctx
Userdata for the system.
Definition system.h:170
Extract the component argument list from an each-callback signature.
Definition delegate.hpp:470
Entity.
Definition entity.hpp:30
entity()
Default constructor.
Definition entity.hpp:32
Class that wraps around a flecs::id_t.
Definition decl.hpp:27
flecs::id_t id_
The raw ID value.
Definition decl.hpp:154
flecs::world_t * world_
World is optional, but guarantees that entity identifiers extracted from the ID are valid.
Definition decl.hpp:152
Typed query.
Definition impl.hpp:266
System builder.
Definition builder.hpp:25
Fluent interface for running a system.
Definition impl.hpp:17
~system_runner_fluent()
Destructor.
Definition impl.hpp:52
system_runner_fluent & stage(flecs::world &stage)
Set the stage for the system runner.
Definition impl.hpp:46
system_runner_fluent & limit(int32_t limit)
Set the limit for the system runner.
Definition impl.hpp:40
system_runner_fluent(world_t *world, entity_t id, int32_t stage_current, int32_t stage_count, ecs_ftime_t delta_time, void *param)
Construct a system runner.
Definition impl.hpp:19
system_runner_fluent & offset(int32_t offset)
Set the offset for the system runner.
Definition impl.hpp:34
System.
Definition impl.hpp:78
system & set_group(uint64_t group_id)
Set the query group.
Definition impl.hpp:146
system & run_each(Func &&func)
Replace the system's run callback and use an each callback for iteration.
Definition impl.hpp:131
system & ctx(void *ctx)
Set the system context.
Definition impl.hpp:94
system(flecs::world_t *world, const ecs_system_desc_t *desc)
Construct from a world and a system descriptor.
Definition impl.hpp:88
flecs::query query() const
Get the query for this system.
Definition impl.hpp:141
system_runner_fluent run(ecs_ftime_t delta_time=0.0f, void *param=nullptr) const
Run the system.
Definition impl.hpp:159
system & each(Func &&func)
Replace the system's each callback.
Definition impl.hpp:119
void * ctx() const
Get the system context.
Definition impl.hpp:102
system & set_group()
Set the query group.
Definition impl.hpp:153
system & run(Func &&func)
Replace the system's run callback.
Definition impl.hpp:108
entity()
Default constructor.
Definition entity.hpp:32
system()
Default constructor.
Definition impl.hpp:82
system_runner_fluent run_worker(int32_t stage_current, int32_t stage_count, ecs_ftime_t delta_time=0.0f, void *param=nullptr) const
Run the system on a specific worker stage.
Definition impl.hpp:164
Type class.
Definition type.hpp:21
The world.
Definition world.hpp:129
world_t * world_
Pointer to the underlying C world.
Definition world.hpp:1009
world_t * c_ptr() const
Obtain a pointer to the C world object.
Definition world.hpp:235
Timer module system mixin.