Skip to content
Flecs v4.1
world.hpp
Go to the documentation of this file.
1/**
2 * @file addons/cpp/world.hpp
3 * @brief World class.
4 */
5
6#pragma once
7
8namespace flecs
9{
10
11namespace _ {
13template <auto Write, typename T>
14void write_component(world_t *world, flecs::entity_t entity, T&& value, flecs::id_t id) {
15 using A = std::remove_const_t<remove_reference_t<T>>;
17 "operation invalid for empty type");
18 auto res = Write(world, entity, id, &value, sizeof(A));
19 A& dst = *static_cast<A*>(res.ptr);
20 if constexpr (std::is_copy_assignable_v<T> || std::is_const_v<remove_reference_t<T>>) {
21 dst = FLECS_FWD(value);
22 } else {
23 dst = FLECS_MOV(value);
24 }
25 if (res.stage) {
26 flecs_defer_end(res.world, res.stage);
27 }
28 if (res.call_modified) {
30 }
31}
34
35template <typename T>
36inline void set(world_t *world, flecs::entity_t entity, T&& value, flecs::id_t id) {
37 _::write_component<ecs_cpp_set>(world, entity, FLECS_FWD(value), id);
38}
39
40template <typename T>
41inline void set(world_t *world, flecs::entity_t entity, const T& value, flecs::id_t id) {
42 _::write_component<ecs_cpp_set>(world, entity, value, id);
43}
44
45template <typename T, typename A>
46inline void set(world_t *world, entity_t entity, A&& value) {
47 flecs::set(world, entity, FLECS_FWD(value), _::type<T>::id(world));
48}
49
50template <typename T, typename A>
51inline void set(world_t *world, entity_t entity, const A& value) {
52 flecs::set(world, entity, value, _::type<T>::id(world));
53}
54
55template <typename T>
56inline void assign(world_t *world, flecs::entity_t entity, T&& value, flecs::id_t id) {
57 _::write_component<ecs_cpp_assign>(world, entity, FLECS_FWD(value), id);
58}
59
60template <typename T>
61inline void assign(world_t *world, flecs::entity_t entity, const T& value, flecs::id_t id) {
62 _::write_component<ecs_cpp_assign>(world, entity, value, id);
63}
64
65template <typename T, typename A>
66inline void assign(world_t *world, entity_t entity, A&& value) {
67 flecs::assign(world, entity, FLECS_FWD(value), _::type<T>::id(world));
68}
69
70template <typename T, typename A>
71inline void assign(world_t *world, entity_t entity, const A& value) {
72 flecs::assign(world, entity, value, _::type<T>::id(world));
73}
75/** Emplace a component value, constructing it in place.
76 *
77 * @tparam T The component type.
78 * @tparam Args Constructor argument types.
79 * @param world The world.
80 * @param entity The entity.
81 * @param id The component ID.
82 * @param args Constructor arguments.
83 */
84template <typename T, typename ... Args, if_t<
85 std::is_constructible<actual_type_t<T>, Args...>::value ||
86 std::is_default_constructible<actual_type_t<T>>::value > = 0>
87inline void emplace(world_t *world, flecs::entity_t entity, flecs::id_t id, Args&&... args) {
89 "operation invalid for empty type");
90 T& dst = *static_cast<T*>(ecs_emplace_id(world, entity, id, sizeof(T), nullptr));
91
92 FLECS_PLACEMENT_NEW(&dst, T{FLECS_FWD(args)...});
93
95}
96
97/** Return the ID without generation.
98 *
99 * @param e The entity ID.
100 * @return The entity ID without generation.
101 *
102 * @see ecs_strip_generation()
103 */
105 return ecs_strip_generation(e);
106}
107
108/** Return the entity generation.
109 *
110 * @param e The entity ID.
111 * @return The generation of the entity.
112 */
113inline uint32_t get_generation(flecs::entity_t e) {
114 return ECS_GENERATION(e);
115}
116
117/**
118 * @defgroup cpp_world World
119 * @ingroup cpp_core
120 * World operations.
121 *
122 * @{
123 */
124
125/** The world.
126 * The world is the container of all ECS data and systems. If the world is
127 * deleted, all data in the world will be deleted as well.
128 */
129struct world {
130 /** Create a world.
131 */
132 explicit world()
133 : world_( ecs_init() ) {
135 }
136
137 /** Create a world with command-line arguments.
138 * Currently, command-line arguments are not interpreted, but they may be
139 * used in the future to configure Flecs parameters.
140 */
141 explicit world(int argc, char *argv[])
142 : world_( ecs_init_w_args(argc, argv) ) {
144 }
145
146 /** Create a world from a C world.
147 */
148 explicit world(world_t *w)
149 : world_( w ) {
150 if (w) {
151 flecs_poly_claim(w);
152 }
153 }
154
155 /** Copy constructor. Increases reference count on the world.
156 */
157 world(const world& obj) {
158 this->world_ = obj.world_;
159 flecs_poly_claim(this->world_);
160 }
161
162 /** Copy assignment operator. Increases reference count on the world. */
163 world& operator=(const world& obj) noexcept {
164 release();
165 this->world_ = obj.world_;
166 flecs_poly_claim(this->world_);
167 return *this;
168 }
169
170 /** Move constructor. Transfers world ownership. */
171 world(world&& obj) noexcept {
172 world_ = obj.world_;
173 obj.world_ = nullptr;
174 }
175
176 /** Move assignment operator. Transfers world ownership. */
177 world& operator=(world&& obj) noexcept {
178 release();
179 world_ = obj.world_;
180 obj.world_ = nullptr;
181 return *this;
182 }
183
184 /** Release the underlying world object.
185 * If this is the last handle, the world will be finalized.
186 */
187 void release() {
188 if (world_) {
189 if (!flecs_poly_release(world_)) {
190 if (ecs_stage_get_id(world_) == -1) {
192 } else {
193 // Before we call ecs_fini(), we increment the reference count back to 1.
194 // Otherwise, copies of this object created during ecs_fini() (e.g., a component on_remove hook)
195 // would again call this destructor and ecs_fini().
196 flecs_poly_claim(world_);
198 }
199 }
200 world_ = nullptr;
201 }
202 }
203
204 /** Destructor. Releases the world reference. */
206 release();
207 }
208
209 /** Implicit conversion to world_t*. */
210 operator world_t*() const { return world_; }
211
212 /** Make the current world object the owner of the world. This may only be called on
213 * one flecs::world object, and may only be called once. Failing to do so
214 * will result in undefined behavior.
215 *
216 * This operation allows a custom (C) world to be wrapped by a C++ object,
217 * and transfer ownership so that the world is automatically cleaned up.
218 */
219 void make_owner() {
220 flecs_poly_release(world_);
221 }
222
223 /** Delete and recreate the world. */
224 void reset() {
225 /* Make sure there's only one reference to the world. */
226 ecs_assert(flecs_poly_refcount(world_) == 1, ECS_INVALID_OPERATION,
227 "reset would invalidate other handles");
229 world_ = ecs_init();
231 }
232
233 /** Obtain a pointer to the C world object.
234 */
235 world_t* c_ptr() const {
236 return world_;
237 }
238
239 /** Register action to be executed when world is destroyed.
240 */
241 void atfini(ecs_fini_action_t action, void *ctx = nullptr) const {
242 ecs_atfini(world_, action, ctx);
243 }
244
245 /** Begin readonly mode.
246 *
247 * @param multi_threaded Whether to enable readonly/multi-threaded mode.
248 *
249 * @return Whether world is currently readonly.
250 *
251 * @see ecs_readonly_begin()
252 * @see flecs::world::is_readonly()
253 * @see flecs::world::readonly_end()
254 */
255 bool readonly_begin(bool multi_threaded = false) const {
256 return ecs_readonly_begin(world_, multi_threaded);
257 }
258
259 /** End readonly mode.
260 *
261 * @see ecs_readonly_end()
262 * @see flecs::world::is_readonly()
263 * @see flecs::world::readonly_begin()
264 */
265 void readonly_end() const {
267 }
268
269 /** Defer operations until end of frame.
270 * When this operation is invoked while iterating, operations in between the
271 * defer_begin() and defer_end() operations are executed at the end of the frame.
272 *
273 * This operation is thread-safe.
274 *
275 * @return true if world changed from non-deferred mode to deferred mode.
276 *
277 * @see ecs_defer_begin()
278 * @see flecs::world::defer()
279 * @see flecs::world::defer_end()
280 * @see flecs::world::is_deferred()
281 * @see flecs::world::defer_resume()
282 * @see flecs::world::defer_suspend()
283 * @see flecs::world::is_defer_suspended()
284 */
285 bool defer_begin() const {
286 return ecs_defer_begin(world_);
287 }
288
289 /** End block of operations to defer.
290 * See defer_begin().
291 *
292 * This operation is thread-safe.
293 *
294 * @return true if world changed from deferred mode to non-deferred mode.
295 *
296 * @see ecs_defer_end()
297 * @see flecs::world::defer()
298 * @see flecs::world::defer_begin()
299 * @see flecs::world::is_deferred()
300 * @see flecs::world::defer_resume()
301 * @see flecs::world::defer_suspend()
302 * @see flecs::world::is_defer_suspended()
303 */
304 bool defer_end() const {
305 return ecs_defer_end(world_);
306 }
307
308 /** Test whether deferring is enabled.
309 *
310 * @return True if deferred, false if not.
311 *
312 * @see ecs_is_deferred()
313 * @see flecs::world::defer()
314 * @see flecs::world::defer_begin()
315 * @see flecs::world::defer_end()
316 * @see flecs::world::defer_resume()
317 * @see flecs::world::defer_suspend()
318 * @see flecs::world::is_defer_suspended()
319 */
320 bool is_deferred() const {
321 return ecs_is_deferred(world_);
322 }
323
324 /** Test whether deferring is suspended.
325 *
326 * @return True if defer is suspended, false if not.
327 *
328 * @see ecs_is_defer_suspended()
329 * @see flecs::world::defer()
330 * @see flecs::world::defer_begin()
331 * @see flecs::world::defer_end()
332 * @see flecs::world::is_deferred()
333 * @see flecs::world::defer_resume()
334 * @see flecs::world::defer_suspend()
335 */
336 bool is_defer_suspended() const {
338 }
339
340 /** Configure world to have N stages.
341 * This initializes N stages, which allows applications to defer operations to
342 * multiple isolated defer queues. This is typically used for applications with
343 * multiple threads, where each thread gets its own queue, and commands are
344 * merged when threads are synchronized.
345 *
346 * Note that set_threads() already creates the appropriate number of stages.
347 * The set_stage_count() operation is useful for applications that want to manage
348 * their own stages and/or threads.
349 *
350 * @param stages The number of stages.
351 *
352 * @see ecs_set_stage_count()
353 * @see flecs::world::get_stage_count()
354 */
355 void set_stage_count(int32_t stages) const {
357 }
358
359 /** Get the number of configured stages.
360 * Return the number of stages set by set_stage_count().
361 *
362 * @return The number of stages used for threading.
363 *
364 * @see ecs_get_stage_count()
365 * @see flecs::world::set_stage_count()
366 */
367 int32_t get_stage_count() const {
369 }
370
371 /** Get current stage ID.
372 * The stage ID can be used by an application to learn about which stage it
373 * is using, which typically corresponds with the worker thread ID.
374 *
375 * @return The stage ID.
376 */
377 int32_t get_stage_id() const {
378 return ecs_stage_get_id(world_);
379 }
380
381 /** Test if this is a stage.
382 * If this function returns false, it is guaranteed that this is a valid
383 * world object.
384 *
385 * @return True if the world is a stage, false if not.
386 */
387 bool is_stage() const {
392 "flecs::world instance contains invalid reference to world or stage");
394 }
395
396 /** Merge world or stage.
397 * When automatic merging is disabled, an application can call this
398 * operation on either an individual stage, or on the world which will merge
399 * all stages. This operation may only be called when staging is not enabled
400 * (either after progress() or after readonly_end()).
401 *
402 * This operation may be called on an already merged stage or world.
403 *
404 * @see ecs_merge()
405 */
406 void merge() const {
408 }
409
410 /** Get stage-specific world pointer.
411 * Flecs threads can safely invoke the API as long as they have a private
412 * context to write to, also referred to as the stage. This function returns a
413 * pointer to a stage, disguised as a world pointer.
414 *
415 * Note that this function does not(!) create a new world. It simply wraps the
416 * existing world in a thread-specific context, which the API knows how to
417 * unwrap. The reason the stage is returned as an ecs_world_t is so that it
418 * can be passed transparently to the existing API functions, vs. having to
419 * create a dedicated API for threading.
420 *
421 * @param stage_id The index of the stage to retrieve.
422 * @return A thread-specific pointer to the world.
423 */
424 flecs::world get_stage(int32_t stage_id) const {
425 return flecs::world(ecs_get_stage(world_, stage_id));
426 }
427
428 /** Create an asynchronous stage.
429 * An asynchronous stage can be used to asynchronously queue operations for
430 * later merging with the world. An asynchronous stage is similar to a regular
431 * stage, except that it does not allow reading from the world.
432 *
433 * Asynchronous stages are never merged automatically, and must therefore be
434 * manually merged with the ecs_merge() function. It is not necessary to call
435 * defer_begin() or defer_end() before and after enqueuing commands, as an
436 * asynchronous stage unconditionally defers operations.
437 *
438 * The application must ensure that no commands are added to the stage while the
439 * stage is being merged.
440 *
441 * @return The stage.
442 */
445 flecs_poly_release(as); // World object will claim.
446 return flecs::world(as);
447 }
448
449 /** Get actual world.
450 * If the current object points to a stage, this operation will return the
451 * actual world.
452 *
453 * @return The actual world.
454 */
456 /* Safe cast, mutability is checked. */
457 return flecs::world(
458 world_ ? const_cast<flecs::world_t*>(ecs_get_world(world_)) : nullptr);
459 }
460
461 /** Test whether the current world object is readonly.
462 * This function allows the code to test whether the currently used world
463 * object is readonly or whether it allows for writing.
464 *
465 * @return True if the world or stage is readonly.
466 *
467 * @see ecs_stage_is_readonly()
468 * @see flecs::world::readonly_begin()
469 * @see flecs::world::readonly_end()
470 */
471 bool is_readonly() const {
473 }
474
475 /** Set world context.
476 * Set a context value that can be accessed by anyone that has a reference
477 * to the world.
478 *
479 * @param ctx A pointer to a user-defined structure.
480 * @param ctx_free A function that is invoked with ctx when the world is freed.
481 *
482 * @see ecs_set_ctx()
483 * @see flecs::world::get_ctx()
484 */
485 void set_ctx(void* ctx, ecs_ctx_free_t ctx_free = nullptr) const {
486 ecs_set_ctx(world_, ctx, ctx_free);
487 }
488
489 /** Get world context.
490 * This operation retrieves a previously set world context.
491 *
492 * @return The context set with set_ctx(). If no context was set, the
493 * function returns nullptr.
494 *
495 * @see ecs_get_ctx()
496 * @see flecs::world::set_ctx()
497 */
498 void* get_ctx() const {
499 return ecs_get_ctx(world_);
500 }
501
502 /** Set world binding context.
503 *
504 * Same as set_ctx() but for binding context. A binding context is intended
505 * specifically for language bindings to store binding-specific data.
506 *
507 * @param ctx A pointer to a user-defined structure.
508 * @param ctx_free A function that is invoked with ctx when the world is freed.
509 *
510 * @see ecs_set_binding_ctx()
511 * @see flecs::world::get_binding_ctx()
512 */
513 void set_binding_ctx(void* ctx, ecs_ctx_free_t ctx_free = nullptr) const {
514 ecs_set_binding_ctx(world_, ctx, ctx_free);
515 }
516
517 /** Get world binding context.
518 * This operation retrieves a previously set world binding context.
519 *
520 * @return The context set with set_binding_ctx(). If no context was set, the
521 * function returns nullptr.
522 *
523 * @see ecs_get_binding_ctx()
524 * @see flecs::world::set_binding_ctx()
525 */
526 void* get_binding_ctx() const {
528 }
529
530 /** Preallocate memory for a number of entities.
531 * This function preallocates memory for the entity index.
532 *
533 * @param entity_count Number of entities to preallocate memory for.
534 *
535 * @see ecs_dim()
536 */
537 void dim(int32_t entity_count) const {
538 ecs_dim(world_, entity_count);
539 }
540
541 /** Set current scope.
542 *
543 * @param scope The scope to set.
544 * @return The previous scope.
545 *
546 * @see ecs_set_scope()
547 * @see flecs::world::get_scope()
548 */
550
551 /** Get current scope.
552 *
553 * @return The current scope.
554 *
555 * @see ecs_get_scope()
556 * @see flecs::world::set_scope()
557 */
558 flecs::entity get_scope() const;
559
560 /** Same as set_scope(), but with type.
561 *
562 * @see ecs_set_scope()
563 * @see flecs::world::get_scope()
564 */
565 template <typename T>
566 flecs::entity set_scope() const;
567
568 /** Set search path.
569 *
570 * @see ecs_set_lookup_path()
571 * @see flecs::world::lookup()
572 */
574 return ecs_set_lookup_path(world_, search_path);
575 }
576
577 /** Lookup entity by name.
578 *
579 * @param name Entity name.
580 * @param sep The scope separator.
581 * @param root_sep The root scope separator.
582 * @param recursive When false, only the current scope is searched.
583 * @return The entity if found, or 0 if not found.
584 */
585 flecs::entity lookup(const char *name, const char *sep = "::", const char *root_sep = "::", bool recursive = true) const;
586
587 template <typename... T, typename A = _::value_type_t<T...>, if_not_t<is_callable<A>::value> = 0>
588 void set(A&& value) const {
589 auto id = _::value_id<T...>(world_, value);
590 flecs::set(world_, id.owner(world_), FLECS_FWD(value), id.id);
591 }
592
593 template <typename... T, typename A = _::value_type_t<T...>, if_not_t<is_callable<A>::value> = 0>
594 void set(const A& value) const {
595 auto id = _::value_id<T...>(world_, value);
596 flecs::set(world_, id.owner(world_), value, id.id);
597 }
598
599 template <typename First, typename Second>
600 void set(Second second, First&& value) const {
601 auto id = _::make_id<First>(world_, second);
602 flecs::set(world_, id.owner(world_), value, id.id);
603 }
604
605 template <typename First, typename Second>
606 void set(Second second, const First& value) const {
607 auto id = _::make_id<First>(world_, second);
608 flecs::set(world_, id.owner(world_), value, id.id);
609 }
610
611 /** Set singleton component inside a callback.
612 */
613 template <typename Func, if_t< is_callable<Func>::value > = 0 >
614 void set(const Func& func) const;
615
616 template <typename T, typename ... Args>
617 void emplace(Args&&... args) const {
618 flecs::id_t component_id = _::type<T>::id(world_);
619 flecs::emplace<T>(world_, component_id, component_id, FLECS_FWD(args)...);
620 }
621
622 #ifndef ensure
623 template <typename... T, typename... Args>
624 decltype(auto) ensure(Args... args) const {
625 auto id = _::make_id<T...>(world_, args...);
626 return _::get_component<true, true, true>(world_, id.owner(world_), id);
627 }
628 #endif
629
630 template <typename T>
631 void modified() const {
632 auto id = _::make_id<T>(world_);
633 ecs_assert(_::type<T>::size() != 0, ECS_INVALID_PARAMETER,
634 "operation invalid for empty type");
635 ecs_modified_id(world_, id.owner(world_), id.id);
636 }
637
638 /** Get ref singleton component.
639 */
640 template <typename T>
641 ref<T> get_ref() const;
642
643
644 template <typename Func, if_t<is_callable<Func>::value> = 0>
645 void get(const Func& func) const;
646
647 template <typename... T, typename... Args>
648 decltype(auto) try_get(Args... args) const {
649 auto id = _::make_id<T...>(world_, args...);
650 return _::get_component<false, false>(world_, id.owner(world_), id);
651 }
652
653 template <typename... T, typename... Args>
654 decltype(auto) get(Args... args) const {
655 auto id = _::make_id<T...>(world_, args...);
656 return _::get_component<false, true>(world_, id.owner(world_), id);
657 }
658
659 template <typename... T, typename... Args>
660 decltype(auto) try_get_mut(Args... args) const {
661 auto id = _::make_id<T...>(world_, args...);
662 return _::get_component<true, false>(world_, id.owner(world_), id);
663 }
664
665 template <typename... T, typename... Args>
666 decltype(auto) get_mut(Args... args) const {
667 auto id = _::make_id<T...>(world_, args...);
668 return _::get_component<true, true>(world_, id.owner(world_), id);
669 }
670
671 template <typename... T, typename... Args>
672 bool has(Args... args) const {
673 auto id = _::make_id<T...>(world_, args...);
674 return _::has_component(world_, id.owner(world_), id);
675 }
676
677 template <typename... T, typename... Args>
678 void add(Args... args) const {
679 auto id = _::make_id<T...>(world_, args...);
680 _::add_component(world_, id.owner(world_), id);
681 }
682
683 template <typename... T, typename... Args>
684 void remove(Args... args) const {
685 auto id = _::make_id<T...>(world_, args...);
686 ecs_remove_id(world_, id.owner(world_), id.id);
687 }
688
689 /** Iterate entities in root of world.
690 * Accepts a callback with the following signature:
691 *
692 * @code
693 * void(*)(flecs::entity e);
694 * @endcode
695 */
696 template <typename Func>
697 void children(Func&& f) const;
698
699 /** Get singleton entity for type.
700 */
701 template <typename T>
702 flecs::entity singleton() const;
703
704 /** Get target for a given pair from a singleton entity.
705 * This operation returns the target for a given pair. The optional
706 * index can be used to iterate through targets, in case the entity has
707 * multiple instances for the same relationship.
708 *
709 * @tparam First The first element of the pair.
710 * @param index The index (0 for the first instance of the relationship).
711 * @return The target entity.
712 */
713 template<typename First>
714 flecs::entity target(int32_t index = 0) const;
715
716 /** Get target for a given pair from a singleton entity.
717 * This operation returns the target for a given pair. The optional
718 * index can be used to iterate through targets, in case the entity has
719 * multiple instances for the same relationship.
720 *
721 * @tparam T The singleton type.
722 * @param first The first element of the pair for which to retrieve the target.
723 * @param index The index (0 for the first instance of the relationship).
724 * @return The target entity.
725 */
726 template<typename T>
727 flecs::entity target(flecs::entity_t first, int32_t index = 0) const;
728
729 /** Get target for a given pair from a singleton entity.
730 * This operation returns the target for a given pair. The optional
731 * index can be used to iterate through targets, in case the entity has
732 * multiple instances for the same relationship.
733 *
734 * @param first The first element of the pair for which to retrieve the target.
735 * @param index The index (0 for the first instance of the relationship).
736 * @return The target entity.
737 */
738 flecs::entity target(flecs::entity_t first, int32_t index = 0) const;
739
740 /** Create an alias for a component.
741 *
742 * @tparam T The type to create an alias for.
743 * @param alias Alias for the component.
744 * @return Entity representing the component.
745 */
746 template <typename T>
747 flecs::entity use(const char *alias = nullptr) const;
748
749 /** Create an alias for an entity.
750 *
751 * @param name Name of the entity.
752 * @param alias Alias for the entity.
753 */
754 flecs::entity use(const char *name, const char *alias = nullptr) const;
755
756 /** Create an alias for an entity.
757 *
758 * @param entity Entity for which to create the alias.
759 * @param alias Alias for the entity.
760 */
761 void use(flecs::entity entity, const char *alias = nullptr) const;
762
763 template <typename... T, typename... Args>
764 int count(Args... args) const {
765 return ecs_count_id(world_, _::make_id<T...>(world_, args...).id);
766 }
767
768 /** All entities created in the function are created in the scope. All operations
769 * called in the function (such as lookup()) are relative to the scope.
770 */
771 template <typename Func>
772 void scope(id_t parent, const Func& func) const {
773 ecs_entity_t prev = ecs_set_scope(world_, parent);
774 func();
775 ecs_set_scope(world_, prev);
776 }
777
778 /** Same as scope(parent, func), but with T as parent.
779 */
780 template <typename T, typename Func>
781 void scope(const Func& func) const {
783 scope(parent, func);
784 }
785
786 template <typename... T, typename... Args>
787 void delete_with(Args... args) const {
788 ecs_delete_with(world_, _::make_id<T...>(world_, args...).id);
789 }
790
791 template <typename... T, typename... Args>
792 void remove_all(Args... args) const {
793 ecs_remove_all(world_, _::make_id<T...>(world_, args...).id);
794 }
795
796 /** Defer all operations called in function.
797 *
798 * @see flecs::world::defer_begin()
799 * @see flecs::world::defer_end()
800 * @see flecs::world::is_deferred()
801 * @see flecs::world::defer_resume()
802 * @see flecs::world::defer_suspend()
803 */
804 template <typename Func>
805 void defer(const Func& func) const {
807 func();
809 }
810
811 /** Suspend deferring operations.
812 *
813 * @see ecs_defer_suspend()
814 * @see flecs::world::defer()
815 * @see flecs::world::defer_begin()
816 * @see flecs::world::defer_end()
817 * @see flecs::world::is_deferred()
818 * @see flecs::world::defer_resume()
819 */
820 void defer_suspend() const {
822 }
823
824 /** Resume deferring operations.
825 *
826 * @see ecs_defer_resume()
827 * @see flecs::world::defer()
828 * @see flecs::world::defer_begin()
829 * @see flecs::world::defer_end()
830 * @see flecs::world::is_deferred()
831 * @see flecs::world::defer_suspend()
832 */
833 void defer_resume() const {
835 }
836
837 /** Check if entity ID exists in the world.
838 *
839 * @see ecs_exists()
840 * @see flecs::world::is_alive()
841 * @see flecs::world::is_valid()
842 */
843 bool exists(flecs::entity_t e) const {
844 return ecs_exists(world_, e);
845 }
846
847 /** Check if entity is alive.
848 *
849 * @see ecs_is_alive()
850 * @see flecs::world::exists()
851 * @see flecs::world::is_valid()
852 */
853 bool is_alive(flecs::entity_t e) const {
854 return ecs_is_alive(world_, e);
855 }
856
857 /** Check if entity ID is valid.
858 * Invalid entities cannot be used with API functions.
859 *
860 * @see ecs_is_valid()
861 * @see flecs::world::exists()
862 * @see flecs::world::is_alive()
863 */
864 bool is_valid(flecs::entity_t e) const {
865 return ecs_is_valid(world_, e);
866 }
867
868 /** Get alive entity for ID.
869 * Return the entity with the current generation.
870 *
871 * @see ecs_get_alive()
872 */
874
875 /**
876 * @see ecs_make_alive()
877 */
879
880 /** Set the version of an entity to the provided value.
881 *
882 * @see ecs_set_version()
883 */
886 }
887
888 /** Get the version of the provided entity.
889 *
890 * @see ecs_get_version()
891 */
892 uint32_t get_version(flecs::entity_t e) const {
893 return ecs_get_version(e);
894 }
895
896 /** Get the world info.
897 *
898 * @see ecs_get_world_info()
899 */
902 }
903
904 /** Get delta_time. */
906 return get_info()->delta_time;
907 }
908
909 /** Free unused memory.
910 *
911 * @see ecs_shrink()
912 */
913 void shrink() const {
915 }
916
917 /** Begin exclusive access.
918 *
919 * @param thread_name Optional thread name for improved debug messages.
920 * @see ecs_exclusive_access_begin()
921 */
922 void exclusive_access_begin(const char *thread_name = nullptr) {
924 }
925
926 /** End exclusive access.
927 *
928 * @param lock_world Lock world for all threads, allow readonly operations.
929 * @see ecs_exclusive_access_end()
930 */
931 void exclusive_access_end(bool lock_world = false) {
932 ecs_exclusive_access_end(world_, lock_world);
933 }
934
935 /** Return the component ID if it has been registered.
936 * This operation is similar to world::id(), but will never automatically
937 * register the component.
938 *
939 * @tparam T The type for which to obtain the ID.
940 */
941 template <typename T>
944 return _::type<T>::id(world_);
945 }
946 else {
947 return 0;
948 }
949 }
950
951 template <typename... T, typename... Args>
952 const flecs::type_info_t* type_info(Args... args) {
953 return ecs_get_type_info(world_, _::make_id<T...>(world_, args...).id);
954 }
955
956# include "mixins/id/mixin.inl"
958# include "mixins/entity/mixin.inl"
959# include "mixins/event/mixin.inl"
960# include "mixins/term/mixin.inl"
962# include "mixins/query/mixin.inl"
963# include "mixins/enum/mixin.inl"
964
965# ifdef FLECS_PREFAB
966# include "mixins/prefab/mixin.inl"
967# endif
968# ifdef FLECS_ENTITY_RANGES
970# endif
971# ifdef FLECS_FRAME
972# include "mixins/frame/mixin.inl"
973# endif
974# ifdef FLECS_MODULE
975# include "mixins/module/mixin.inl"
976# endif
977# ifdef FLECS_PIPELINE
979# endif
980# ifdef FLECS_SYSTEM
981# include "mixins/system/mixin.inl"
982# endif
983# ifdef FLECS_TIMER
984# include "mixins/timer/mixin.inl"
985# endif
986# ifdef FLECS_SCRIPT
987# include "mixins/script/mixin.inl"
988# endif
989# ifdef FLECS_META
990# include "mixins/meta/world.inl"
991# endif
992# ifdef FLECS_JSON
993# include "mixins/json/world.inl"
994# endif
995# ifdef FLECS_APP
996# include "mixins/app/mixin.inl"
997# endif
998# ifdef FLECS_METRICS
999# include "mixins/metrics/mixin.inl"
1000# endif
1001# ifdef FLECS_ALERTS
1002# include "mixins/alerts/mixin.inl"
1003# endif
1004
1005public:
1006 /** Initialize built-in components. */
1008
1009 world_t *world_; /**< Pointer to the underlying C world. */
1010};
1011
1012/** @} */
1013
1014} // namespace flecs
Alert world mixin.
App world addon mixin.
Component mixin.
Entity world mixin.
Entity ranges world mixin.
Enum world mixin.
Event world mixin.
Frame world mixin.
void ecs_remove_id(ecs_world_t *world, ecs_entity_t entity, ecs_id_t component)
Remove a component from an entity.
void ecs_remove_all(ecs_world_t *world, ecs_id_t component)
Remove all instances of the specified component.
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:473
#define ECS_INVALID_OPERATION
Invalid operation error code.
Definition log.h:669
#define ECS_INVALID_PARAMETER
Invalid parameter error code.
Definition log.h:671
ecs_world_t * ecs_stage_new(ecs_world_t *world)
Create an unmanaged stage.
bool ecs_defer_end(ecs_world_t *world)
End a block of operations to defer.
bool ecs_readonly_begin(ecs_world_t *world, bool multi_threaded)
Begin readonly mode.
void ecs_defer_resume(ecs_world_t *world)
Resume deferring.
bool ecs_defer_begin(ecs_world_t *world)
Defer operations until the end of the frame.
void ecs_defer_suspend(ecs_world_t *world)
Suspend deferring but do not flush queue.
bool ecs_is_deferred(const ecs_world_t *world)
Test if deferring is enabled for the current stage.
void ecs_stage_free(ecs_world_t *stage)
Free an unmanaged stage.
void ecs_merge(ecs_world_t *stage)
Merge a stage.
int32_t ecs_stage_get_id(const ecs_world_t *world)
Get the stage ID.
bool ecs_stage_is_readonly(const ecs_world_t *world)
Test whether the current world is readonly.
int32_t ecs_get_stage_count(const ecs_world_t *world)
Get the number of configured stages.
ecs_world_t * ecs_get_stage(const ecs_world_t *world, int32_t stage_id)
Get stage-specific world pointer.
void ecs_set_stage_count(ecs_world_t *world, int32_t stages)
Configure the world to have N stages.
void ecs_readonly_end(ecs_world_t *world)
End readonly mode.
bool ecs_is_defer_suspended(const ecs_world_t *world)
Test if deferring is suspended for the current stage.
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.
struct ecs_stage_t ecs_stage_t
A stage enables modification while iterating and from multiple threads.
Definition flecs.h:442
ecs_id_t ecs_entity_t
An entity identifier.
Definition flecs.h:395
struct ecs_world_t ecs_world_t
A world is the container for all ECS data and supporting features.
Definition flecs.h:439
flecs::entity entity(Args &&... args) const
Create an entity.
Definition impl.hpp:195
ecs_world_info_t world_info_t
World info type.
Definition c_types.hpp:19
ecs_id_t id_t
ID type.
Definition c_types.hpp:20
ecs_entity_t entity_t
Entity type.
Definition c_types.hpp:21
ecs_world_t world_t
World type.
Definition c_types.hpp:18
ecs_type_info_t type_info_t
Type info type.
Definition c_types.hpp:33
void ecs_delete_with(ecs_world_t *world, ecs_id_t component)
Delete all entities with the specified component.
int32_t ecs_count_id(const ecs_world_t *world, ecs_id_t entity)
Count entities that have the specified ID.
void(*) ecs_ctx_free_t(void *ctx)
Function to clean up context data.
Definition flecs.h:660
void(*) ecs_fini_action_t(ecs_world_t *world, void *ctx)
Action callback on world exit.
Definition flecs.h:655
void * ecs_emplace_id(ecs_world_t *world, ecs_entity_t entity, ecs_id_t component, size_t size, bool *is_new)
Emplace a component.
void ecs_modified_id(ecs_world_t *world, ecs_entity_t entity, ecs_id_t component)
Signal that a component has been modified.
ecs_id_t ecs_strip_generation(ecs_entity_t e)
Remove the generation from an entity ID.
bool ecs_is_valid(const ecs_world_t *world, ecs_entity_t e)
Test whether an entity is valid.
uint32_t ecs_get_version(ecs_entity_t entity)
Get the generation of an entity.
bool ecs_exists(const ecs_world_t *world, ecs_entity_t entity)
Test whether an entity exists.
bool ecs_is_alive(const ecs_world_t *world, ecs_entity_t e)
Test whether an entity is alive.
void ecs_set_version(ecs_world_t *world, ecs_entity_t entity)
Override the generation of an entity.
#define ecs_ftime_t
Customizable precision for scalar time values.
Definition flecs.h:59
ecs_entity_t * ecs_set_lookup_path(ecs_world_t *world, const ecs_entity_t *lookup_path)
Set the search path for lookup operations.
ecs_entity_t ecs_set_scope(ecs_world_t *world, ecs_entity_t scope)
Set the current scope.
void ecs_atfini(ecs_world_t *world, ecs_fini_action_t action, void *ctx)
Register an action to be executed when the world is destroyed.
int ecs_fini(ecs_world_t *world)
Delete a world.
ecs_world_t * ecs_init(void)
Create a new world.
ecs_world_t * ecs_init_w_args(int argc, char *argv[])
Create a new world with arguments.
void * ecs_get_binding_ctx(const ecs_world_t *world)
Get the world binding context.
void ecs_shrink(ecs_world_t *world)
Free unused memory.
void ecs_dim(ecs_world_t *world, int32_t entity_count)
Dimension the world for a specified number of entities.
const ecs_world_info_t * ecs_get_world_info(const ecs_world_t *world)
Get the world info.
const ecs_world_t * ecs_get_world(const ecs_poly_t *poly)
Get the world from a poly.
void ecs_set_ctx(ecs_world_t *world, void *ctx, ecs_ctx_free_t ctx_free)
Set a world context.
void ecs_exclusive_access_begin(ecs_world_t *world, const char *thread_name)
Begin exclusive thread access.
void ecs_set_binding_ctx(ecs_world_t *world, void *ctx, ecs_ctx_free_t ctx_free)
Set a world binding context.
#define flecs_poly_is(object, type)
Test if a pointer is of the specified type.
Definition flecs.h:2624
void ecs_exclusive_access_end(ecs_world_t *world, bool lock_world)
End exclusive thread access.
void * ecs_get_ctx(const ecs_world_t *world)
Get the world context.
ID world mixin.
JSON world mixin.
Meta world mixin.
Metrics world mixin.
Module world mixin.
Int to enum.
Definition component.hpp:18
Observer world mixin.
Pipeline world mixin.
Query world mixin.
Script world mixin.
float delta_time
Time passed to or computed by ecs_progress().
Definition flecs.h:1538
Entity.
Definition entity.hpp:30
The world.
Definition world.hpp:129
bool is_stage() const
Test if this is a stage.
Definition world.hpp:387
void shrink() const
Free unused memory.
Definition world.hpp:913
uint32_t get_version(flecs::entity_t e) const
Get the version of the provided entity.
Definition world.hpp:892
void merge() const
Merge world or stage.
Definition world.hpp:406
world_t * world_
Pointer to the underlying C world.
Definition world.hpp:1009
const flecs::world_info_t * get_info() const
Get the world info.
Definition world.hpp:900
flecs::entity get_scope() const
Get current scope.
Definition world.hpp:91
flecs::entity lookup(const char *name, const char *sep="::", const char *root_sep="::", bool recursive=true) const
Lookup entity by name.
Definition world.hpp:102
ecs_ftime_t delta_time() const
Get delta_time.
Definition world.hpp:905
flecs::entity get_alive(flecs::entity_t e) const
Get alive entity for ID.
Definition world.hpp:170
void readonly_end() const
End readonly mode.
Definition world.hpp:265
flecs::entity make_alive(flecs::entity_t e) const
Ensure an entity ID is alive.
Definition world.hpp:176
void exclusive_access_begin(const char *thread_name=nullptr)
Begin exclusive access.
Definition world.hpp:922
flecs::entity target(int32_t index=0) const
Get target for a given pair from a singleton entity.
Definition world.hpp:128
void defer(const Func &func) const
Defer all operations called in function.
Definition world.hpp:805
bool is_alive(flecs::entity_t e) const
Check if entity is alive.
Definition world.hpp:853
world_t * c_ptr() const
Obtain a pointer to the C world object.
Definition world.hpp:235
~world()
Destructor.
Definition world.hpp:205
bool defer_begin() const
Defer operations until end of frame.
Definition world.hpp:285
void reset()
Delete and recreate the world.
Definition world.hpp:224
flecs::entity_t * set_lookup_path(const flecs::entity_t *search_path) const
Set search path.
Definition world.hpp:573
void defer_suspend() const
Suspend deferring operations.
Definition world.hpp:820
void make_owner()
Make the current world object the owner of the world.
Definition world.hpp:219
bool is_valid(flecs::entity_t e) const
Check if entity ID is valid.
Definition world.hpp:864
flecs::world async_stage() const
Create an asynchronous stage.
Definition world.hpp:443
bool is_deferred() const
Test whether deferring is enabled.
Definition world.hpp:320
void release()
Release the underlying world object.
Definition world.hpp:187
void * get_binding_ctx() const
Get world binding context.
Definition world.hpp:526
int32_t get_stage_id() const
Get current stage ID.
Definition world.hpp:377
void init_builtin_components()
Initialize built-in components.
Definition world.hpp:12
world(const world &obj)
Copy constructor.
Definition world.hpp:157
void scope(const Func &func) const
Same as scope(parent, func), but with T as parent.
Definition world.hpp:781
void defer_resume() const
Resume deferring operations.
Definition world.hpp:833
flecs::entity set_scope() const
Same as set_scope(), but with type.
Definition world.hpp:97
void dim(int32_t entity_count) const
Preallocate memory for a number of entities.
Definition world.hpp:537
void set_version(flecs::entity_t e) const
Set the version of an entity to the provided value.
Definition world.hpp:884
void set_stage_count(int32_t stages) const
Configure world to have N stages.
Definition world.hpp:355
void * get_ctx() const
Get world context.
Definition world.hpp:498
bool defer_end() const
End block of operations to defer.
Definition world.hpp:304
world(world_t *w)
Create a world from a C world.
Definition world.hpp:148
void children(Func &&f) const
Iterate entities in root of world.
Definition world.hpp:116
flecs::world get_world() const
Get actual world.
Definition world.hpp:455
void scope(id_t parent, const Func &func) const
All entities created in the function are created in the scope.
Definition world.hpp:772
world(world &&obj) noexcept
Move constructor.
Definition world.hpp:171
world & operator=(const world &obj) noexcept
Copy assignment operator.
Definition world.hpp:163
flecs::id_t id_if_registered()
Return the component ID if it has been registered.
Definition world.hpp:942
flecs::entity use(const char *alias=nullptr) const
Create an alias for a component.
Definition world.hpp:54
bool is_readonly() const
Test whether the current world object is readonly.
Definition world.hpp:471
bool readonly_begin(bool multi_threaded=false) const
Begin readonly mode.
Definition world.hpp:255
void get(const Func &func) const
Get a singleton component using a callback.
Definition world.hpp:155
flecs::world get_stage(int32_t stage_id) const
Get stage-specific world pointer.
Definition world.hpp:424
bool exists(flecs::entity_t e) const
Check if entity ID exists in the world.
Definition world.hpp:843
world()
Create a world.
Definition world.hpp:132
void set_binding_ctx(void *ctx, ecs_ctx_free_t ctx_free=nullptr) const
Set world binding context.
Definition world.hpp:513
void atfini(ecs_fini_action_t action, void *ctx=nullptr) const
Register action to be executed when world is destroyed.
Definition world.hpp:241
int32_t get_stage_count() const
Get the number of configured stages.
Definition world.hpp:367
flecs::entity singleton() const
Get singleton entity for type.
Definition world.hpp:122
void exclusive_access_end(bool lock_world=false)
End exclusive access.
Definition world.hpp:931
void set_ctx(void *ctx, ecs_ctx_free_t ctx_free=nullptr) const
Set world context.
Definition world.hpp:485
bool is_defer_suspended() const
Test whether deferring is suspended.
Definition world.hpp:336
world(int argc, char *argv[])
Create a world with command-line arguments.
Definition world.hpp:141
world & operator=(world &&obj) noexcept
Move assignment operator.
Definition world.hpp:177
ref< T > get_ref() const
Get ref singleton component.
Definition world.hpp:109
flecs::entity entity(Args &&... args) const
Create an entity.
System module world mixin.
Term world mixin.
Timer module mixin.
enable_if_t< false==V, int > if_not_t
Convenience enable_if alias for negated conditions.
Definition utils.hpp:172
enable_if_t< V, int > if_t
Convenience enable_if alias using int as default type.
Definition utils.hpp:168
flecs::id_t strip_generation(flecs::entity_t e)
Return the ID without generation.
Definition world.hpp:104
uint32_t get_generation(flecs::entity_t e)
Return the entity generation.
Definition world.hpp:113
void emplace(world_t *world, flecs::entity_t entity, flecs::id_t id, Args &&... args)
Emplace a component value, constructing it in place.
Definition world.hpp:87