Flecs: Commands
Description: A fast entity component system (ECS) for C & C++

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

Loading...
Searching...
No Matches
Commands
C API » Core » World
Collaboration diagram for Commands:

## Functions
bool | ecs_readonly_begin (ecs_world_t *world, bool multi_threaded)
| Begin readonly mode.
void | ecs_readonly_end (ecs_world_t *world)
| End readonly mode.
void | ecs_merge (ecs_world_t *world)
| Merge world or stage.
bool | ecs_defer_begin (ecs_world_t *world)
| Defer operations until end of frame.
bool | ecs_is_deferred (const ecs_world_t *world)
| Test if deferring is enabled for current stage.
bool | ecs_defer_end (ecs_world_t *world)
| End block of operations to defer.
void | ecs_defer_suspend (ecs_world_t *world)
| Suspend deferring but do not flush queue.
void | ecs_defer_resume (ecs_world_t *world)
| Resume deferring.
void | ecs_set_stage_count (ecs_world_t *world, int32_t stages)
| Configure world to have N stages.
int32_t | ecs_get_stage_count (const ecs_world_t *world)
| Get number of configured stages.
ecs_world_t * | ecs_get_stage (const ecs_world_t *world, int32_t stage_id)
| Get stage-specific world pointer.
bool | ecs_stage_is_readonly (const ecs_world_t *world)
| Test whether the current world is readonly.
ecs_world_t * | ecs_stage_new (ecs_world_t *world)
| Create unmanaged stage.
void | ecs_stage_free (ecs_world_t *stage)
| Free unmanaged stage.
int32_t | ecs_stage_get_id (const ecs_world_t *world)
| Get stage id.

## Detailed Description

## Function Documentation

## ◆ ecs_defer_begin()

bool ecs_defer_begin | ( | ecs_world_t * | world | ) |

Defer operations until end of frame.

When this operation is invoked while iterating, operations inbetween the ecs_defer_begin() and ecs_defer_end() operations are executed at the end of the frame.

This operation is thread safe.

Parameters

  world | The world.

Returns
  true if world changed from non-deferred mode to deferred mode.

See also
  ecs_defer_end()
  ecs_is_deferred()
  ecs_defer_resume()
  ecs_defer_suspend()

## ◆ ecs_defer_end()

bool ecs_defer_end | ( | ecs_world_t * | world | ) |

End block of operations to defer.

See ecs_defer_begin().

This operation is thread safe.

Parameters

  world | The world.

Returns
  true if world changed from deferred mode to non-deferred mode.

See also
  ecs_defer_begin()
  ecs_defer_is_deferred()
  ecs_defer_resume()
  ecs_defer_suspend()

## ◆ ecs_defer_resume()

void ecs_defer_resume | ( | ecs_world_t * | world | ) |

Resume deferring.

See ecs_defer_suspend().

Parameters

  world | The world.

See also
  ecs_defer_begin()
  ecs_defer_end()
  ecs_defer_is_deferred()
  ecs_defer_suspend()

## ◆ ecs_defer_suspend()

void ecs_defer_suspend | ( | ecs_world_t * | world | ) |

Suspend deferring but do not flush queue.

This operation can be used to do an undeferred operation while not flushing the operations in the queue.

An application should invoke ecs_defer_resume() before ecs_defer_end() is called. The operation may only be called when deferring is enabled.

Parameters

  world | The world.

See also
  ecs_defer_begin()
  ecs_defer_end()
  ecs_defer_is_deferred()
  ecs_defer_resume()

## ◆ ecs_get_stage()

ecs_world_t * ecs_get_stage | ( | const ecs_world_t * | world,
|  | int32_t | stage_id )

Get stage-specific world pointer.

Flecs threads can safely invoke the API as long as they have a private context to write to, also referred to as the stage. This function returns a pointer to a stage, disguised as a world pointer.

Note that this function does not(!) create a new world. It simply wraps the existing world in a thread-specific context, which the API knows how to unwrap. The reason the stage is returned as an ecs_world_t is so that it can be passed transparently to the existing API functions, vs. having to create a dedicated API for threading.

Parameters

  world | The world.
  stage_id | The index of the stage to retrieve.

Returns
  A thread-specific pointer to the world.

## ◆ ecs_get_stage_count()

int32_t ecs_get_stage_count | ( | const ecs_world_t * | world | ) |

Get number of configured stages.

Return number of stages set by ecs_set_stage_count().

Parameters

  world | The world.

Returns
  The number of stages used for threading.

## ◆ ecs_is_deferred()

bool ecs_is_deferred | ( | const ecs_world_t * | world | ) |

Test if deferring is enabled for current stage.

Parameters

  world | The world.

Returns
  True if deferred, false if not.

See also
  ecs_defer_begin()
  ecs_defer_end()
  ecs_defer_resume()
  ecs_defer_suspend()

## ◆ ecs_merge()

void ecs_merge | ( | ecs_world_t * | world | ) |

Merge world or stage.

When automatic merging is disabled, an application can call this operation on either an individual stage, or on the world which will merge all stages. This operation may only be called when staging is not enabled (either after ecs_progress() or after ecs_readonly_end()).

This operation may be called on an already merged stage or world.

Parameters

  world | The world.

## ◆ ecs_readonly_begin()

bool ecs_readonly_begin | ( | ecs_world_t * | world,
|  | bool | multi_threaded )

Begin readonly mode.

This operation puts the world in readonly mode, which disallows mutations on the world. Readonly mode exists so that internal mechanisms can implement optimizations that certain aspects of the world to not change, while also providing a mechanism for applications to prevent accidental mutations in, for example, multithreaded applications.

Readonly mode is a stronger version of deferred mode. In deferred mode ECS operations such as add/remove/set/delete etc. are added to a command queue to be executed later. In readonly mode, operations that could break scheduler logic (such as creating systems, queries) are also disallowed.

Readonly mode itself has a single threaded and a multi threaded mode. In single threaded mode certain mutations on the world are still allowed, for example:

- Entity liveliness operations (such as new, make_alive), so that systems are able to create new entities.
- Implicit component registration, so that this works from systems
- Mutations to supporting data structures for the evaluation of uncached queries (filters), so that these can be created on the fly.

These mutations are safe in a single threaded applications, but for multithreaded applications the world needs to be entirely immutable. For this purpose multi threaded readonly mode exists, which disallows all mutations on the world. This means that in multi threaded applications, entity liveliness operations, implicit component registration, and on-the-fly query creation are not guaranteed to work.

While in readonly mode, applications can still enqueue ECS operations on a stage. Stages are managed automatically when using the pipeline addon and ecs_progress(), but they can also be configured manually as shown here:

// Number of stages typically corresponds with number of threads
ecs_set_stage_count(world, 2);
ecs_stage_t *stage = ecs_get_stage(world, 1);
ecs_readonly_begin(world);
ecs_add(world, e, Tag); // readonly assert
ecs_add(stage, e, Tag); // OK
ecs_readonly_begin
bool ecs_readonly_begin(ecs_world_t *world, bool multi_threaded)
Begin readonly mode.
ecs_get_stage
ecs_world_t * ecs_get_stage(const ecs_world_t *world, int32_t stage_id)
Get stage-specific world pointer.
ecs_set_stage_count
void ecs_set_stage_count(ecs_world_t *world, int32_t stages)
Configure world to have N stages.
ecs_stage_t
struct ecs_stage_t ecs_stage_t
A stage enables modification while iterating and from multiple threads.
Definition flecs.h:427

When an attempt is made to perform an operation on a world in readonly mode, the code will throw an assert saying that the world is in readonly mode.

A call to ecs_readonly_begin() must be followed up with ecs_readonly_end(). When ecs_readonly_end() is called, all enqueued commands from configured stages are merged back into the world. Calls to ecs_readonly_begin() and ecs_readonly_end() should always happen from a context where the code has exclusive access to the world. The functions themselves are not thread safe.

In a typical application, a (non-exhaustive) call stack that uses ecs_readonly_begin() and ecs_readonly_end() will look like this:

ecs_progress()
ecs_readonly_begin()
ecs_defer_begin()
// user code
ecs_readonly_end()
ecs_defer_end()
ecs_progress
FLECS_API bool ecs_progress(ecs_world_t *world, ecs_ftime_t delta_time)
Progress a world.
ecs_defer_end
bool ecs_defer_end(ecs_world_t *world)
End block of operations to defer.
ecs_defer_begin
bool ecs_defer_begin(ecs_world_t *world)
Defer operations until end of frame.
ecs_readonly_end
void ecs_readonly_end(ecs_world_t *world)
End readonly mode.

Parameters

  world | The world
  multi_threaded | Whether to enable readonly/multi threaded mode.

Returns
  Whether world is in readonly mode.

## ◆ ecs_readonly_end()

void ecs_readonly_end | ( | ecs_world_t * | world | ) |

End readonly mode.

This operation ends readonly mode, and must be called after ecs_readonly_begin(). Operations that were deferred while the world was in readonly mode will be flushed.

Parameters

  world | The world

## ◆ ecs_set_stage_count()

void ecs_set_stage_count | ( | ecs_world_t * | world,
|  | int32_t | stages )

Configure world to have N stages.

This initializes N stages, which allows applications to defer operations to multiple isolated defer queues. This is typically used for applications with multiple threads, where each thread gets its own queue, and commands are merged when threads are synchronized.

Note that the ecs_set_threads() function already creates the appropriate number of stages. The ecs_set_stage_count() operation is useful for applications that want to manage their own stages and/or threads.

Parameters

  world | The world.
  stages | The number of stages.

## ◆ ecs_stage_free()

void ecs_stage_free | ( | ecs_world_t * | stage | ) |

Free unmanaged stage.

Parameters

  stage | The stage to free.

## ◆ ecs_stage_get_id()

int32_t ecs_stage_get_id | ( | const ecs_world_t * | world | ) |

Get stage id.

The stage id can be used by an application to learn about which stage it is using, which typically corresponds with the worker thread id.

Parameters

  world | The world.

Returns
  The stage id.

## ◆ ecs_stage_is_readonly()

bool ecs_stage_is_readonly | ( | const ecs_world_t * | world | ) |

Test whether the current world is readonly.

This function allows the code to test whether the currently used world is readonly or whether it allows for writing.

Parameters

  world | A pointer to a stage or the world.

Returns
  True if the world or stage is readonly.

## ◆ ecs_stage_new()

ecs_world_t * ecs_stage_new | ( | ecs_world_t * | world | ) |

Create unmanaged stage.

Create a stage whose lifecycle is not managed by the world. Must be freed with ecs_stage_free().

Parameters

  world | The world.

Returns
  The stage.