Skip to content
Flecs v4.1
builder.hpp
Go to the documentation of this file.
1/**
2 * @file addons/cpp/mixins/entity/builder.hpp
3 * @brief Entity builder.
4 */
5
6#pragma once
7
8namespace flecs
9{
10
11/** Entity builder.
12 * @ingroup cpp_entities
13 */
14template <typename Self>
16
18
19 template <typename... T, typename... Args>
20 const Self& add(Args... args) const {
21 _::add_component(this->world_, this->id_,
22 _::make_id<T...>(this->world_, args...));
23 return to_base();
24 }
25
26 template <typename Second>
27 const Self& add_second(flecs::entity_t first) const {
28 return add(first, _::type<Second>::id(this->world_));
29 }
30
31 /** Conditional add.
32 * This operation adds if condition is true, removes if condition is false.
33 *
34 * @param cond The condition to evaluate.
35 * @param component The component to add.
36 */
37 const Self& add_if(bool cond, flecs::id_t component) const {
38 if (cond) {
39 return this->add(component);
40 } else {
41 return this->remove(component);
42 }
43 }
44
45 /** Conditional add.
46 * This operation adds if condition is true, removes if condition is false.
47 *
48 * @tparam T The component to add.
49 * @param cond The condition to evaluate.
50 */
51 template <typename T>
52 const Self& add_if(bool cond) const {
53 if (cond) {
54 return this->add<T>();
55 } else {
56 return this->remove<T>();
57 }
58 }
59
60 /** Conditional add.
61 * This operation adds if condition is true, removes if condition is false.
62 *
63 * @param cond The condition to evaluate.
64 * @param first The first element of the pair.
65 * @param second The second element of the pair.
66 */
67 const Self& add_if(bool cond, flecs::entity_t first, flecs::entity_t second) const {
68 if (cond) {
69 return this->add(first, second);
70 } else {
71 /* If second is 0 or if relationship is exclusive, use wildcard for
72 * second which will remove all instances of the relationship.
73 * Replacing 0 with Wildcard will make it possible to use the second
74 * as the condition. */
75 if (!second || ecs_has_id(this->world_, first, flecs::Exclusive)) {
76 second = flecs::Wildcard;
77 }
78 return this->remove(first, second);
79 }
80 }
81
82 /** Conditional add.
83 * This operation adds if condition is true, removes if condition is false.
84 *
85 * @tparam First The first element of the pair.
86 * @param cond The condition to evaluate.
87 * @param second The second element of the pair.
88 */
89 template <typename First>
90 const Self& add_if(bool cond, flecs::entity_t second) const {
91 return this->add_if(cond, _::type<First>::id(this->world_), second);
92 }
93
94 /** Conditional add.
95 * This operation adds if condition is true, removes if condition is false.
96 *
97 * @tparam First The first element of the pair.
98 * @tparam Second The second element of the pair.
99 * @param cond The condition to evaluate.
100 */
101 template <typename First, typename Second>
102 const Self& add_if(bool cond) const {
103 return this->add_if<First>(cond, _::type<Second>::id(this->world_));
104 }
105
106 /** Conditional add.
107 * This operation adds if condition is true, removes if condition is false.
108 *
109 * @param cond The condition to evaluate.
110 * @param constant The enumeration constant.
111 */
112 template <typename E, if_t< is_enum<E>::value > = 0>
113 const Self& add_if(bool cond, E constant) const {
114 const auto& et = enum_type<E>(this->world_);
115 return this->add_if<E>(cond, et.entity(constant));
116 }
117
118 /** Shortcut for `add(IsA, entity)`.
119 *
120 * @param second The second element of the pair.
121 */
122 const Self& is_a(entity_t second) const {
123 return this->add(flecs::IsA, second);
124 }
125
126 /** Shortcut for `add(IsA, entity)`.
127 *
128 * @tparam T The type associated with the entity.
129 */
130 template <typename T>
131 const Self& is_a() const {
132 return this->add(flecs::IsA, _::type<T>::id(this->world_));
133 }
134
135 /** Shortcut for `add(ChildOf, entity)`.
136 *
137 * @param second The second element of the pair.
138 */
139 const Self& child_of(entity_t second) const {
140 return this->add(flecs::ChildOf, second);
141 }
142
143 /** Shortcut for `add(DependsOn, entity)`.
144 *
145 * @param second The second element of the pair.
146 */
147 const Self& depends_on(entity_t second) const {
148 return this->add(flecs::DependsOn, second);
149 }
150
151 /** Shortcut for `add(DependsOn, entity)`.
152 *
153 * @param second The second element of the pair.
154 */
155 template <typename E, if_t<is_enum<E>::value> = 0>
156 const Self& depends_on(E second) const {
157 const auto& et = enum_type<E>(this->world_);
159 return depends_on(target);
160 }
161
162 /** Shortcut for `add(ChildOf, entity)`.
163 *
164 * @tparam T The type associated with the entity.
165 */
166 template <typename T>
167 const Self& child_of() const {
168 return this->child_of(_::type<T>::id(this->world_));
169 }
170
171 /** Shortcut for `add(DependsOn, entity)`.
172 *
173 * @tparam T The type associated with the entity.
174 */
175 template <typename T>
176 const Self& depends_on() const {
177 return this->depends_on(_::type<T>::id(this->world_));
178 }
179
180 template <typename... T, typename... Args>
181 const Self& remove(Args... args) const {
182 ecs_remove_id(this->world_, this->id_,
183 _::make_id<T...>(this->world_, args...).id);
184 return to_base();
185 }
186
187 template <typename Second>
188 const Self& remove_second(flecs::entity_t first) const {
189 return remove(first, _::type<Second>::id(this->world_));
190 }
191
192 template <typename... T, typename... Args>
193 const Self& auto_override(Args... args) const {
194 return add(ECS_AUTO_OVERRIDE | _::make_id<T...>(this->world_, args...).id);
195 }
196
197 template <typename Second>
198 const Self& auto_override_second(flecs::entity_t first) const {
199 return auto_override(first, _::type<Second>::id(this->world_));
200 }
201
202 template <typename... T, typename A = _::value_type_t<T...>>
203 const Self& set_auto_override(A&& value) const {
204 auto id = _::value_id<T...>(this->world_, value);
205 this->auto_override(id.id);
206 flecs::set(this->world_, this->id_, FLECS_FWD(value), id.id);
207 return to_base();
208 }
209
210 template <typename... T, typename A = _::value_type_t<T...>>
211 const Self& set_auto_override(const A& value) const {
212 auto id = _::value_id<T...>(this->world_, value);
213 this->auto_override(id.id);
214 flecs::set(this->world_, this->id_, value, id.id);
215 return to_base();
216 }
217
218 template <typename First>
219 const Self& set_auto_override(flecs::entity_t second, First&& value) const {
220 auto id = _::make_id<First>(this->world_, second);
221 this->auto_override(id.id);
222 flecs::set(this->world_, this->id_, FLECS_FWD(value), id.id);
223 return to_base();
224 }
225
226 template <typename First>
227 const Self& set_auto_override(flecs::entity_t second, const First& value) const {
228 auto id = _::make_id<First>(this->world_, second);
229 this->auto_override(id.id);
230 flecs::set(this->world_, this->id_, value, id.id);
231 return to_base();
232 }
233
234 template <typename... T, typename... Args>
235 const Self& emplace_auto_override(Args&&... args) const {
236 auto id = _::make_id<T...>(this->world_);
237 this->auto_override(id.id);
238 flecs::emplace<typename decltype(id)::type>(this->world_, this->id_,
239 id.id, FLECS_FWD(args)...);
240 return to_base();
241 }
242
243 /** Enable an entity.
244 * Enabled entities are matched with systems and can be searched with
245 * queries.
246 */
247 const Self& enable() const {
248 ecs_enable(this->world_, this->id_, true);
249 return to_base();
250 }
251
252 /** Disable an entity.
253 * Disabled entities are not matched with systems and cannot be searched
254 * with queries, unless explicitly specified in the query expression.
255 */
256 const Self& disable() const {
257 ecs_enable(this->world_, this->id_, false);
258 return to_base();
259 }
260
261 /** Enable an ID.
262 * This sets the enabled bit for this component. If this is the first time
263 * the component is enabled or disabled, the bitset is added.
264 *
265 * @param id The ID to enable.
266 * @param toggle True to enable, false to disable (default = true).
267 *
268 * @see ecs_enable_id()
269 */
270 const Self& enable(flecs::id_t id, bool toggle = true) const {
271 ecs_enable_id(this->world_, this->id_, id, toggle);
272 return to_base();
273 }
274
275 /** Enable a component.
276 * @see enable(flecs::id_t) const
277 *
278 * @tparam T The component to enable.
279 */
280 template<typename T>
281 const Self& enable() const {
282 return this->enable(_::type<T>::id(this->world_));
283 }
284
285 /** Enable a pair.
286 * @see enable(flecs::id_t) const
287 *
288 * @param first The first element of the pair.
289 * @param second The second element of the pair.
290 */
292 return this->enable(ecs_pair(first, second));
293 }
294
295 /** Enable a pair.
296 * @see enable(flecs::id_t) const
297 *
298 * @tparam First The first element of the pair.
299 * @param second The second element of the pair.
300 */
301 template<typename First>
302 const Self& enable(flecs::id_t second) const {
303 return this->enable(_::type<First>::id(world_), second);
304 }
305
306 /** Enable a pair.
307 * @see enable(flecs::id_t) const
308 *
309 * @tparam First The first element of the pair.
310 * @tparam Second The second element of the pair.
311 */
312 template<typename First, typename Second>
313 const Self& enable() const {
315 }
316
317 /** Disable an ID.
318 * This sets the enabled bit for this ID. If this is the first time
319 * the ID is enabled or disabled, the bitset is added.
320 *
321 * @param id The ID to disable.
322 *
323 * @see ecs_enable_id()
324 * @see enable(flecs::id_t) const
325 */
326 const Self& disable(flecs::id_t id) const {
327 return this->enable(id, false);
328 }
329
330 /** Disable a component.
331 * @see disable(flecs::id_t) const
332 *
333 * @tparam T The component to disable.
334 */
335 template<typename T>
336 const Self& disable() const {
337 return this->disable(_::type<T>::id(world_));
338 }
339
340 /** Disable a pair.
341 * @see disable(flecs::id_t) const
342 *
343 * @param first The first element of the pair.
344 * @param second The second element of the pair.
345 */
347 return this->disable(ecs_pair(first, second));
348 }
349
350 /** Disable a pair.
351 * @see disable(flecs::id_t) const
352 *
353 * @tparam First The first element of the pair.
354 * @param second The second element of the pair.
355 */
356 template<typename First>
357 const Self& disable(flecs::id_t second) const {
358 return this->disable(_::type<First>::id(world_), second);
359 }
360
361 /** Disable a pair.
362 * @see disable(flecs::id_t) const
363 *
364 * @tparam First The first element of the pair.
365 * @tparam Second The second element of the pair.
366 */
367 template<typename First, typename Second>
368 const Self& disable() const {
370 }
371
372 const Self& set_ptr(entity_t comp, size_t size, const void *ptr) const {
373 ecs_set_id(this->world_, this->id_, comp, size, ptr);
374 return to_base();
375 }
376
377 const Self& set_ptr(entity_t comp, const void *ptr) const {
378
379 const ecs_type_info_t *type_info = ecs_get_type_info(this->world_, comp);
380
381 /* Can't set if it's not a component */
382 ecs_assert(type_info != nullptr, ECS_INVALID_PARAMETER, nullptr);
383
384 return set_ptr(comp, type_info->size, ptr);
385 }
386
387 template <typename... T, typename A = _::value_type_t<T...>>
388 const Self& set(A&& value) const {
389 auto id = _::value_id<T...>(this->world_, value);
390 flecs::set(this->world_, this->id_, FLECS_FWD(value), id.id);
391 return to_base();
392 }
393
394 template <typename... T, typename A = _::value_type_t<T...>>
395 const Self& set(const A& value) const {
396 auto id = _::value_id<T...>(this->world_, value);
397 flecs::set(this->world_, this->id_, value, id.id);
398 return to_base();
399 }
400
401 template <typename First, typename Second>
402 const Self& set(Second second, First&& value) const {
403 auto id = _::make_id<First>(this->world_, second);
404 flecs::set(this->world_, this->id_, FLECS_FWD(value), id.id);
405 return to_base();
406 }
407
408 template <typename First, typename Second>
409 const Self& set(Second second, const First& value) const {
410 auto id = _::make_id<First>(this->world_, second);
411 flecs::set(this->world_, this->id_, value, id.id);
412 return to_base();
413 }
414
415 template <typename Second>
416 const Self& set_second(entity_t first, Second&& value) const {
417 auto id = _::second_id<Second>(this->world_, first);
418 flecs::set(this->world_, this->id_, FLECS_FWD(value), id.id);
419 return to_base();
420 }
421
422 template <typename Second>
423 const Self& set_second(entity_t first, const Second& value) const {
424 auto id = _::second_id<Second>(this->world_, first);
425 flecs::set(this->world_, this->id_, value, id.id);
426 return to_base();
427 }
428
429 template <typename First, typename Second>
430 const Self& set_second(const Second& value) const {
431 flecs::set<pair_object<First, Second>>(this->world_, this->id_, value);
432 return to_base();
433 }
434
435 template <typename... T, typename A = _::value_type_t<T...>>
436 const Self& assign(A&& value) const {
437 auto id = _::value_id<T...>(this->world_, value);
438 flecs::assign(this->world_, this->id_, FLECS_FWD(value), id.id);
439 return to_base();
440 }
441
442 template <typename... T, typename A = _::value_type_t<T...>>
443 const Self& assign(const A& value) const {
444 auto id = _::value_id<T...>(this->world_, value);
445 flecs::assign(this->world_, this->id_, value, id.id);
446 return to_base();
447 }
448
449 template <typename First, typename Second>
450 const Self& assign(Second second, First&& value) const {
451 auto id = _::make_id<First>(this->world_, second);
452 flecs::assign(this->world_, this->id_, FLECS_FWD(value), id.id);
453 return to_base();
454 }
455
456 template <typename First, typename Second>
457 const Self& assign(Second second, const First& value) const {
458 auto id = _::make_id<First>(this->world_, second);
459 flecs::assign(this->world_, this->id_, value, id.id);
460 return to_base();
461 }
462
463 template <typename Second>
464 const Self& assign_second(entity_t first, Second&& value) const {
465 auto id = _::second_id<Second>(this->world_, first);
466 flecs::assign(this->world_, this->id_, FLECS_FWD(value), id.id);
467 return to_base();
468 }
469
470 template <typename Second>
471 const Self& assign_second(entity_t first, const Second& value) const {
472 auto id = _::second_id<Second>(this->world_, first);
473 flecs::assign(this->world_, this->id_, value, id.id);
474 return to_base();
475 }
476
477 template <typename First, typename Second>
478 const Self& assign_second(const Second& value) const {
479 flecs::assign<pair_object<First, Second>>(this->world_, this->id_, value);
480 return to_base();
481 }
482
483 /** Set 1..N components.
484 * This operation accepts a callback with as arguments the components to
485 * set. If the entity does not have all of the provided components, they
486 * will be added.
487 *
488 * This operation is faster than individually calling ensure() for each component
489 * as it only obtains entity metadata once. When this operation is called
490 * while deferred, its performance is equivalent to that of calling ensure()
491 * for each component separately.
492 *
493 * The operation will invoke modified() for each component after the callback
494 * has been invoked.
495 *
496 * @param func The callback to invoke.
497 */
498 template <typename Func>
499 const Self& insert(const Func& func) const;
500
501 template <typename... T, typename... Args>
502 const Self& emplace(Args&&... args) const {
503 auto id = _::make_id<T...>(this->world_);
504 flecs::emplace<typename decltype(id)::type>(this->world_, this->id_,
505 id.id, FLECS_FWD(args)...);
506 return to_base();
507 }
508
509 template <typename First, typename ... Args>
510 const Self& emplace_first(flecs::entity_t second, Args&&... args) const {
511 auto first = _::type<First>::id(this->world_);
512 flecs::emplace<First>(this->world_, this->id_,
513 ecs_pair(first, second),
514 FLECS_FWD(args)...);
515 return to_base();
516 }
517
518 template <typename Second, typename ... Args>
519 const Self& emplace_second(flecs::entity_t first, Args&&... args) const {
520 auto second = _::type<Second>::id(this->world_);
521 ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second)) != nullptr,
522 ECS_INVALID_PARAMETER, "pair is not a component");
523 ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second))->component == second,
524 ECS_INVALID_PARAMETER, "type of pair is not Second");
525 flecs::emplace<Second>(this->world_, this->id_,
526 ecs_pair(first, second),
527 FLECS_FWD(args)...);
528 return to_base();
529 }
530
531 /** The function will be run with the scope set to the current entity. */
532 template <typename Func>
533 const Self& scope(const Func& func) const {
534 ecs_entity_t prev = ecs_set_scope(this->world_, this->id_);
535 func();
536 ecs_set_scope(this->world_, prev);
537 return to_base();
538 }
539
540 /** Set the entity name. */
541 const Self& set_name(const char *name) const {
542 ecs_set_name(this->world_, this->id_, name);
543 return to_base();
544 }
545
546 /** Set the entity alias. */
547 const Self& set_alias(const char *name) const {
548 ecs_set_alias(this->world_, this->id_, name);
549 return to_base();
550 }
551
552# ifdef FLECS_DOC
554# endif
555
556# ifdef FLECS_META
558# endif
559
560# ifdef FLECS_JSON
562# endif
563
565
566protected:
567 const Self& to_base() const {
568 return *static_cast<const Self*>(this);
569 }
570};
571
572}
Doc entity builder mixin.
enum_data< E > enum_type(flecs::world_t *world)
Convenience function for getting enum reflection data.
Definition enum.hpp:457
Event entity mixin.
void ecs_remove_id(ecs_world_t *world, ecs_entity_t entity, ecs_id_t component)
Remove a component from an entity.
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:473
#define ECS_INVALID_PARAMETER
Invalid parameter error code.
Definition log.h:671
const ecs_type_info_t * ecs_get_type_info(const ecs_world_t *world, ecs_id_t component)
Get the type info for a component.
ecs_id_t ecs_entity_t
An entity identifier.
Definition flecs.h:395
untyped_component & constant(const char *name, T value)
Add a constant.
ecs_id_t id_t
ID type.
Definition c_types.hpp:20
ecs_entity_t entity_t
Entity type.
Definition c_types.hpp:21
void ecs_enable_id(ecs_world_t *world, ecs_entity_t entity, ecs_id_t component, bool enable)
Enable or disable a component.
void ecs_enable(ecs_world_t *world, ecs_entity_t entity, bool enabled)
Enable or disable an entity.
bool ecs_has_id(const ecs_world_t *world, ecs_entity_t entity, ecs_id_t component)
Test if an entity has a component.
void ecs_set_id(ecs_world_t *world, ecs_entity_t entity, ecs_id_t component, size_t size, const void *ptr)
Set the value of a component.
const ecs_id_t ECS_AUTO_OVERRIDE
Automatically override component when it is inherited.
void ecs_set_alias(ecs_world_t *world, ecs_entity_t entity, const char *alias)
Set an alias for an entity.
ecs_entity_t ecs_set_name(ecs_world_t *world, ecs_entity_t entity, const char *name)
Set the name of an entity.
ecs_entity_t ecs_set_scope(ecs_world_t *world, ecs_entity_t scope)
Set the current scope.
JSON entity mixin.
Meta entity builder mixin.
Type that contains component information (passed to ctors/dtors/...).
Definition flecs.h:1052
ecs_size_t size
Size of the type.
Definition flecs.h:1053
Component class.
Entity builder.
Definition builder.hpp:15
const Self & disable() const
Disable an entity.
Definition builder.hpp:256
const Self & enable(flecs::id_t second) const
Enable a pair.
Definition builder.hpp:302
const Self & add_if(bool cond, E constant) const
Conditional add.
Definition builder.hpp:113
const Self & disable(flecs::id_t first, flecs::id_t second) const
Disable a pair.
Definition builder.hpp:346
const Self & is_a() const
Shortcut for add(IsA, entity).
Definition builder.hpp:131
const Self & enable() const
Enable an entity.
Definition builder.hpp:247
const Self & enable() const
Enable a component.
Definition builder.hpp:281
const Self & child_of() const
Shortcut for add(ChildOf, entity).
Definition builder.hpp:167
const Self & enable() const
Enable a pair.
Definition builder.hpp:313
const Self & enable(flecs::id_t first, flecs::id_t second) const
Enable a pair.
Definition builder.hpp:291
const Self & disable(flecs::id_t id) const
Disable an ID.
Definition builder.hpp:326
const Self & add_if(bool cond) const
Conditional add.
Definition builder.hpp:102
const Self & is_a(entity_t second) const
Shortcut for add(IsA, entity).
Definition builder.hpp:122
const Self & depends_on(E second) const
Shortcut for add(DependsOn, entity).
Definition builder.hpp:156
const Self & add_if(bool cond, flecs::entity_t first, flecs::entity_t second) const
Conditional add.
Definition builder.hpp:67
const Self & add_if(bool cond) const
Conditional add.
Definition builder.hpp:52
const Self & disable() const
Disable a component.
Definition builder.hpp:336
entity_view()
Default constructor.
const Self & set_name(const char *name) const
Set the entity name.
Definition builder.hpp:541
const Self & insert(const Func &func) const
Set 1..N components.
Definition impl.hpp:23
const Self & scope(const Func &func) const
The function will be run with the scope set to the current entity.
Definition builder.hpp:533
const Self & add_if(bool cond, flecs::entity_t second) const
Conditional add.
Definition builder.hpp:90
const Self & add_if(bool cond, flecs::id_t component) const
Conditional add.
Definition builder.hpp:37
const Self & set_alias(const char *name) const
Set the entity alias.
Definition builder.hpp:547
const Self & disable(flecs::id_t second) const
Disable a pair.
Definition builder.hpp:357
const Self & enable(flecs::id_t id, bool toggle=true) const
Enable an ID.
Definition builder.hpp:270
const Self & child_of(entity_t second) const
Shortcut for add(ChildOf, entity).
Definition builder.hpp:139
const Self & depends_on(entity_t second) const
Shortcut for add(DependsOn, entity).
Definition builder.hpp:147
const Self & depends_on() const
Shortcut for add(DependsOn, entity).
Definition builder.hpp:176
const Self & disable() const
Disable a pair.
Definition builder.hpp:368
flecs::string_view name() const
Return the entity name.
entity_view()
Default constructor.
flecs::entity target(int32_t index=0) const
Get target for a given pair.
Definition impl.hpp:36
entity()
Default constructor.
Definition entity.hpp:32
flecs::id_t id_
The raw ID value.
Definition decl.hpp:154
flecs::entity second() const
Get second element from a pair.
Definition impl.hpp:31
flecs::world_t * world_
World is optional, but guarantees that entity identifiers extracted from the ID are valid.
Definition decl.hpp:152
flecs::entity first() const
Get first element from a pair.
Definition impl.hpp:20