Flecs: include/flecs/addons/cpp/mixins/system/impl.hpp Source File
Description: A fast entity component system (ECS) for C & C++

| Flecs v4.1 A fast entity component system (ECS) for C & C++

Loading...
Searching...
No Matches
impl.hpp
Go to the documentation of this file.
1
5
6#pragma once
7
8#include "builder.hpp"
9
10namespace flecs
11{
12
17 struct system_runner_fluent {
19 system_runner_fluent(
20 world_t *world,
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
34 system_runner_fluent& offset(int32_t offset) {
35 offset_ = offset;
36 return *this;
37 }
38
40 system_runner_fluent& limit(int32_t limit) {
41 limit_ = limit;
42 return *this;
43 }
44
46 system_runner_fluent& stage(flecs::world& stage) {
47 stage_ = stage.c_ptr();
48 return *this;
49 }
50
52 ~system_runner_fluent() {
53 if (stage_count_) {
54 ecs_run_worker(
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
77 struct system final : entity
78{
79 using entity::entity;
80
82 explicit system() {
83 id_ = 0;
84 world_ = nullptr;
85 }
86
88 explicit system(flecs::world_t *world, ecs_system_desc_t *desc) {
89 world_ = world;
90 id_ = ecs_system_init(world, desc);
91 }
92
94 system& ctx(void *ctx) {
95 ecs_system_desc_t desc = {};
96 desc.ctx = ctx;
97 ecs_system_update(world_, id_, &desc);
98 return *this;
99 }
100
102 void* ctx() const {
103 return ecs_system_get(world_, id_)->ctx;
104 }
105
107 template <typename Func>
108 system& run(Func&& func) {
109 using Delegate = typename _::run_delegate<
110 typename std::decay<Func>::type>;
111 auto ctx = FLECS_NEW(Delegate)(FLECS_FWD(func));
112 ecs_system_desc_t desc = {};
113 desc.run = Delegate::run;
114 desc.run_ctx = ctx;
115 desc.run_ctx_free = _::free_obj<Delegate>;
116 ecs_system_update(world_, id_, &desc);
117 return *this;
118 }
119
121 template <typename Func>
122 system& each(Func&& func) {
123 using CallbackComponents =
124 typename _::each_callback_args<arg_list_t<Func>>::type;
125 return each_callback(CallbackComponents{}, FLECS_FWD(func));
126 }
127
130 template <typename Func>
131 system& run_each(Func&& func) {
132 using CallbackComponents =
133 typename _::each_callback_args<arg_list_t<Func>>::type;
134 return run_each_callback(CallbackComponents{}, FLECS_FWD(func));
135 }
136
138 flecs::query<> query() const {
139 return flecs::query<>(ecs_system_get(world_, id_)->query);
140 }
141
143 system& set_group(uint64_t group_id) {
144 ecs_system_set_group(world_, id_, group_id);
145 return *this;
146 }
147
149 template <typename Group>
150 system& set_group() {
151 ecs_system_set_group(world_, id_, _::type<Group>().id(world_));
152 return *this;
153 }
154
156 system_runner_fluent run(ecs_ftime_t delta_time = 0.0f, void *param = nullptr) const {
157 return system_runner_fluent(world_, id_, 0, 0, delta_time, param);
158 }
159
161 system_runner_fluent run_worker(
162 int32_t stage_current,
163 int32_t stage_count,
164 ecs_ftime_t delta_time = 0.0f,
165 void *param = nullptr) const
166 {
167 return system_runner_fluent(
168 world_, id_, stage_current, stage_count, delta_time, param);
169 }
170
171# ifdef FLECS_TIMER
172# include "../timer/system_mixin.inl"
173# endif
174
175private:
176 template <typename ... CallbackComponents, typename Func>
177 system& each_callback(_::arg_list<CallbackComponents...>, Func&& func) {
178 using Delegate = typename _::each_delegate<
179 typename std::decay<Func>::type, CallbackComponents...>;
180 auto ctx = FLECS_NEW(Delegate)(FLECS_FWD(func));
181 ecs_system_desc_t desc = {};
182 desc.callback = Delegate::run;
183 desc.callback_ctx = ctx;
184 desc.callback_ctx_free = _::free_obj<Delegate>;
185 ecs_system_update(world_, id_, &desc);
186 return *this;
187 }
188
189 template <typename ... CallbackComponents, typename Func>
190 system& run_each_callback(_::arg_list<CallbackComponents...>, Func&& func) {
191 using Delegate = typename _::each_delegate<
192 typename std::decay<Func>::type, CallbackComponents...>;
193 auto ctx = FLECS_NEW(Delegate)(FLECS_FWD(func));
194 ecs_system_desc_t desc = {};
195 desc.run = Delegate::run_each;
196 desc.run_ctx = ctx;
197 desc.run_ctx_free = _::free_obj<Delegate>;
198 ecs_system_update(world_, id_, &desc);
199 return *this;
200 }
201};
202
204 inline system world::system(flecs::entity e) const {
205 return flecs::system(world_, e);
206}
207
208template <typename... Comps, typename... Args>
209inline system_builder<Comps...> world::system(Args &&... args) const {
210 return flecs::system_builder<Comps...>(world_, FLECS_FWD(args)...);
211}
212
213namespace _ {
214
215inline void system_init(flecs::world& world) {
216 world.component<TickSource>("flecs::system::TickSource");
217}
218
219} // namespace _
220
221template <typename ... Components>
222template <typename Func>
223inline system system_builder<Components...>::each(Func&& func) {
224 if constexpr (sizeof...(Components) == 0) {
225 using CallbackComponents =
226 typename _::each_callback_args<arg_list_t<Func>>::type;
227 return this->each_callback(CallbackComponents{}, FLECS_FWD(func));
228 } else {
229 // Faster version of each() that iterates the query on the C++ side.
230 return this->run_each(FLECS_FWD(func));
231 }
232}
233
234template <typename ... Components>
235template <typename ... CallbackComponents, typename Func>
236inline system system_builder<Components...>::each_callback(
237 _::arg_list<CallbackComponents...>,
238 Func&& func)
239{
240 this->template prepend_each_callback_signature<CallbackComponents...>();
241
242 using Delegate = typename _::each_delegate<
243 typename std::decay<Func>::type, CallbackComponents...>;
244
245 auto ctx = FLECS_NEW(Delegate)(FLECS_FWD(func));
246 this->desc_.run = Delegate::run_each;
247 this->desc_.run_ctx = ctx;
248 this->desc_.run_ctx_free = _::free_obj<Delegate>;
249 return system(this->world_, &this->desc_);
250}
251
252template <typename ... Components>
253template <typename ... CallbackComponents>
254inline void system_builder<Components...>::prepend_each_callback_signature() {
255 if constexpr (sizeof...(Components) == 0 && sizeof...(CallbackComponents) != 0) {
256 constexpr int32_t callback_term_count =
257 static_cast<int32_t>(sizeof...(CallbackComponents));
258
259 ecs_assert(this->term_index_ + callback_term_count <= FLECS_TERM_COUNT_MAX,
260 ECS_INVALID_PARAMETER, "maximum number of terms exceeded");
261
262 const int32_t existing_term_count = this->term_index_;
263 this->set_term(nullptr);
264
265 for (int32_t i = existing_term_count - 1; i >= 0; i --) {
266 this->desc_.query.terms[i + callback_term_count] =
267 this->desc_.query.terms[i];
268 }
269
270 for (int32_t i = 0; i < callback_term_count; i ++) {
271 this->desc_.query.terms[i] = ecs_term_t{};
272 }
273
274 this->term_index_ = 0;
275 _::sig<CallbackComponents...>(this->world_).populate(this);
276 this->term_index_ = existing_term_count + callback_term_count;
277 }
278}
279
280} // namespace flecs
ecs_assert
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:473
ECS_INVALID_PARAMETER
#define ECS_INVALID_PARAMETER
Invalid parameter error code.
Definition log.h:671
ecs_system_get
FLECS_API const ecs_system_t * ecs_system_get(const ecs_world_t *world, ecs_entity_t system)
Get a system object.
ecs_system_desc_t
struct ecs_system_desc_t ecs_system_desc_t
Use with ecs_system_init() and ecs_system_update().
ecs_run
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.
ecs_system_init
FLECS_API ecs_entity_t ecs_system_init(ecs_world_t *world, const ecs_system_desc_t *desc)
Create a system.
ecs_system_set_group
FLECS_API void ecs_system_set_group(ecs_world_t *world, ecs_entity_t system, uint64_t group_id)
Set query group for system.
ecs_system_update
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.
ecs_run_worker
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.
ecs_term_t
struct ecs_term_t ecs_term_t
A term is a single element in a query.
Definition flecs.h:438
flecs::world::system
flecs::system system(flecs::entity e) const
Upcast an entity to a system.
Definition impl.hpp:204
flecs::TickSource
EcsTickSource TickSource
Tick source component.
Definition decl.hpp:19
flecs::world::component
flecs::component< T > component(Args &&... args) const
Find or register a component.
Definition impl.hpp:11
flecs::entity_t
ecs_entity_t entity_t
Entity type.
Definition c_types.hpp:21
flecs::world_t
ecs_world_t world_t
World type.
Definition c_types.hpp:18
ecs_ftime_t
#define ecs_ftime_t
Customizable precision for scalar time values.
Definition flecs.h:59
FLECS_TERM_COUNT_MAX
#define FLECS_TERM_COUNT_MAX
Maximum number of terms in queries.
Definition flecs.h:330
builder.hpp
System builder.
ecs_system_desc_t
Use with ecs_system_init() and ecs_system_update().
Definition system.h:38
ecs_system_desc_t::ctx
void * ctx
Context to be passed to callback (as ecs_iter_t::param).
Definition system.h:70
ecs_system_desc_t::run_ctx_free
ecs_ctx_free_t run_ctx_free
Callback to free run ctx.
Definition system.h:85
ecs_system_desc_t::callback_ctx
void * callback_ctx
Context associated with callback (for language bindings).
Definition system.h:76
ecs_system_desc_t::run_ctx
void * run_ctx
Context associated with run (for language bindings).
Definition system.h:82
ecs_system_desc_t::callback
ecs_iter_action_t callback
Callback that is run for each result returned by the system's query.
Definition system.h:54
ecs_system_desc_t::callback_ctx_free
ecs_ctx_free_t callback_ctx_free
Callback to free callback ctx.
Definition system.h:79
ecs_system_desc_t::run
ecs_run_action_t run
Callback that is invoked when a system is run.
Definition system.h:67
ecs_system_t::ctx
void * ctx
Userdata for the system.
Definition system.h:170
flecs::_::each_callback_args
Extract the component argument list from an each-callback signature.
Definition delegate.hpp:932
flecs::_::each_delegate
Definition delegate.hpp:220
flecs::_::run_delegate
Definition delegate.hpp:544
flecs::_::sig
Definition signature.hpp:38
flecs::_::type
Definition flecs.hpp:39
flecs::entity
Entity.
Definition entity.hpp:30
flecs::entity::entity
entity()
Default constructor.
Definition entity.hpp:32
flecs::id
Class that wraps around a flecs::id_t.
Definition decl.hpp:27
flecs::id::id_
flecs::id_t id_
The raw ID value.
Definition decl.hpp:149
flecs::id::world_
flecs::world_t * world_
World is optional, but guarantees that entity identifiers extracted from the ID are valid.
Definition decl.hpp:147
flecs::query
Typed query.
Definition impl.hpp:262
flecs::system_builder
System builder.
Definition builder.hpp:25
flecs::system_runner_fluent
Fluent interface for running a system.
Definition impl.hpp:17
flecs::system_runner_fluent::~system_runner_fluent
~system_runner_fluent()
Destructor.
Definition impl.hpp:52
flecs::system_runner_fluent::stage
system_runner_fluent & stage(flecs::world &stage)
Set the stage for the system runner.
Definition impl.hpp:46
flecs::system_runner_fluent::limit
system_runner_fluent & limit(int32_t limit)
Set the limit for the system runner.
Definition impl.hpp:40
flecs::system_runner_fluent::system_runner_fluent
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
flecs::system_runner_fluent::offset
system_runner_fluent & offset(int32_t offset)
Set the offset for the system runner.
Definition impl.hpp:34
flecs::system
System.
Definition impl.hpp:78
flecs::system::system
system(flecs::world_t *world, ecs_system_desc_t *desc)
Construct from a world and a system descriptor.
Definition impl.hpp:88
flecs::system::set_group
system & set_group(uint64_t group_id)
Set the query group.
Definition impl.hpp:143
flecs::system::run_each
system & run_each(Func &&func)
Replace the system's run callback and use an each callback for iteration.
Definition impl.hpp:131
flecs::system::ctx
system & ctx(void *ctx)
Set the system context.
Definition impl.hpp:94
flecs::system::query
flecs::query query() const
Get the query for this system.
Definition impl.hpp:138
flecs::system::run
system_runner_fluent run(ecs_ftime_t delta_time=0.0f, void *param=nullptr) const
Run the system.
Definition impl.hpp:156
flecs::system::each
system & each(Func &&func)
Replace the system's each callback.
Definition impl.hpp:122
flecs::system::ctx
void * ctx() const
Get the system context.
Definition impl.hpp:102
flecs::system::set_group
system & set_group()
Set the query group.
Definition impl.hpp:150
flecs::system::run
system & run(Func &&func)
Replace the system's run callback.
Definition impl.hpp:108
flecs::system::entity
entity()
Default constructor.
Definition entity.hpp:32
flecs::system::system
system()
Default constructor.
Definition impl.hpp:82
flecs::system::run_worker
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:161
flecs::type
Type class.
Definition type.hpp:21
flecs::world
The world.
Definition world.hpp:246
flecs::world::world_
world_t * world_
Pointer to the underlying C world.
Definition world.hpp:1540
system_mixin.inl
Timer module system mixin.