Struct WorldRef

Source
pub struct WorldRef<'a> { /* private fields */ }

Implementations§

Source§

impl<'a> WorldRef<'a>

Source

pub fn real_world(&self) -> WorldRef<'a>

Source

pub unsafe fn from_ptr(raw_world: *mut ecs_world_t) -> Self

§Safety

Caller must ensure raw_world points to a valid sys::ecs_world_t

Examples found in repository?
examples/flecs/queries/query_group_by_callbacks.rs (line 41)
36extern "C" fn callback_group_create(
37    world: *mut sys::ecs_world_t,
38    group_id: u64,
39    _group_by_ctx: *mut c_void,
40) -> *mut c_void {
41    let world_ref = unsafe { WorldRef::from_ptr(world) };
42    println!(
43        "Group created: {:?}",
44        world_ref.world().entity_from_id(group_id).name()
45    );
46
47    println!();
48
49    let mut counter = GROUP_COUNTER.lock().unwrap();
50    *counter += 1;
51
52    // Return data that will be associated with the group
53    let ctx = Box::new(GroupCtx { counter: *counter });
54
55    Box::into_raw(ctx) as *mut std::ffi::c_void // Cast to make sure function type matches
56}
57
58// callbacks need to be extern "C" to be callable from C
59extern "C" fn callback_group_delete(
60    world: *mut sys::ecs_world_t,
61    group_id: u64,
62    _ctx: *mut c_void,
63    _group_by_ctx: *mut c_void,
64) {
65    let world_ref = unsafe { WorldRef::from_ptr(world) };
66    println!(
67        "Group deleted: {:?}",
68        world_ref.world().entity_from_id(group_id).name()
69    );
70
71    // if you have any data associated with the group, you need to free it
72    // or use the callback group_by_ctx where you pass a context to the callback
73}
More examples
Hide additional examples
examples/flecs/queries/query_group_by_custom.rs (line 37)
29extern "C" fn callback_group_by_relationship(
30    world: *mut sys::ecs_world_t,
31    table: *mut sys::ecs_table_t,
32    id: u64,
33    _group_by_ctx: *mut c_void,
34) -> u64 {
35    // Use sys::ecs_search to find the target for the relationship in the table
36    let mut match_id: sys::ecs_id_t = Default::default();
37    let world = unsafe { WorldRef::from_ptr(world) };
38    let id = IdView::new_from(world, (id, flecs::Wildcard::ID)).id();
39    if unsafe { sys::ecs_search(world.world_ptr_mut(), table, *id, &mut match_id) } != -1 {
40        *IdView::new_from(world, match_id).second_id().id() // First, Second or Third
41    } else {
42        0
43    }
44}

Methods from Deref<Target = World>§

Source

pub fn info(&self) -> WorldInfo

Get the world’s info. See sys::WorldInfo for what information you can retrieve.

§Example
use flecs_ecs::prelude::*;

let world = World::new();

world.progress();

let world_info = world.info();

assert!(world_info.delta_time > 0.0);
//assert!(world_info.world_time_total_raw > 0.0); //BUG TODO
//assert!(world_info.systems_ran_frame == 0);
§See also
  • C++ API: world::get_info
Source

pub fn quit(&self)

Signals the application to quit.

After calling this function, the next call to World::progress() returns false.

§Example
use flecs_ecs::prelude::*;

let world = World::new();

let mut count = 0;
while world.progress() {
    count += 1;
    if count == 5 {
        world.quit();
    }
}
assert!(count == 5);
§See also
Source

pub fn should_quit(&self) -> bool

Tests if World::quit() has been called.

§Returns

True if quit has been called, false otherwise.

§Example
use flecs_ecs::prelude::*;

let world = World::new();

assert!(!world.should_quit());
world.quit();
assert!(world.should_quit());
§See also
Source

pub fn on_destroyed(&self, action: ecs_fini_action_t, ctx: *mut c_void)

Registers an action to be executed when the world is destroyed.

§See also
  • C++ API: world::atfini
Source

pub fn frame_begin(&self, delta_time: f32) -> f32

Begins a frame.

When an application does not use World::progress() to control the main loop, it can still use Flecs features such as FPS limiting and time measurements processed.

Calls to World::frame_begin must always be followed by World::frame_end.

The function accepts a delta_time parameter, which will get passed to systems. This value is also used to compute the amount of time the function needs to sleep to ensure it does not exceed the target_fps, when it is set. When 0 is provided for delta_time, the time will be measured.

§Safety

This function should only be ran from the main thread.

§Arguments
  • delta_time: Time elapsed since the last frame.
§Returns

The provided delta_time, or the measured time if 0 was provided.

§Example
use flecs_ecs::prelude::*;

#[derive(Component)]
struct Position {
   x: f32,
   y: f32,
}

let world = World::new();

let delta_time = 1.0 / 60.0; // 60 FPS

let entity = world.entity().set(Position { x: 5.0, y: 0.0 });

let sys = world.system::<&Position>().each(|pos| {});

let world_info = world.info();

assert!(world_info.systems_ran_frame == 0);

let delta_time_measured = world.frame_begin(0.0);

world.frame_end();

//TODO
//assert!(world_info.systems_ran_frame == 1);
§See also
Source

pub fn frame_end(&self)

Ends a frame.

This operation must be called at the end of the frame, and always after World::frame_begin().

§Safety

The function should only be run from the main thread.

§See also
Source

pub fn readonly_begin(&self, multi_threaded: bool) -> bool

Begin readonly mode.

When an application does not use World::progress() to control the main loop, it can still use Flecs features such as the defer queue. To stage changes, this function must be called after World::frame_begin().

A call to World::readonly_begin() must be followed by a call to World::readonly_end().

When staging is enabled, modifications to entities are stored to a stage. This ensures that arrays are not modified while iterating. Modifications are merged back to the “main stage” when World::readonly_end() is invoked.

While the world is in staging mode, no structural changes (add/remove/…) can be made to the world itself. Operations must be executed on a stage instead (see World::stage()).

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, so that these can be created on the fly.

These mutations are safe in single-threaded applications, but for multi-threaded applications, the world needs to be entirely immutable. For this purpose, multi-threaded readonly mode exists, which disallows all mutations on the world.

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

Number of stages typically corresponds with number of threads

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 readonly_begin must be followed up with readonly_end(). When readonly_end() is called, all enqueued commands from configured stages are merged back into the world. Calls to readonly_begin() and readonly_end() should always happen from a context where the code has exclusive access to the world. The functions themselves are not thread safe.

§Safety

This function should only be run from the main thread.

§Returns

Whether the world is currently staged and whether it is in readonly mode.

§Example

use flecs_ecs::prelude::*;

#[derive(Component)]
struct Position { x: i32, y: i32 }

let world = World::new();

let stage = world.stage(0);

world.readonly_begin(false);

assert_eq!(stage.count::<Position>(), 0);

world.readonly_end();

world.readonly_begin(false);

stage.entity().set(Position { x: 10, y: 20 });
stage.entity().set(Position { x: 10, y: 20 });

assert_eq!(stage.count::<Position>(), 0);

world.readonly_end();

assert_eq!(stage.count::<Position>(), 2);
§See also
Source

pub fn readonly_end(&self)

End readonly mode.

Leaves staging mode. After this operation, the world may be directly mutated again. By default, this operation also merges data back into the world, unless auto-merging was disabled explicitly.

§Safety

This function should only be run from the main thread.

§Returns

Whether the world is currently staged.

§Example

see World::readonly_begin().

§See also
Source

pub fn is_readonly(&self) -> bool

Test whether the current world object is readonly.

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

§Returns

True if the world or stage is readonly.

§Example
use flecs_ecs::prelude::*;

let world = World::new();

assert!(!world.is_readonly());

world.readonly_begin(false);

assert!(world.is_readonly());

world.readonly_end();

assert!(!world.is_readonly());
§See also
Source

pub fn defer_begin(&self) -> bool

Defers operations until the end of the frame.

When this operation is invoked while iterating, the operations between World::defer_begin() and World::defer_end() are executed at the end of the frame.

§Safety

This operation is thread safe.

§Returns

Whether the operation was successful.

§Example

use flecs_ecs::prelude::*;

#[derive(Component)]
struct Position {
   x: i32,
   y: i32,
}

let world = World::new();

world.defer_begin();

let e = world
    .entity()
    .set(Position { x: 10, y: 20 });

assert!(!e.has::<Position>());

world.defer_end();

assert!(e.has::<Position>());
§See also
Source

pub fn defer_end(&self) -> bool

Ends a block of operations to defer.

This should follow a World::defer_begin() call.

§Safety

This operation is thread safe.

§Returns

Whether the operation was successful.

§Example

see World::defer_begin

§See also
Source

pub fn is_deferred(&self) -> bool

Test whether deferring is enabled.

§Returns

Whether deferring is enabled.

§Example
use flecs_ecs::prelude::*;

let world = World::new();

assert!(!world.is_deferred());

world.defer_begin();

assert!(world.is_deferred());

world.defer_end();

assert!(!world.is_deferred());
§See also
Source

pub fn defer<T>(&self, func: impl FnOnce() -> T) -> T

Defers all operations executed in the passed-in closure.

§Arguments
  • func - The closure to execute.
§Examples
let return_something_if_wanted = world.defer(|| {
    // deferred operations here
});
§See also
Source

pub fn defer_suspend(&self)

Suspends deferring of operations but do flush the queue.

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

An application should invoke World::defer_resume() before World::defer_end() is called. The operation may only be called when deferring is enabled.

§See also
Source

pub fn defer_resume(&self)

Resumes deferring of operations.

§See also
Source

pub fn set_stage_count(&self, stages: i32)

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 World::set_threads() already creates the appropriate number of stages. The World::set_stage_count() operation is useful for applications that want to manage their own stages and/or threads.

§Arguments
  • stages: The number of stages.
§Example
use flecs_ecs::prelude::*;

let world = World::new();

world.set_stage_count(2);

world.readonly_begin(false);

let stage1 = world.stage(0);

let e1 = stage1.entity_named("e1");

world.readonly_end();

assert!(e1.id() != 0);
assert_eq!(e1.name(), "e1");
§See also
Source

pub fn get_stage_count(&self) -> i32

Get number of configured stages.

Return number of stages set by World::set_stage_count().

§Returns

The number of stages used for threading.

§Example
use flecs_ecs::prelude::*;

let world = World::new();

assert_eq!(world.get_stage_count(), 1);

world.set_stage_count(4);

assert_eq!(world.get_stage_count(), 4);
§See also
Source

pub fn stage_id(&self) -> i32

Get current 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.

§Returns

The stage id.

§Example
use flecs_ecs::prelude::*;

let world = World::new();

assert_eq!(world.stage_id(), 0);

world.set_stage_count(4);

assert_eq!(world.stage_id(), 0);

let stage = world.stage(3);

assert_eq!(stage.stage_id(), 3);
§See also
Source

pub fn is_stage(&self) -> bool

Test if is a stage.

If this function returns false, it is guaranteed that this is a valid world object.

§Returns

True if the world is a stage, false if not.

§Example
use flecs_ecs::prelude::*;

let world = World::new();

assert!(!world.is_stage());

let stage = world.stage(0);

assert!(stage.is_stage());
§See also
Source

pub fn merge(&self)

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 World::progress() or after World::readonly_end()).

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

§Example
use flecs_ecs::prelude::*;

#[derive(Component)]
struct Position { x: i32, y: i32 }

let world = World::new();

let e = world.entity();

let stage = world.create_async_stage();

e.mut_current_stage(stage).set(Position { x: 10, y: 20 });

assert!(!e.has::<Position>());

stage.merge();

assert!(e.has::<Position>());
§See also
Source

pub fn stage(&self, stage_id: i32) -> WorldRef<'_>

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 sys::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.

§Arguments
  • stage_id - The index of the stage to retrieve.
§Returns

A thread-specific pointer to the world.

§Example
use flecs_ecs::prelude::*;

let world = World::new();

assert_eq!(world.stage_id(), 0);

world.set_stage_count(4);

assert_eq!(world.stage_id(), 0);

let stage = world.stage(3);

assert_eq!(stage.stage_id(), 3);
§See also
Source

pub fn create_async_stage(&self) -> WorldRef<'_>

Create asynchronous stage.

An asynchronous stage can be used to asynchronously queue operations for later merging with the world. An asynchronous stage is similar to a regular stage, except that it does not allow reading from the world.

Asynchronous stages are never merged automatically, and must therefore be manually merged with the sys::ecs_merge function. It is not necessary to call defer_begin or defer_end before and after enqueuing commands, as an asynchronous stage unconditionally defers operations.

The application must ensure that no commands are added to the stage while the stage is being merged.

An asynchronous stage must be cleaned up by sys::ecs_async_stage_free.

§Returns

The stage.

§Example
use flecs_ecs::prelude::*;

#[derive(Component)]
struct Position { x: i32, y: i32 }

let world = World::new();

let e = world.entity();

let stage = world.create_async_stage();

e.mut_current_stage(stage).set(Position { x: 10, y: 20 });

assert!(!e.has::<Position>());

stage.merge();

assert!(e.has::<Position>());
§See also
  • C++ API: world::async_stage
Source

pub fn get_world(&self) -> WorldRef<'_>

Get actual world.

If the current object points to a stage, this operation will return the actual world.

§Returns

The actual world.

§Example
use flecs_ecs::prelude::*;

let world = World::new();

let stage = world.stage(0);

let world_ref = stage.get_world();

assert!(!world_ref.is_stage());
§See also
  • C++ API: world::get_world
Source

pub fn set_context(&self, ctx: *mut c_void, ctx_free: ecs_ctx_free_t)

Set world context.

Set a context value that can be accessed by anyone that has a reference to the world.

§Arguments
  • ctx - The world context.
  • ctx_free - The free function for the context. Can pass None if no free function is needed.
§Example
use flecs_ecs::prelude::*;
use core::ffi::c_void;

extern "C" fn free_ctx(ctx: *mut c_void) {
   unsafe {
      Box::from_raw(ctx as *mut i32);
  }
}

let world = World::new();

let ctx = Box::leak(Box::new(42));

world.set_context(ctx as *mut i32 as *mut c_void, Some(free_ctx));

assert_eq!(world.context() as *const i32, ctx);
§See also
Source

pub fn context(&self) -> *mut c_void

Get world context.

§Returns

The configured world context.

§Example

See World::set_context.

§See also
Source

pub fn preallocate_entity_count(&self, entity_count: i32)

Preallocate memory for a number of entities.

This function preallocates memory for the entity index.

§Arguments
  • entity_count - Number of entities to preallocate memory for.
§See also
  • C++ API: world::dim
Source

pub fn set_entity_range(&self, min: impl Into<Entity>, max: impl Into<Entity>)

Set the entity range.

This function limits the range of issued entity IDs between min and max.

§Arguments
  • min - Minimum entity ID issued.
  • max - Maximum entity ID issued.
§Example
use flecs_ecs::prelude::*;

let world = World::new();

world.set_entity_range(5000, 0);

let e = world.entity();

assert_eq!(e.id(), 5000);

let e = world.entity();

assert_eq!(e.id(), 5001);
§See also
Source

pub fn enable_range_check(&self, enabled: bool)

Enforce that operations cannot modify entities outside of the specified range.

This function ensures that only entities within the specified range can be modified. Use this function if specific parts of the code are only allowed to modify a certain set of entities, as could be the case for networked applications.

§Arguments
  • enabled - True if the range check should be enabled, false otherwise.
§Example
use flecs_ecs::prelude::*;

let world = World::new();

let e = world.entity();
let e2 = world.entity();

world.set_entity_range(5000, 0);
world.enable_range_check(true);

e.add_id(e2); // panics in debug mode! because e and e2 are outside the range
panic!("in release mode, this does not panic, this is to prevent the test from failing")
§See also
Source

pub fn get_scope(&self) -> Option<EntityView<'_>>

Get the current scope. Get the scope set by set_scope. If no scope is set, this operation will return None.

§Returns

Returns an EntityView representing the current scope. If no scope is set, this operation will return None.

§Example
use flecs_ecs::prelude::*;

let world = World::new();

let e = world.entity_named("scope");

world.set_scope_id(e);

let s = world.get_scope();

assert_eq!(s.unwrap(), e);
§See also
Source

pub fn set_scope_id(&self, id: impl IntoId) -> EntityView<'_>

Set the current scope. This operation sets the scope of the current stage to the provided entity. As a result new entities will be created in this scope, and lookups will be relative to the provided scope. It is considered good practice to restore the scope to the old value.

This method changes the current scope to the entity represented by the provided id.

§Arguments
  • id - The ID of the scope entity to set.
§Returns

Returns an EntityView representing the previous set scope.

§Example
use flecs_ecs::prelude::*;

let world = World::new();

let e = world.entity_named("scope");

// previous scope can be used to set the scope back to the original.
let previous_scope = world.set_scope_id(e);

let s = world.get_scope();

assert_eq!(s.unwrap(), e);
§See also
Source

pub fn set_scope<T: ComponentId>(&self) -> EntityView<'_>

Sets the current scope, but allows the scope type to be inferred from the type parameter. This operation sets the scope of the current stage to the provided entity. As a result new entities will be created in this scope, and lookups will be relative to the provided scope. It is considered good practice to restore the scope to the old value.

§Type Parameters
  • T - The type that implements ComponentId.
§Returns

Returns an EntityView representing the previous set scope.

§Example
use flecs_ecs::prelude::*;

#[derive(Component)]
struct Scope;

let world = World::new();

// previous scope can be used to set the scope back to the original.
let previous_scope = world.set_scope::<Scope>();

let s = world.get_scope();

assert_eq!(s.unwrap(), world.component_id::<Scope>());
§See also
Source

pub fn set_lookup_path( &self, search_path: impl Into<Entity>, ) -> *mut ecs_entity_t

Sets the search path for entity lookup operations.

This function configures the search path used for looking up an entity.

§Best Practices
  • It’s advisable to restore the previous search path after making temporary changes.
§Default Behavior
  • The default search path includes flecs.core.
§Overwriting
  • Providing a custom search path will overwrite the existing search path.
§Considerations
  • If the custom search path doesn’t include flecs.core, operations that rely on looking up names from flecs.core may fail.
§Arguments
  • search_path - The entity to set as the search path.
§Returns

Returns the current search path after the operation.

§See also
Source

pub fn lookup_recursive(&self, name: &str) -> EntityView<'_>

Lookup an entity by name. The entity is searched recursively recursively traversing up the tree until found.

§Panics

Ensure that the entity exists before using it. Use the World::try_lookup_recursive() variant otherwise.

§Arguments
  • name - The name of the entity to lookup.
§Returns

The entity

§Example
use flecs_ecs::prelude::*;

#[derive(Component)]
struct Position { x: i32, y: i32 }

let world = World::new();
let a = world.entity().set(Position { x: 10, y: 20 }).with(|| {
   world.entity_named("X");
 });

let x = world.lookup_recursive("X");
assert!(x.has_id(a));
§See also
Examples found in repository?
examples/flecs/queries/query_setting_variables.rs (line 112)
42fn main() {
43    let world = World::new();
44
45    // Make the ECS aware of the inheritance relationships. Note that IsA
46    // relationship used here is the same as in the prefab example.
47    world.component::<CombatUnit>().is_a::<Unit>();
48    world.component::<MeleeUnit>().is_a::<CombatUnit>();
49    world.component::<RangedUnit>().is_a::<CombatUnit>();
50
51    world.component::<Warrior>().is_a::<MeleeUnit>();
52    world.component::<Wizard>().is_a::<RangedUnit>();
53    world.component::<Marksman>().is_a::<RangedUnit>();
54
55    // Populate store with players and platoons
56    for p in 0..PLAYER_COUNT {
57        let player = if p == 0 {
58            // Give first player a name so we can look it up later
59            world.entity_named("MyPlayer")
60        } else {
61            world.entity()
62        };
63
64        // Add player tag so we can query for all players if we want to
65        player.add::<Player>();
66
67        for _ in 0..PLATOONS_PER_PLAYER {
68            let platoon = world
69                .entity()
70                .add_first::<Player>(player)
71                // Add platoon tag so we can query for all platoons if we want to
72                .add::<Platoon>();
73
74            // Add warriors, wizards and marksmen to the platoon
75            world
76                .entity()
77                .add::<Warrior>()
78                .add_first::<Platoon>(platoon);
79            world
80                .entity()
81                .add::<Marksman>()
82                .add_first::<Platoon>(platoon);
83            world.entity().add::<Wizard>().add_first::<Platoon>(platoon);
84        }
85    }
86
87    // Create a query to find all RangedUnits for a platoon/player. The
88    // equivalent query in the query DSL would look like this:
89    //   (Platoon, $Platoon), Player($Platoon, $Player)
90    //
91    // The way to read how this query is evaluated is:
92    // - find all entities with (Platoon, *), store * in _Platoon
93    // - check if _Platoon has (Player, *), store * in _Player
94    let mut query = world
95        .query::<&RangedUnit>()
96        .with::<&Platoon>()
97        .set_second_name("$platoon")
98        .with_first_name::<&Player>("$player")
99        .set_src_name("$platoon")
100        .build();
101
102    // If we would iterate this query it would return all ranged units for all
103    // platoons & for all players. We can limit the results to just a single
104    // platoon or a single player setting a variable beforehand. In this example
105    // we'll just find all platoons & ranged units for a single player.
106
107    let player_var = query.find_var("player").unwrap();
108    let platoon_var = query.find_var("platoon").unwrap();
109
110    // Iterate query, limit the results to units of MyPlayer
111    query
112        .set_var(player_var, world.lookup_recursive("MyPlayer"))
113        .each_iter(|it, index, _| {
114            let unit = it.entity(index);
115            println!(
116                "Unit id: {} of class {} in platoon id: {} for player {}",
117                unit,
118                it.id(0).to_str(),
119                it.get_var(platoon_var),
120                it.get_var(player_var)
121            );
122        });
123
124    // Output:
125    //  Unit id: 529 of class Wizard in platoon id: 526 for player MyPlayer
126    //  Unit id: 533 of class Wizard in platoon id: 530 for player MyPlayer
127    //  Unit id: 537 of class Wizard in platoon id: 534 for player MyPlayer
128    //  Unit id: 528 of class Marksman in platoon id: 526 for player MyPlayer
129    //  Unit id: 532 of class Marksman in platoon id: 530 for player MyPlayer
130    //  Unit id: 536 of class Marksman in platoon id: 534 for player MyPlayer
131
132    // Try removing the set_var call, this will cause the iterator to return
133    // all units in all platoons for all players.
134}
Source

pub fn lookup(&self, name: &str) -> EntityView<'_>

Lookup entity by name, only the current scope is searched

§Panics

Ensure that the entity exists before using it. Use the World::try_lookup() variant otherwise.

§Arguments
  • name - The name of the entity to lookup.
§Returns

The entity

§See also
Source

pub fn try_lookup_recursive(&self, name: &str) -> Option<EntityView<'_>>

Lookup an entity by name. The entity is searched recursively recursively traversing up the tree until found.

§Arguments
  • name - The name of the entity to lookup.
§Returns

The entity if found, otherwise None.

§See also
Source

pub fn try_lookup(&self, name: &str) -> Option<EntityView<'_>>

Lookup entity by name, only the current scope is searched

§Arguments
  • name - The name of the entity to lookup.
§Returns

The entity if found, otherwise None.

§See also
Source

pub fn set<T: ComponentId + DataComponent + ComponentType<Struct>>( &self, component: T, )

Sets a singleton component of type T on the world.

§Arguments
  • component - The singleton component to set on the world.
§See also
  • C++ API: world::set
Examples found in repository?
examples/flecs/systems/system_time_interval.rs (line 20)
17fn main() {
18    let world = World::new();
19
20    world.set(Timeout { value: 3.5 });
21
22    world
23        .system::<&mut Timeout>()
24        .each_iter(|it, _index, timeout| {
25            timeout.value -= it.delta_time();
26        });
27
28    world.system_named::<()>("Tick").interval(1.0).run(tick);
29
30    world.system_named::<()>("FastTick").interval(0.5).run(tick);
31
32    // Run the main loop at 60 FPS
33    world.set_target_fps(60.0);
34
35    while world.progress() {
36        if world.map::<&Timeout, _>(|timeout| timeout.value <= 0.0) {
37            println!("Timed out!");
38            break;
39        }
40    }
41
42    // Output:
43    // FastTick
44    // Tick
45    // FastTick
46    // FastTick
47    // Tick
48    // FastTick
49    // FastTick
50    // Tick
51    // FastTick
52    // FastTick
53    // Timed out!
54}
More examples
Hide additional examples
examples/flecs/queries/query_singleton.rs (line 19)
15fn main() {
16    let world = World::new();
17
18    // Set singleton
19    world.set(Gravity { value: 9.81 });
20
21    // Set Velocity
22    world.entity_named("e1").set(Velocity { x: 0.0, y: 0.0 });
23    world.entity_named("e2").set(Velocity { x: 0.0, y: 1.0 });
24    world.entity_named("e3").set(Velocity { x: 0.0, y: 2.0 });
25
26    // Create query that matches Gravity as singleton
27    let query = world
28        .query::<(&mut Velocity, &Gravity)>()
29        .term_at(1)
30        .singleton()
31        .build();
32
33    // In a query string expression you can use the $ shortcut for singletons:
34    //   Velocity, Gravity($)
35
36    query.each_entity(|entity, (velocity, gravity)| {
37        velocity.y += gravity.value;
38        println!("Entity {} has {:?}", entity.path().unwrap(), velocity);
39    });
40
41    // Output:
42    // Entity ::e1 has Velocity { x: 0.0, y: 9.81 }
43    // Entity ::e2 has Velocity { x: 0.0, y: 10.81 }
44    // Entity ::e3 has Velocity { x: 0.0, y: 11.81 }
45}
Source

pub fn set_first<First>(&self, second: impl Into<Entity>, first: First)
where First: ComponentId + ComponentType<Struct> + DataComponent,

Set a singleton pair using the second element type and a first id.

§Safety

Caller must ensure that First and second pair id data type is the one provided.

§See also
  • C++ API: world::set
Source

pub fn set_second<Second>(&self, first: impl Into<Entity>, second: Second)
where Second: ComponentId + ComponentType<Struct> + DataComponent,

Set a singleton pair using the second element type and a first id.

§Safety

Caller must ensure that first and Second pair id data type is the one provided.

§See also
  • C++ API: world::set
Source

pub fn set_pair<First, Second>( &self, data: <(First, Second) as ComponentOrPairId>::CastType, )

Set singleton pair. This operation sets the pair value, and uses the first non tag / ZST as type. If the entity did not yet have the pair, it will be added, otherwise overridden.

§See also
  • C++ API: world::set
Source

pub fn modified_id(&self, id: impl Into<Entity>)

signal that singleton component was modified.

§Arguments
  • id - The id of the component that was modified.
§See also
Source

pub fn modified<T>(&self)
where T: ComponentId,

Signal that singleton component was modified.

§Type Parameters
  • T - The type of the component that was modified.
§See also
Source

pub fn try_get<T: GetTupleTypeOperation>( &self, callback: impl for<'e> FnOnce(T::ActualType<'e>), ) -> bool
where T::OnlyType: ComponentOrPairId,

gets a mutable or immutable singleton component and/or relationship(s) from the world. Only one singleton component at a time is retrievable, but you can call this function multiple times within the callback. each component type must be marked & or &mut to indicate if it is mutable or not. use Option wrapper to indicate if the component is optional.

  • try_get assumes when not using Option wrapper, that the entity has the component. If it does not, it will not run the callback. If unsure and you still want to have the callback be ran, use Option wrapper instead.
§Note
  • You cannot get single component tags with this function, use has functionality instead.
  • You can only get relationships with a payload, so where one is not a tag / not a zst. tag relationships, use has functionality instead.
  • This causes the table to lock where the entity belongs to to prevent invalided references, see #Panics. The lock is dropped at the end of the callback.
§Panics
  • This will panic if within the callback you do any operation that could invalidate the reference. This happens when the entity is moved to a different table in memory. Such as adding, removing components or creating/deleting entities where the entity belongs to the same table (which could cause a table grow operation). In case you need to do such operations, you can either do it after the get operation or defer the world with world.defer_begin().
§Returns
  • If the callback has ran.
§Example
use flecs_ecs::prelude::*;

#[derive(Component)]
struct Tag;

#[derive(Component)]
pub struct Position {
    pub x: f32,
    pub y: f32,
}

let world = World::new();

world.set(Position { x: 10.0, y: 20.0 });
world.set_pair::<Tag, Position>(Position { x: 30.0, y: 40.0 });
    
let has_run = world.try_get::<&Position>(|pos| {
   assert_eq!(pos.x, 10.0);
});
assert!(has_run);

let has_run = world.try_get::<&mut(Tag,Position)>(|pos| {
    assert_eq!(pos.x, 30.0);
});
assert!(has_run);
Source

pub fn get<T: GetTupleTypeOperation>( &self, callback: impl for<'e> FnOnce(T::ActualType<'e>), )
where T::OnlyType: ComponentOrPairId,

gets a mutable or immutable singleton component and/or relationship(s) from the world. Only one singleton component at a time is retrievable, but you can call this function multiple times within the callback. each component type must be marked & or &mut to indicate if it is mutable or not. use Option wrapper to indicate if the component is optional.

§Note
  • You cannot get single component tags with this function, use has functionality instead.
  • You can only get relationships with a payload, so where one is not a tag / not a zst. tag relationships, use has functionality instead.
  • This causes the table to lock where the entity belongs to to prevent invalided references, see #Panics. The lock is dropped at the end of the callback.
§Panics
  • This will panic if within the callback you do any operation that could invalidate the reference. This happens when the entity is moved to a different table in memory. Such as adding, removing components or creating/deleting entities where the entity belongs to the same table (which could cause a table grow operation). In case you need to do such operations, you can either do it after the get operation or defer the world with world.defer_begin().

  • get assumes when not using Option wrapper, that the entity has the component. This will panic if the entity does not have the component. If unsure, use Option wrapper or try_get function instead. try_get does not run the callback if the entity does not have the component that isn’t marked Option.

§Example
use flecs_ecs::prelude::*;

#[derive(Component)] struct Tag;

#[derive(Component)]
pub struct Position {
    pub x: f32,
    pub y: f32,
}

let world = World::new();

world.set(Position { x: 10.0, y: 20.0 });
world.set_pair::<Tag, Position>(Position { x: 30.0, y: 40.0 });
    
world.get::<&Position>(|pos| {
    assert_eq!(pos.x, 10.0);
});
world.get::<&mut(Tag,Position)>(|pos| {
    assert_eq!(pos.x, 30.0);    
});
Source

pub fn cloned<T: ClonedTupleTypeOperation>(&self) -> T::ActualType
where T::OnlyType: ComponentOrPairId,

Clones a singleton component and/or relationship from the world and returns it. each component type must be marked &. This helps Rust type checker to determine if it’s a relationship. use Option wrapper to indicate if the component is optional. use () tuple format when getting multiple components.

§Note
  • You cannot clone component tags with this function.
  • You can only clone relationships with a payload, so where one is not a tag / not a zst.
§Panics
  • This will panic if the world does not have the singleton component that isn’t marked Option.
§Example
use flecs_ecs::prelude::*;

#[derive(Component)] struct Tag;

#[derive(Component, Clone)]
pub struct Position {
    pub x: f32,
    pub y: f32,
}

#[derive(Component, Clone)]
pub struct Velocity {
    pub x: f32,
    pub y: f32,
}

let world = World::new();

world.set(Position { x: 10.0, y: 20.0 });
world.set_pair::<Tag, Position>(Position { x: 30.0, y: 40.0 });
    
let pos = world.cloned::<&Position>();
assert_eq!(pos.x, 10.0);

let tag_pos = world.cloned::<&(Tag, Position)>();
assert_eq!(tag_pos.x, 30.0);

let vel = world.cloned::<Option<&Velocity>>();
assert!(vel.is_none());
Source

pub fn try_map<T: GetTupleTypeOperation, Return>( &self, callback: impl for<'e> FnOnce(T::ActualType<'e>) -> Option<Return>, ) -> Option<Return>
where T::OnlyType: ComponentOrPairId,

gets mutable or immutable component(s) and/or relationship(s) from the world in a callback and return a value. each component type must be marked & or &mut to indicate if it is mutable or not. use Option wrapper to indicate if the component is optional.

  • try_map assumes when not using Option wrapper, that the entity has the component. If it does not, it will not run the callback and return None. If unsure and you still want to have the callback be ran, use Option wrapper instead.
§Note
  • You cannot get single component tags with this function, use has functionality instead.
  • You can only get relationships with a payload, so where one is not a tag / not a zst. tag relationships, use has functionality instead.
  • This causes the table to lock where the entity belongs to to prevent invalided references, see #Panics. The lock is dropped at the end of the callback.
§Panics
  • This will panic if within the callback you do any operation that could invalidate the reference. This happens when the entity is moved to a different table in memory. Such as adding, removing components or creating/deleting entities where the entity belongs to the same table (which could cause a table grow operation). In case you need to do such operations, you can either do it after the get operation or defer the world with world.defer_begin().
§Returns
  • a Some(value) if the callback has ran. Where the type of value is specified in Return generic (can be elided). None if the callback has not ran.
§Example
use flecs_ecs::prelude::*;

#[derive(Component)] struct Tag;

#[derive(Component)]
pub struct Velocity {
    pub x: f32,
    pub y: f32,
}

#[derive(Component)]
pub struct Position {
    pub x: f32,
    pub y: f32,
}

let world = World::new();

let entity = world.entity()
                  .set(Position { x: 10.0, y: 20.0 })
                  .set_pair::<Tag, Position>(Position { x: 30.0, y: 40.0 });
    
let pos_x = entity.try_map::<&Position, _>(|(pos)| {
    assert_eq!(pos.x, 10.0);
    Some(pos.x)
});
assert!(pos_x.is_some());
assert_eq!(pos_x.unwrap(), 10.0);

let is_pos_x_10 = entity.try_map::<(Option<&Velocity>, &Position), _>( |(tag, pos)| {
    assert_eq!(pos.x, 10.0);
    assert!(tag.is_none());
    Some(pos.x == 10.0)
});
assert!(is_pos_x_10.is_some());
assert!(is_pos_x_10.unwrap());

// no return type
let has_run = entity.try_map::<(&mut(Tag,Position), &Position),_>(|(tag_pos_rel, pos)| {
    assert_eq!(pos.x, 10.0);
    assert_eq!(tag_pos_rel.x, 30.0);
    Some(())
});
assert!(has_run.is_some());
Source

pub fn map<T: GetTupleTypeOperation, Return>( &self, callback: impl for<'e> FnOnce(T::ActualType<'e>) -> Return, ) -> Return
where T::OnlyType: ComponentOrPairId,

gets mutable or immutable singleton component and/or relationship from the world in a callback. each component type must be marked & or &mut to indicate if it is mutable or not. use Option wrapper to indicate if the component is optional. use () tuple format when getting multiple components.

§Note
  • You cannot get single component tags with this function, use has functionality instead.
  • You can only get relationships with a payload, so where one is not a tag / not a zst. tag relationships, use has functionality instead.
  • This causes the table to lock where the entity belongs to to prevent invalided references, see #Panics. The lock is dropped at the end of the callback.
§Panics
  • This will panic if within the callback you do any operation that could invalidate the reference. This happens when the entity is moved to a different table in memory. Such as adding, removing components or creating/deleting entities where the entity belongs to the same table (which could cause a table grow operation). In case you need to do such operations, you can either do it after the get operation or defer the world with world.defer_begin().

  • get assumes when not using Option wrapper, that the entity has the component. This will panic if the entity does not have the component. If unsure, use Option wrapper or try_get function instead. try_get does not run the callback if the entity does not have the component that isn’t marked Option.

§Example
use flecs_ecs::prelude::*;

#[derive(Component)] struct Tag;

#[derive(Component)]
pub struct Velocity {
    pub x: f32,
    pub y: f32,
}

#[derive(Component)]
pub struct Position {
    pub x: f32,
    pub y: f32,
}

let world = World::new();

let entity = world.entity()
                  .set(Position { x: 10.0, y: 20.0 })
                  .set_pair::<Tag, Position>(Position { x: 30.0, y: 40.0 });

let position_parent = Position { x: 20.0, y: 30.0 };

let pos_actual = entity.map::<&Position, _>(|pos| {
    assert_eq!(pos.x, 10.0);
    // Calculate actual position
    Position {
        x: pos.x + position_parent.x,
        y: pos.y + position_parent.y,
    }
});

let pos_x = entity.map::<(Option<&Velocity>, &Position),_>( |(vel, pos)| {
    assert_eq!(pos.x, 10.0);
    assert!(vel.is_none());
    pos.x
});
assert_eq!(pos_x, 10.0);

let is_x_10 = entity.map::<(&mut(Tag,Position), &Position), _>(|(tag_pos_rel, pos)| {
    assert_eq!(pos.x, 10.0);
    assert_eq!(tag_pos_rel.x, 30.0);
    pos.x == 10.0
});
assert!(is_x_10);
Examples found in repository?
examples/flecs/systems/system_time_interval.rs (line 36)
17fn main() {
18    let world = World::new();
19
20    world.set(Timeout { value: 3.5 });
21
22    world
23        .system::<&mut Timeout>()
24        .each_iter(|it, _index, timeout| {
25            timeout.value -= it.delta_time();
26        });
27
28    world.system_named::<()>("Tick").interval(1.0).run(tick);
29
30    world.system_named::<()>("FastTick").interval(0.5).run(tick);
31
32    // Run the main loop at 60 FPS
33    world.set_target_fps(60.0);
34
35    while world.progress() {
36        if world.map::<&Timeout, _>(|timeout| timeout.value <= 0.0) {
37            println!("Timed out!");
38            break;
39        }
40    }
41
42    // Output:
43    // FastTick
44    // Tick
45    // FastTick
46    // FastTick
47    // Tick
48    // FastTick
49    // FastTick
50    // Tick
51    // FastTick
52    // FastTick
53    // Timed out!
54}
Source

pub fn get_ref<T>(&self) -> CachedRef<'_, T::UnderlyingType>

Get a reference to a singleton component.

A reference allows for quick and safe access to a component value, and is a faster alternative to repeatedly calling get for the same component.

  • T: Component for which to get a reference.

Returns: The reference singleton component.

§See also
  • C++ API: world::get_ref
Source

pub fn singleton<T: ComponentId>(&self) -> EntityView<'_>

Get singleton entity for type.

§Type Parameters
  • T - The component type to get the singleton entity for.
§Returns

The entity representing the component.

§See also
  • C++ API: world::singleton
Source

pub fn target<First>(&self, index: Option<i32>) -> EntityView<'_>
where First: ComponentId,

Gets the target for a given pair from a singleton entity.

This operation returns the target for a given pair. The optional index can be used to iterate through targets, in case the entity has multiple instances for the same relationship.

§Type Parameters
  • First - The first element of the pair.
§Arguments
  • index - The index (None for the first instance of the relationship).
§See also
Source

pub fn target_id( &self, relationship: impl Into<Entity>, index: Option<usize>, ) -> EntityView<'_>

Retrieves the target for a given pair from a singleton entity.

This operation fetches the target associated with a specific pair. An optional index parameter allows iterating through multiple targets if the entity has more than one instance of the same relationship.

§Arguments
  • first - The first element of the pair for which to retrieve the target.
  • index - The index (0 for the first instance of the relationship).
§See also
Source

pub fn has_id(&self, id: impl IntoId) -> bool

Check if world has the provided id.

§Arguments
  • id: The id to check of a pair, entity or component.
§Returns

True if the world has the provided id, false otherwise.

§See also
Source

pub fn has<T>(&self) -> bool

Check if world has the provided type (enum,pair,struct).

§Type Parameters
  • T - The type to check.
§Returns

True if the world has the provided type, false otherwise.

§See also
Source

pub fn has_enum<T>(&self, constant: T) -> bool

Check if world has the provided enum constant.

§Type Parameters
  • T - The enum type.
§Arguments
  • constant - The enum constant to check.
§Returns

True if the world has the provided constant, false otherwise.

§See also
Source

pub fn add_id<T>(&self, id: T) -> EntityView<'_>
where T: IntoId,

Add a singleton component by id. id can be a component, entity or pair id.

§Arguments
  • id: The id of the component to add.
§Returns

EntityView handle to the singleton component.

§See also
  • C++ API: world::add
Source

pub fn add<T: ComponentOrPairId>(&self) -> EntityView<'_>

Add a singleton component.

§Type Parameters
  • T - The component to add.
§Returns

EntityView handle to the singleton component.

§See also
  • C++ API: world::add
Source

pub fn add_enum<T: ComponentId + ComponentType<Enum> + EnumComponentInfo>( &self, enum_value: T, ) -> EntityView<'_>

Add a singleton enum component.

§Type Parameters
  • T - The enum component to add.
§Returns

EntityView handle to the singleton enum component.

§See also
  • C++ API: world::add
Source

pub fn add_second<Second: ComponentId + TagComponent>( &self, first: impl Into<Entity>, ) -> EntityView<'_>

Add a singleton pair by first id.

§Safety

Caller must ensure the id is a non ZST types. Otherwise it could cause the payload to have uninitialized data.

§Returns

EntityView handle to the singleton pair.

Source

pub fn add_first<First: ComponentId + TagComponent>( &self, second: impl Into<Entity>, ) -> EntityView<'_>

Add a singleton pair by second id.

§Safety

Caller must ensure the id is a non ZST types. Otherwise it could cause the payload to have uninitialized data.

§Returns

EntityView handle to the singleton pair.

§See also
  • C++ API: world::add
Source

pub fn add_pair_enum<First, Second>(&self, enum_value: Second) -> EntityView<'_>
where First: ComponentId, Second: ComponentId + ComponentType<Enum> + EnumComponentInfo,

Add a singleton pair with enum tag.

§Type Parameters
  • First - The first element of the pair.
  • Second - The second element of the pair of type enum.
§Arguments
  • enum_value: The enum value to add.
§Returns

EntityView handle to the singleton pair.

§See also
  • C++ API: world::add
Source

pub fn remove_id<T>(&self, id: T) -> EntityView<'_>
where T: IntoId,

Remove singleton component by id. id can be a component, entity or pair id.

§Arguments
  • id: The id of the component to remove.
§See also
  • C++ API: world::remove
Source

pub fn remove<T: ComponentOrPairId>(&self)

Remove singleton component.

§Type Parameters
  • T - The component to remove.
§See also
  • C++ API: world::remove
Source

pub fn remove_enum_tag<First, Second>(&self, enum_value: Second)
where First: ComponentId, Second: ComponentId + ComponentType<Enum> + EnumComponentInfo,

Remove singleton pair with enum tag.

§Type Parameters
  • First - The first element of the pair.
  • Second - The second element of the pair.
§Arguments
  • enum_value - The enum value to remove.
§See also
  • C++ API: world::remove
Source

pub fn remove_second<Second: ComponentId>(&self, first: impl Into<Entity>)

Remove singleton pair by first id.

§Type Parameters
  • Second - The second element of the pair.
§Arguments
  • first: The first element of the pair.
§See also
  • C++ API: world::remove
Source

pub fn remove_first<First: ComponentId>(&self, second: impl Into<Entity>)

Remove singleton pair by second id.

§Type Parameters
  • First - The first element of the pair.
§Arguments
  • second: The second element of the pair.
§See also
  • C++ API: world::remove
Source

pub fn each_child(&self, callback: impl FnMut(EntityView<'_>))

Iterate entities in root of world

§Arguments
  • func - The function invoked for each child. Must match the signature FnMut(EntityView).
§See also
  • C++ API: world::children
Source

pub fn set_alias_component<T: ComponentId>(&self, alias: &str) -> EntityView<'_>

create alias for component

§Type Parameters
  • T - The component type to create an alias for.
§Arguments
  • alias - The alias to create.
§Returns

The entity representing the component.

§See also
  • C++ API: world::use
Source

pub fn set_alias_entity_by_name( &self, name: &str, alias: &str, ) -> EntityView<'_>

create alias for entity by name

§Arguments
  • name - The name of the entity to create an alias for.
  • alias - The alias to create.
§Returns

The entity found by name.

§See also
  • C++ API: world::use
Source

pub fn set_alias_entity(&self, entity: impl Into<Entity>, alias: &str)

create alias for entity

§Arguments
  • entity - The entity to create an alias for.
  • alias - The alias to create.
§See also
  • C++ API: world::use
Source

pub fn count_id(&self, id: impl IntoId) -> i32

Count entities with the provided id.

§Arguments
  • id - The id to count.
§Returns

The number of entities with the provided id.

§See also
  • C++ API: world::count
Source

pub fn count<T: ComponentOrPairId>(&self) -> i32

Count entities with the provided component.

§Type Parameters
  • T - The component to count.
§Returns

The number of entities with the provided component.

§See also
  • C++ API: world::count
Examples found in repository?
examples/flecs/systems/system_sync_point_delete.rs (line 80)
17fn main() {
18    let world = World::new();
19
20    // This example shows how to annotate systems that delete entities, in a way
21    // that allows the scheduler to correctly insert sync points. See the
22    // sync_point example for more details on sync points.
23    //
24    // While annotating a system for a delete operation follows the same
25    // design as other operations, one key difference is that a system often
26    // does not know which components a to be deleted entity has. This makes it
27    // impossible to annotate the system in advance for specific components.
28    //
29    // To ensure the scheduler is still able to insert the correct sync points,
30    // a system can use a wildcard to indicate that any component could be
31    // modified by the system, which forces the scheduler to insert a sync.
32
33    // Basic move system.
34    world
35        .system_named::<(&mut Position, &Velocity)>("Move")
36        .each(|(p, v)| {
37            p.x += v.x;
38            p.y += v.y;
39        });
40
41    // Delete entities when p.x >= 3. Add wildcard annotation to indicate any
42    // component could be written by the system. Position itself is added as
43    // const, since inside the system we're only reading it.
44    world
45        .system_named::<&Position>("DeleteEntity")
46        .write::<flecs::Wildcard>()
47        .each_entity(|e, p| {
48            if p.x >= 3.0 {
49                println!("Delete entity {}", e.name());
50                e.destruct();
51            }
52        });
53
54    // Print resulting Position. Note that this system will never print entities
55    // that have been deleted by the previous system.
56    world
57        .system_named::<&Position>("PrintPosition")
58        .each_entity(|e, p| {
59            println!("{}: {{ {}, {} }}", e.name(), p.x, p.y);
60        });
61
62    // Create a few test entities for a Position, Velocity query
63    world
64        .entity_named("e1")
65        .set(Position { x: 0.0, y: 0.0 })
66        .set(Velocity { x: 1.0, y: 2.0 });
67
68    world
69        .entity_named("e2")
70        .set(Position { x: 1.0, y: 2.0 })
71        .set(Velocity { x: 1.0, y: 2.0 });
72
73    // Run systems. Debug logging enables us to see the generated schedule.
74    // NOTE flecs C / flecs_ecs_sys needs to be build in debug mode to see the logging.
75    // use the feature flag "sys_build_debug" to enable debug build of flecs C.
76
77    set_log_level(1);
78
79    while world.progress() {
80        if world.count::<Position>() == 0 {
81            break; // No more entities left with Position
82        }
83    }
84    set_log_level(-1);
85
86    // world
87    //     .get::<Snap>()
88    //     .test("system_sync_point_delete".to_string()));
89
90    // Output:
91    //  info: pipeline rebuild
92    //  info: | schedule: threading: 0, staging: 1:
93    //  info: | | system Move
94    //  info: | | system DeleteEntity
95    //  info: | | merge
96    //  info: | schedule: threading: 0, staging: 1:
97    //  info: | | system PrintPosition
98    //  info: | | merge
99    //  e1: { 1, 2 }
100    //  e2: { 2, 4 }
101    //  Delete entity e2
102    //  e1: { 2, 4 }
103    //  Delete entity e1
104
105    // Removing the wildcard annotation from the DeleteEntity system will
106    // remove the first sync point.
107
108    // Note how after both entities are deleted, all three systems will be de-activated and not ran by the scheduler
109}
Source

pub fn count_second<Second: ComponentId>(&self, first: impl Into<Entity>) -> i32

Count entities with the provided pair.

§Type Parameters
  • Second - The second element of the pair.
§Arguments
  • first - The ID of the first element of the pair.
§Returns

The number of entities with the provided pair.

§See also
  • C++ API: world::count
Source

pub fn count_first<First: ComponentId>(&self, second: impl Into<Entity>) -> i32

Count entities with the provided pair.

§Type Parameters
  • First - The first element of the pair.
§Arguments
  • second - The ID of the second element of the pair.
§Returns

The number of entities with the provided pair.

§See also
  • C++ API: world::count
Source

pub fn count_enum<T: ComponentId + ComponentType<Enum> + EnumComponentInfo>( &self, enum_value: T, ) -> i32

Count entities with the provided enum constant.

§Type Parameters
  • T - The enum type.
§Arguments
  • constant - The enum constant to count.
§Returns

The number of entities with the provided enum constant.

§See also
  • C++ API: world::count
Source

pub fn count_enum_tag_pair<First, Second>(&self, enum_value: Second) -> i32
where First: ComponentId, Second: ComponentId + ComponentType<Enum> + EnumComponentInfo,

Count entities with the provided pair enum tag.

§Type Parameters
  • First - The first element of the pair.
  • Second - The second element of the pair.
§Arguments
  • enum_value - The enum value to count.
§Returns

The number of entities with the provided pair enum tag.

§See also
  • C++ API: world::count
Source

pub fn run_in_scope_with_id( &self, parent_id: impl Into<Entity>, func: impl FnMut(), )

All entities created in function are created in scope. All operations called in function (such as lookup) are relative to scope.

§Arguments
  • parent_id - The id of the scope to use.
  • func - The function to run.
§See also
  • C++ API: world::scope
Source

pub fn run_in_scope_with<T: ComponentId>(&self, func: impl FnMut())

All entities created in function are created in scope. All operations called in function (such as lookup) are relative to scope.

§Type Parameters
  • T - The component type to use as scope / parent.
§Arguments
  • func - The function to run.
§See also
  • C++ API: world::scope
Source

pub fn scope_id(&self, parent_id: impl IntoId, f: impl FnMut(&World))

Use provided scope for operations ran on returned world. Operations need to be ran in a single statement

§Arguments
  • parent_id - The id of the scope to use.
§Returns

A scoped world.

§See also
  • C++ API: world::scope
Source

pub fn scope<T: ComponentId>(&self, f: impl FnMut(&World))

Use provided scope for operations ran on returned world. Operations need to be ran in a single statement

§Type Parameters
  • T - The component type to use as scope.
§Returns

A scoped world.

§See also
  • C++ API: world::scope
Source

pub fn scope_name(&self, name: &str, f: impl FnMut(&World))

Use provided scope of name for operations ran on returned world. Operations need to be ran in a single statement

§Arguments
  • name - The name of the scope to use.
§Returns

A scoped world.

§See also
  • C++ API: world::scope
Source

pub fn with_id(&self, id: impl IntoId, func: impl FnMut())

all entities created in function are created with id

§Arguments
  • id: The id to create entities with.
  • func: The function to run.
§See also
  • C++ API: world::with
Source

pub fn with<T: ComponentOrPairId>(&self, func: impl FnMut())

Entities created in function are created with component

§Type Parameters
  • T: The component type.
§Arguments
  • func: The function to run.
§See also
  • C++ API: world::with
Source

pub fn with_second<Second: ComponentId>( &self, first: impl Into<Entity>, func: impl FnMut(), )

Entities created in function are created with pair

§Type Parameters
  • Second: The second element of the pair.
§Arguments
  • first: The first element of the pair.
  • func: The function to run.
§See also
  • C++ API: world::with
Source

pub fn with_first<First: ComponentId>( &self, second: impl Into<Entity>, func: impl FnMut(), )

Entities created in function are created with pair

§Type Parameters
  • First: The first element of the pair.
§Arguments
  • second: The second element of the pair.
  • func: The function to run.
§See also
  • C++ API: world::with
Source

pub fn with_enum<T>(&self, enum_value: T, func: impl FnMut())

Entities created in function are created with enum constant

§Type Parameters
  • T: The enum type.
§Arguments
  • enum_value: The enum value to give the entity.
  • func: The function to run.
§See also
  • C++ API: world::with
Source

pub fn with_enum_pair<First, Second>( &self, enum_value: Second, func: impl FnMut(), )
where First: ComponentId, Second: ComponentId + ComponentType<Enum> + EnumComponentInfo,

Entities created in function are created with enum tag pair

§Type Parameters
  • First: The first element of the pair.
  • Second: The enum component type.
§Arguments
  • enum_value: The enum value to give the entity.
  • func: The function to run.
§See also
  • C++ API: world::with
Source

pub fn delete_with_id(&self, id: impl IntoId)

Delete all entities with the given id

§Arguments
  • id: The id to delete.
§See also
  • C++ API: world::delete_with
Source

pub fn delete_entities_with<T: ComponentOrPairId>(&self)

Delete all entities with the given component

§Type Parameters
  • T: The component type to delete.
§See also
  • C++ API: world::delete_with
Source

pub fn delete_with_second<Second: ComponentId>(&self, first: impl Into<Entity>)

Delete all entities with the given pair

§Type Parameters
  • Second: The second element of the pair.
§Arguments
  • first: The first id of the pair.
§See also
  • C++ API: world::delete_with
Source

pub fn delete_entities_with_second_id<First: ComponentId>( &self, second: impl Into<Entity>, )

Delete all entities with the given pair

§Type Parameters
  • First: The first element of the pair.
§Arguments
  • second: The second id of the pair.
§See also
  • C++ API: world::delete_with
Source

pub fn delete_with_enum<T: ComponentId + ComponentType<Enum> + EnumComponentInfo>( &self, enum_value: T, )

Delete all entities with the given enum constant

§Type Parameters
  • T: The enum type.
§Arguments
  • enum_value: The enum value to query against for deletion.
§See also
  • C++ API: world::delete_with
Source

pub fn delete_with_enum_pair<First, Second>(&self, enum_value: Second)
where First: ComponentId, Second: ComponentId + ComponentType<Enum> + EnumComponentInfo,

Delete all entities with the given enum tag pair / relationship

§Type Parameters
  • First: The first element of the pair.
  • Second: The enum component type.
§Arguments
  • enum_value: The enum value to query against for deletion.
§See also
  • world::delete_with
Source

pub fn remove_all_id(&self, id: impl IntoId)

Remove all instances of the given id from entities

§Arguments
  • id: The id to remove.
§See also
  • C++ API: world::remove_all
Source

pub fn remove_all<T: ComponentOrPairId>(&self)

Remove all instances of the given component from entities

§Type Parameters
  • T: The component type to remove.
§See also
  • C++ API: world::remove_all
Source

pub fn remove_all_second<Second: ComponentId>(&self, first: impl Into<Entity>)

Remove all instances of the given pair from entities

§Type Parameters
  • Second: The second element of the pair.
§Arguments
  • first: The first id of the pair.
§See also
  • C++ API: world::remove_all
Source

pub fn remove_all_first<First: ComponentId>(&self, second: impl Into<Entity>)

Remove all instances of the given pair from entities

§Type Parameters
  • First: The first element of the pair.
§Arguments
  • second: The second id of the pair.
§See also
  • C++ API: world::remove_all
Source

pub fn remove_all_enum<T: ComponentId + ComponentType<Enum> + EnumComponentInfo>( &self, enum_value: T, )

Remove all instances with the given enum constant from entities

§Type Parameters
  • T: The enum type.
§Arguments
  • enum_value: The enum value to query against for removal.
§See also
  • C++ API: world::remove_all
Source

pub fn remove_all_enum_pair<First, Second>(&self, enum_value: Second)
where First: ComponentId, Second: ComponentId + ComponentType<Enum> + EnumComponentInfo,

Remove all instances with the given enum tag pair / relationship from entities

§Type Parameters
  • First: The first element of the pair.
  • Second: The enum component type.
§Arguments
  • enum_value: The enum value to query against for removal.
§See also
  • C++ API: world::remove_all
Source

pub fn exists(&self, entity: impl Into<Entity>) -> bool

Checks if the given entity ID exists in the world.

§Arguments
  • entity - The entity to check.
§Returns

True if the entity exists, false otherwise.

§See also
  • C++ API: world::exists
Source

pub fn is_alive(&self, entity: impl Into<Entity>) -> bool

Checks if the given entity ID is alive in the world.

§See also
  • C++ API: world::is_alive
Source

pub fn is_valid(&self, entity: impl Into<Entity>) -> bool

Checks if the given entity ID is valid. Invalid entities cannot be used with API functions.

§See also
  • C++ API: world::is_valid
Source

pub fn get_alive(&self, entity: impl Into<Entity>) -> EntityView<'_>

Get alive entity for id.

§Arguments
  • entity - The entity to check
§Returns

The entity with the current generation. If the entity is not alive, this function will return an Entity of 0. Use try_get_alive if you want to return an Option<EntityView>.

§See also
  • C++ API: world::try_get_alive
Examples found in repository?
examples/flecs/systems/system_mutate_entity_handle.rs (line 48)
16fn main() {
17    let world = World::new();
18
19    // System that deletes an entity after a timeout expires
20    world
21        .system::<&mut Timeout>()
22        .each_iter(|it, _index, timeout| {
23            timeout.value -= it.delta_time();
24            if timeout.value <= 0.0 {
25                // Delete the entity
26
27                // To make sure the delete operation is enqueued (see
28                // mutate_entity example for more details) we need to provide it
29                // with a mutable context (stage) using the mut() function. If
30                // we don't provide a mutable context, the operation will be
31                // attempted on the context stored in the flecs::entity object,
32                // which would throw a readonly error.
33
34                // To catch these errors at compile time, replace the type of
35                // to_delete with flecs::entity_view. This class does not have
36                // any methods for mutating the entity, which forces the code to
37                // first call mut().
38
39                // The it.world() function can be used to provide the context:
40                //   t.to_delete.mut(it.world()).destruct();
41                //
42                // The current entity can also be used to provide context. This
43                // is useful for functions that accept a flecs::entity:
44                //   t.to_delete.mut(it.entity(index)).destruct();
45                //
46                // A shortcut is to use the iterator directly:
47                let world = it.world();
48                let to_delete = world.get_alive(timeout.to_delete);
49                println!("Expire: {} deleted!", to_delete.name());
50                to_delete.destruct();
51            }
52        });
53
54    // System that prints remaining expiry time
55    world.system::<&Timeout>().each_entity(|e, timeout| {
56        let world = e.world();
57        let to_delete = world.get_alive(timeout.to_delete);
58        println!(
59            "PrintExpire: {} has {:.2} seconds left",
60            to_delete.name(),
61            timeout.value
62        );
63    });
64
65    // Observer that triggers when entity is actually deleted
66    world
67        .observer::<flecs::OnRemove, &Tag>()
68        .each_entity(|e, _tag| {
69            println!("Expired: {} actually deleted", e.name());
70        });
71
72    let to_delete = world.entity_named("ToDelete").add::<Tag>();
73
74    world.entity_named("MyEntity").set(Timeout {
75        to_delete: to_delete.id(),
76        value: 2.5,
77    });
78
79    world.set_target_fps(1.0);
80
81    while world.progress() {
82        // If entity is no longer alive, exit
83        if !to_delete.is_alive() {
84            break;
85        }
86
87        println!("Tick...");
88    }
89
90    // Output:
91    //  PrintExpire: ToDelete has 2.00 seconds left
92    //  Tick...
93    //  PrintExpire: ToDelete has 0.98 seconds left
94    //  Tick...
95    //  Expire: ToDelete deleted!
96    //  PrintExpire: ToDelete has -0.03 seconds left
97    //  Expired: ToDelete actually deleted
98}
Source

pub fn try_get_alive(&self, entity: impl Into<Entity>) -> Option<EntityView<'_>>

Get alive entity for id.

§Arguments
  • entity - The entity to check
§Returns

The entity with the current generation. If the entity is not alive, this function will return None.

§See also
  • C++ API: world::try_get_alive
Source

pub fn make_alive(&self, entity: impl Into<Entity>) -> EntityView<'_>

Ensures that entity with provided generation is alive. This operation will fail if an entity exists with the same id and a different, non-zero generation.

§Arguments
  • entity - The entity to ensure is alive.
§Returns

The entity with the provided generation.

§See also
  • C++ API: world::make_alive
Source

pub fn run_post_frame(&self, action: ecs_fini_action_t, ctx: *mut c_void)

Run callback after completing frame

§Arguments
  • action - The action to run.
  • ctx - The context to pass to the action.
§See also
  • C++ API: world::run_post_frame
Source

pub fn entity_from_enum<T>(&self, enum_value: T) -> EntityView<'_>

Convert enum constant to entity

§Type Parameters
  • T - The enum type.
§Arguments
  • enum_value - The enum value to convert.
§Returns

EntityView wrapping the id of the enum constant.

§See also
  • C++ API: world::entity
Source

pub fn entity_from_named<'a, T: ComponentId>( &'a self, name: &str, ) -> EntityView<'a>

Create an entity that’s associated with a type and name

§Type Parameters
  • T - The component type to associate with the new entity.
§Arguments
  • name - The name to use for the new entity.
§See also
  • C++ API: world::entity
Source

pub fn entity_from<T: ComponentId>(&self) -> EntityView<'_>

Create an entity that’s associated with a type

§Type Parameters
  • T - The component type to associate with the new entity.
§See also
  • C++ API: world::entity
Source

pub fn entity_named(&self, name: &str) -> EntityView<'_>

Create an entity that’s associated with a name. The name does an extra allocation if it’s bigger than 24 bytes. To avoid this, use entity_named_cstr. length of 24 bytes: "hi this is 24 bytes long"

Named entities can be looked up with the lookup functions. Entity names may be scoped, where each element in the name is separated by “::”. For example: “Foo::Bar”. If parts of the hierarchy in the scoped name do not yet exist, they will be automatically created.

§Example
use flecs_ecs::prelude::*;

let world = World::new();

let entity = world.entity_named("Foo");
assert_eq!(entity.get_name(), Some("Foo"));
§See also
Examples found in repository?
examples/flecs/queries/query_find_entity.rs (line 14)
11fn main() {
12    let world = World::new();
13    // Create a few test entities for a Position query
14    world.entity_named("e1").set(Position { x: 10.0, y: 20.0 });
15
16    world.entity_named("e2").set(Position { x: 20.0, y: 30.0 });
17
18    // Create a simple query for component Position
19    let query = world.new_query::<&Position>();
20
21    let entity: Option<EntityView> = query.find(|pos| (pos.x - 20.0).abs() < f32::EPSILON);
22
23    if let Some(entity) = entity {
24        println!("Entity found: {:?}", entity.path().unwrap());
25    } else {
26        println!("Entity not found");
27    }
28
29    // Output:
30    //  Entity found: "::e2"
31}
More examples
Hide additional examples
examples/flecs/observers/observer_yield_existing.rs (line 22)
18fn main() {
19    let world = World::new();
20
21    // Create existing entities with Position component
22    world.entity_named("e1").set(Position { x: 10.0, y: 20.0 });
23    world.entity_named("e2").set(Position { x: 20.0, y: 30.0 });
24
25    // Create an observer for three events
26    world
27        .observer::<flecs::OnSet, &Position>()
28        .yield_existing()
29        .each_iter(|it, index, pos| {
30            println!(
31                " - {}: {}: {}: {{ {}, {} }}",
32                it.event().name(),
33                it.event_id().to_str(),
34                it.entity(index),
35                pos.x,
36                pos.y
37            );
38        });
39
40    // Output:
41    //  - OnSet: Position: e1: { 10, 20 }
42    //  - OnSet: Position: e2: { 20, 30 }
43}
examples/flecs/entities/entity_hooks.rs (line 29)
14fn main() {
15    let world = World::new();
16
17    world
18        .component::<Position>()
19        .on_add(|entity, _pos| {
20            println!("added Position to {:?}", entity.name());
21        })
22        .on_remove(|entity, pos| {
23            println!("removed {:?} from {:?}", pos, entity.name());
24        })
25        .on_set(|entity, pos| {
26            println!("set {:?} for {:?}", pos, entity.name());
27        });
28
29    let entity = world.entity_named("Bob");
30
31    entity.set(Position { x: 10.0, y: 20.0 });
32
33    // This operation changes the entity's archetype, which invokes a move
34    // add is used for adding tags.
35    entity.add::<Tag>();
36
37    entity.destruct();
38
39    // Output:
40    //  added Position { x: 0.0, y: 0.0 } to "Bob"
41    //  set Position { x: 10.0, y: 20.0 } for "Bob"
42    //  removed Position { x: 10.0, y: 20.0 } from "Bob"
43}
examples/flecs/observers/observer_custom_event.rs (line 32)
14fn main() {
15    let world = World::new();
16
17    // Create an observer for the custom event
18    world
19        .observer::<MyEvent, &Position>()
20        .each_iter(|it, index, _pos| {
21            println!(
22                " - {}: {}: {}",
23                it.event().name(),
24                it.event_id().to_str(),
25                it.entity(index)
26            );
27        });
28
29    // The observer query can be matched against the entity, so make sure it
30    // has the Position component before emitting the event. This does not
31    // trigger the observer yet.
32    let entity = world.entity_named("e1").set(Position { x: 10.0, y: 20.0 });
33
34    // Emit the custom event. This triggers the observer.
35    world
36        .event()
37        .add::<Position>()
38        .entity(entity)
39        .emit(&MyEvent);
40
41    // Output:
42    //  - MyEvent: Position: e1
43}
examples/flecs/observers/observer_two_components.rs (line 41)
21fn main() {
22    let world = World::new();
23
24    // Create observer for custom event
25    world
26        .observer::<flecs::OnSet, (&Position, &Velocity)>()
27        .each_iter(|it, index, (pos, vel)| {
28            println!(
29                " - {}: {}: {}: p: {{ {}, {} }}, v: {{ {}, {} }}",
30                it.event().name(),
31                it.event_id().to_str(),
32                it.entity(index).name(),
33                pos.x,
34                pos.y,
35                vel.x,
36                vel.y
37            );
38        });
39
40    // Create entity, set Position (emits EcsOnSet, does not yet match observer)
41    let entity = world.entity_named("e").set(Position { x: 10.0, y: 20.0 });
42
43    // Set Velocity (emits EcsOnSet, matches observer)
44    entity.set(Velocity { x: 1.0, y: 2.0 });
45
46    // Output:
47    //  - OnSet: Velocity: e: p: { 10, 20 }, v: { 1, 2 }
48}
examples/flecs/queries/query_wildcard.rs (line 25)
17fn main() {
18    let world = World::new();
19
20    // Create a query that matches edible components
21    let query = world.new_query::<&(EatsAmount, flecs::Wildcard)>();
22
23    // Create a few entities that match the query
24    world
25        .entity_named("Bob")
26        .set_pair::<EatsAmount, Apples>(EatsAmount { amount: 10 })
27        .set_pair::<EatsAmount, Pears>(EatsAmount { amount: 5 });
28
29    world
30        .entity_named("Alice")
31        .set_pair::<EatsAmount, Apples>(EatsAmount { amount: 4 });
32
33    // Iterate the query with a flecs::iter. This makes it possible to inspect
34    // the pair that we are currently matched with.
35    query.each_iter(|it, index, eats| {
36        let entity = it.entity(index);
37        let pair = it.pair(0).unwrap();
38        let food = pair.second_id();
39
40        println!("{} eats {} {}", entity, eats.amount, food);
41    });
42
43    // Output:
44    //  Alice eats 4 Apples
45    //  Bob eats 10 Apples
46    //  Bob eats 5 Pears
47}
Source

pub fn entity_named_cstr(&self, name: &CStr) -> EntityView<'_>

Create an entity that’s associated with a name. The name must be a valid C str. No extra allocation is done.

Named entities can be looked up with the lookup functions. Entity names may be scoped, where each element in the name is separated by “::”. For example: “Foo::Bar”. If parts of the hierarchy in the scoped name do not yet exist, they will be automatically created.

§Example
use flecs_ecs::prelude::*;

let world = World::new();

let entity = world.entity_named("Foo");
assert_eq!(entity.get_name(), Some("Foo"));
§See also
Source

pub fn entity(&self) -> EntityView<'_>

Create a new entity.

§See also
Examples found in repository?
examples/flecs/relationships/relationships_symmetric.rs (line 15)
7fn main() {
8    let world = World::new();
9
10    // Register TradesWith as symmetric relationship. Symmetric relationships
11    // go both ways, adding (R, B) to A will also add (R, A) to B.
12    world.component::<TradesWith>().add::<flecs::Symmetric>();
13
14    // Create two players
15    let player_1 = world.entity();
16    let player_2 = world.entity();
17
18    // Add (TradesWith, player_2) to player_1. This also adds
19    // (TradesWith, player_1) to player_2.
20    player_1.add_first::<TradesWith>(player_2);
21
22    // Log platoon of unit
23    println!(
24        "Player 1 trades with Player 2: {}",
25        player_1.has_first::<TradesWith>(player_2)
26    ); // true
27    println!(
28        "Player 2 trades with Player 1: {}",
29        player_2.has_first::<TradesWith>(player_1)
30    ); // true
31
32    // Output:
33    //  Player 1 trades with Player 2: true
34    //  Player 2 trades with Player 1: true
35}
More examples
Hide additional examples
examples/flecs/systems/system_custom_phases_no_builtin.rs (line 22)
15fn main() {
16    let world = World::new();
17
18    // Create three custom phases. Note that the phases have the Phase tag,
19    // which is necessary for the builtin pipeline to discover which systems it
20    // should run.
21
22    let update = world.entity().add::<flecs::pipeline::Phase>();
23
24    let physics = world
25        .entity()
26        .add::<flecs::pipeline::Phase>()
27        .depends_on_id(update);
28
29    let collisions = world
30        .entity()
31        .add::<flecs::pipeline::Phase>()
32        .depends_on_id(physics);
33
34    // Create 3 dummy systems.
35    world
36        .system_named::<()>("CollisionSystem")
37        .kind_id(collisions)
38        .run(sys);
39
40    world
41        .system_named::<()>("PhysicsSystem")
42        .kind_id(physics)
43        .run(sys);
44
45    world
46        .system_named::<()>("GameSystem")
47        .kind_id(update)
48        .run(sys);
49
50    // Run pipeline
51    world.progress();
52
53    // Output:
54    //   system GameSystem
55    //   system PhysicsSystem
56    //   system CollisionSystem
57}
examples/flecs/systems/system_custom_phases.rs (line 22)
15fn main() {
16    let world = World::new();
17
18    // Create two custom phases that branch off of EcsOnUpdate. Note that the
19    // phases have the Phase tag, which is necessary for the builtin pipeline
20    // to discover which systems it should run.
21    let physics = world
22        .entity()
23        .add::<flecs::pipeline::Phase>()
24        .depends_on::<flecs::pipeline::OnUpdate>();
25
26    let collisions = world
27        .entity()
28        .add::<flecs::pipeline::Phase>()
29        .depends_on_id(physics);
30
31    // Create 3 dummy systems.
32    world
33        .system_named::<()>("CollisionSystem")
34        .kind_id(collisions)
35        .run(sys);
36
37    world
38        .system_named::<()>("PhysicsSystem")
39        .kind_id(physics)
40        .run(sys);
41
42    world
43        .system_named::<()>("GameSystem")
44        .kind::<flecs::pipeline::OnUpdate>()
45        .run(sys);
46
47    // Run pipeline
48    world.progress();
49
50    // Output:
51    //   system GameSystem
52    //   system PhysicsSystem
53    //   system CollisionSystem
54}
examples/flecs/relationships/relationships_exclusive.rs (line 16)
8fn main() {
9    let world = World::new();
10
11    // Register Platoon as exclusive relationship. This ensures that an entity
12    // can only belong to a single Platoon.
13    world.component::<Platoon>().add::<flecs::Exclusive>();
14
15    // Create two platoons
16    let platoon_1 = world.entity();
17    let platoon_2 = world.entity();
18
19    // Create a unit
20    let unit = world.entity();
21
22    // Add unit to platoon 1
23    unit.add_first::<Platoon>(platoon_1);
24
25    // Log platoon of unit
26    println!(
27        "Unit in platoon 1: {}",
28        unit.has_first::<Platoon>(platoon_1)
29    ); // true
30    println!(
31        "Unit in platoon 2: {}",
32        unit.has_first::<Platoon>(platoon_2)
33    ); // false
34
35    println!();
36
37    // Add unit to platoon 2. Because Platoon is an exclusive relationship, this
38    // both removes (Platoon, platoon_1) and adds (Platoon, platoon_2) in a
39    // single operation.
40    unit.add_first::<Platoon>(platoon_2);
41
42    // Log platoon of unit
43    println!(
44        "Unit in platoon 1: {}",
45        unit.has_first::<Platoon>(platoon_1)
46    ); // false
47    println!(
48        "Unit in platoon 2: {}",
49        unit.has_first::<Platoon>(platoon_2)
50    ); // true
51
52    // Output:
53    //  Unit in platoon 1: true
54    //  Unit in platoon 2: false
55    //
56    //  Unit in platoon 1: false
57    //  Unit in platoon 2: true
58}
examples/flecs/systems/system_ctx.rs (line 84)
43fn main() {
44    let world = World::new();
45
46    // Applications can pass context data to a system. A common use case where this
47    // comes in handy is when a system needs to iterate more than one query. The
48    // following example shows how to pass a custom query into a system for a simple
49    // collision detection example.
50
51    let mut query_collide = world.new_query::<(&Position, &Radius)>();
52
53    let sys = world
54        .system::<(&Position, &Radius)>()
55        .set_context(&mut query_collide as *mut Query<(&Position, &Radius)> as *mut c_void)
56        .each_iter(|mut it, index, (p1, r1)| {
57            let query = unsafe { it.context::<Query<(&Position, &Radius)>>() };
58            let e1 = it.entity(index);
59
60            query.each_entity(|e2, (p2, r2)| {
61                if e1 == *e2 {
62                    // don't collide with self
63                    return;
64                }
65
66                if e1 > *e2 {
67                    // Simple trick to prevent collisions from being detected
68                    // twice with the entities reversed.
69                    return;
70                }
71
72                // Check for collision
73                let d_sqr = distance_sqr(p1, p2);
74                let r_sqr = sqr(r1.value + r2.value);
75                if r_sqr > d_sqr {
76                    println!("{} and {} collided!", e1, e2);
77                }
78            });
79        });
80
81    // Create a few test entities
82    for _ in 0..10 {
83        world
84            .entity()
85            .set(Position {
86                x: rand(50),
87                y: rand(50),
88            })
89            .set(Radius {
90                value: rand(10) + 1.0,
91            });
92    }
93
94    // Run the system
95    sys.run();
96
97    // Output:
98    //  532 and 539 collided!
99    //  532 and 540 collided!
100    //  534 and 538 collided!
101    //  536 and 537 collided!
102    //  536 and 540 collided!
103    //  537 and 540 collided!
104}
examples/flecs/queries/query_group_by.rs (line 36)
26fn main() {
27    let world = World::new();
28
29    world.component::<First>();
30    world.component::<Second>();
31    world.component::<Third>();
32
33    let query = world.query::<&Position>().group_by::<Group>().build();
34
35    world
36        .entity()
37        .add::<(Group, Third)>()
38        .set(Position { x: 1.0, y: 1.0 });
39    world
40        .entity()
41        .add::<(Group, Second)>()
42        .set(Position { x: 2.0, y: 2.0 });
43    world
44        .entity()
45        .add::<(Group, First)>()
46        .set(Position { x: 3.0, y: 3.0 });
47
48    world
49        .entity()
50        .add::<(Group, Third)>()
51        .set(Position { x: 4.0, y: 4.0 })
52        .add::<Tag>();
53    world
54        .entity()
55        .add::<(Group, Second)>()
56        .set(Position { x: 5.0, y: 5.0 })
57        .add::<Tag>();
58    world
59        .entity()
60        .add::<(Group, First)>()
61        .set(Position { x: 6.0, y: 6.0 })
62        .add::<Tag>();
63
64    println!();
65
66    query.run_iter(|it, pos| {
67        let group = world.entity_from_id(it.group_id());
68        println!(
69            "Group: {:?} - Table: [{:?}]",
70            group.path().unwrap(),
71            it.archetype()
72        );
73
74        for i in it.iter() {
75            println!(" [{:?}]", pos[i]);
76        }
77
78        println!();
79    });
80
81    // Output:
82    //  Group: "::First" - Table: [Position, (Group,First)]
83    //  [Position { x: 3.0, y: 3.0 }]
84    //
85    //  Group: "::First" - Table: [Position, Tag, (Group,First)]
86    //  [Position { x: 6.0, y: 6.0 }]
87    //
88    //  Group: "::Second" - Table: [Position, (Group,Second)]
89    //  [Position { x: 2.0, y: 2.0 }]
90    //
91    //  Group: "::Second" - Table: [Position, Tag, (Group,Second)]
92    //  [Position { x: 5.0, y: 5.0 }]
93    //
94    //  Group: "::Third" - Table: [Position, (Group,Third)]
95    //  [Position { x: 1.0, y: 1.0 }]
96    //
97    //  Group: "::Third" - Table: [Position, Tag, (Group,Third)]
98    //  [Position { x: 4.0, y: 4.0 }]
99}
Source

pub fn entity_null(&self) -> EntityView<'_>

Create entity with id 0. This function is useful when the API must provide an entity that belongs to a world, but the entity id is 0.

§Example
use flecs_ecs::prelude::*;

let world = World::new();
let entity = world.entity_null();
assert_eq!(entity.id(), 0);
§See also
  • C++ API: world::entity
Source

pub fn entity_from_id(&self, id: impl Into<Entity>) -> EntityView<'_>

Create a new entity with the provided id.

§Arguments
  • id - The id to use for the new entity.
§See also
  • C++ API: world::entity
Examples found in repository?
examples/flecs/queries/query_group_by_callbacks.rs (line 44)
36extern "C" fn callback_group_create(
37    world: *mut sys::ecs_world_t,
38    group_id: u64,
39    _group_by_ctx: *mut c_void,
40) -> *mut c_void {
41    let world_ref = unsafe { WorldRef::from_ptr(world) };
42    println!(
43        "Group created: {:?}",
44        world_ref.world().entity_from_id(group_id).name()
45    );
46
47    println!();
48
49    let mut counter = GROUP_COUNTER.lock().unwrap();
50    *counter += 1;
51
52    // Return data that will be associated with the group
53    let ctx = Box::new(GroupCtx { counter: *counter });
54
55    Box::into_raw(ctx) as *mut std::ffi::c_void // Cast to make sure function type matches
56}
57
58// callbacks need to be extern "C" to be callable from C
59extern "C" fn callback_group_delete(
60    world: *mut sys::ecs_world_t,
61    group_id: u64,
62    _ctx: *mut c_void,
63    _group_by_ctx: *mut c_void,
64) {
65    let world_ref = unsafe { WorldRef::from_ptr(world) };
66    println!(
67        "Group deleted: {:?}",
68        world_ref.world().entity_from_id(group_id).name()
69    );
70
71    // if you have any data associated with the group, you need to free it
72    // or use the callback group_by_ctx where you pass a context to the callback
73}
74
75fn main() {
76    let world = World::new();
77
78    // Register components in order so that id for First is lower than Third
79    world.component::<First>();
80    world.component::<Second>();
81    world.component::<Third>();
82
83    // Grouped query
84    let query = world
85        .query::<(&Position,)>()
86        .group_by::<Group>()
87        // Callback invoked when a new group is created
88        .on_group_create(Some(callback_group_create))
89        // Callback invoked when a group is deleted
90        .on_group_delete(Some(callback_group_delete))
91        .build();
92
93    // Create entities in 6 different tables with 3 group ids
94    world
95        .entity()
96        .add::<(Group, Third)>()
97        .set(Position { x: 1.0, y: 1.0 });
98    world
99        .entity()
100        .add::<(Group, Second)>()
101        .set(Position { x: 2.0, y: 2.0 });
102    world
103        .entity()
104        .add::<(Group, First)>()
105        .set(Position { x: 3.0, y: 3.0 });
106
107    world
108        .entity()
109        .add::<(Group, Third)>()
110        .set(Position { x: 4.0, y: 4.0 })
111        .add::<Tag>();
112    world
113        .entity()
114        .add::<(Group, Second)>()
115        .set(Position { x: 5.0, y: 5.0 })
116        .add::<Tag>();
117    world
118        .entity()
119        .add::<(Group, First)>()
120        .set(Position { x: 6.0, y: 6.0 })
121        .add::<Tag>();
122
123    println!();
124
125    // The query cache now looks like this:
126    //  - group First:
127    //     - table [Position, (Group, First)]
128    //     - table [Position, Tag, (Group, First)]
129    //
130    //  - group Second:
131    //     - table [Position, (Group, Second)]
132    //     - table [Position, Tag, (Group, Second)]
133    //
134    //  - group Third:
135    //     - table [Position, (Group, Third)]
136    //     - table [Position, Tag, (Group, Third)]
137    //
138
139    query.run_iter(|it, (pos,)| {
140        let group = world.entity_from_id(it.group_id());
141        let ctx = unsafe { &*(query.group_context(group) as *mut GroupCtx) };
142        println!(
143            "Group: {:?} - Table: [{:?}] - Counter: {}",
144            group.path().unwrap(),
145            it.archetype(),
146            ctx.counter
147        );
148
149        for i in it.iter() {
150            println!(" [{:?}]", pos[i]);
151        }
152
153        println!();
154    });
155
156    // Deleting the query will call the on_group_deleted callback
157    query.destruct();
158
159    // Output:
160    //  Group created: "Third"
161    //  Group created: "Second"
162    //  Group created: "First"
163    //
164    //  Group: "::First" - Table: [Position, (Group,First)] - Counter: 3
165    //   [Position { x: 3.0, y: 3.0 }]
166    //
167    //  Group: "::First" - Table: [Position, Tag, (Group,First)] - Counter: 3
168    //   [Position { x: 6.0, y: 6.0 }]
169    //
170    //  Group: "::Second" - Table: [Position, (Group,Second)] - Counter: 2
171    //   [Position { x: 2.0, y: 2.0 }]
172    //
173    //  Group: "::Second" - Table: [Position, Tag, (Group,Second)] - Counter: 2
174    //   [Position { x: 5.0, y: 5.0 }]
175    //
176    //  Group: "::Third" - Table: [Position, (Group,Third)] - Counter: 1
177    //   [Position { x: 1.0, y: 1.0 }]
178    //
179    //  Group: "::Third" - Table: [Position, Tag, (Group,Third)] - Counter: 1
180    //   [Position { x: 4.0, y: 4.0 }]
181    //
182    //  Group deleted: "Second"
183    //  Group deleted: "First"
184    //  Group deleted: "Third"
185}
More examples
Hide additional examples
examples/flecs/queries/query_group_by.rs (line 67)
26fn main() {
27    let world = World::new();
28
29    world.component::<First>();
30    world.component::<Second>();
31    world.component::<Third>();
32
33    let query = world.query::<&Position>().group_by::<Group>().build();
34
35    world
36        .entity()
37        .add::<(Group, Third)>()
38        .set(Position { x: 1.0, y: 1.0 });
39    world
40        .entity()
41        .add::<(Group, Second)>()
42        .set(Position { x: 2.0, y: 2.0 });
43    world
44        .entity()
45        .add::<(Group, First)>()
46        .set(Position { x: 3.0, y: 3.0 });
47
48    world
49        .entity()
50        .add::<(Group, Third)>()
51        .set(Position { x: 4.0, y: 4.0 })
52        .add::<Tag>();
53    world
54        .entity()
55        .add::<(Group, Second)>()
56        .set(Position { x: 5.0, y: 5.0 })
57        .add::<Tag>();
58    world
59        .entity()
60        .add::<(Group, First)>()
61        .set(Position { x: 6.0, y: 6.0 })
62        .add::<Tag>();
63
64    println!();
65
66    query.run_iter(|it, pos| {
67        let group = world.entity_from_id(it.group_id());
68        println!(
69            "Group: {:?} - Table: [{:?}]",
70            group.path().unwrap(),
71            it.archetype()
72        );
73
74        for i in it.iter() {
75            println!(" [{:?}]", pos[i]);
76        }
77
78        println!();
79    });
80
81    // Output:
82    //  Group: "::First" - Table: [Position, (Group,First)]
83    //  [Position { x: 3.0, y: 3.0 }]
84    //
85    //  Group: "::First" - Table: [Position, Tag, (Group,First)]
86    //  [Position { x: 6.0, y: 6.0 }]
87    //
88    //  Group: "::Second" - Table: [Position, (Group,Second)]
89    //  [Position { x: 2.0, y: 2.0 }]
90    //
91    //  Group: "::Second" - Table: [Position, Tag, (Group,Second)]
92    //  [Position { x: 5.0, y: 5.0 }]
93    //
94    //  Group: "::Third" - Table: [Position, (Group,Third)]
95    //  [Position { x: 1.0, y: 1.0 }]
96    //
97    //  Group: "::Third" - Table: [Position, Tag, (Group,Third)]
98    //  [Position { x: 4.0, y: 4.0 }]
99}
examples/flecs/queries/query_group_by_custom.rs (line 107)
46fn main() {
47    let world = World::new();
48
49    // Register components in order so that id for First is lower than Third
50    world.component::<First>();
51    world.component::<Second>();
52    world.component::<Third>();
53
54    // Grouped query
55    let query = world
56        .query::<&Position>()
57        .group_by_fn::<Group>(Some(callback_group_by_relationship))
58        .build();
59
60    // Create entities in 6 different tables with 3 group ids
61    world
62        .entity()
63        .add::<(Group, Third)>()
64        .set(Position { x: 1.0, y: 1.0 });
65    world
66        .entity()
67        .add::<(Group, Second)>()
68        .set(Position { x: 2.0, y: 2.0 });
69    world
70        .entity()
71        .add::<(Group, First)>()
72        .set(Position { x: 3.0, y: 3.0 });
73
74    world
75        .entity()
76        .add::<(Group, Third)>()
77        .set(Position { x: 4.0, y: 4.0 })
78        .add::<Tag>();
79    world
80        .entity()
81        .add::<(Group, Second)>()
82        .set(Position { x: 5.0, y: 5.0 })
83        .add::<Tag>();
84    world
85        .entity()
86        .add::<(Group, First)>()
87        .set(Position { x: 6.0, y: 6.0 })
88        .add::<Tag>();
89
90    println!();
91
92    // The query cache now looks like this:
93    //  - group First:
94    //     - table [Position, (Group, First)]
95    //     - table [Position, Tag, (Group, First)]
96    //
97    //  - group Second:
98    //     - table [Position, (Group, Second)]
99    //     - table [Position, Tag, (Group, Second)]
100    //
101    //  - group Third:
102    //     - table [Position, (Group, Third)]
103    //     - table [Position, Tag, (Group, Third)]
104    //
105
106    query.run_iter(|it, pos| {
107        let group = world.entity_from_id(it.group_id());
108        println!(
109            "Group: {:?} - Table: [{:?}]",
110            group.path().unwrap(),
111            it.archetype()
112        );
113
114        for i in it.iter() {
115            println!(" [{:?}]", pos[i]);
116        }
117
118        println!();
119    });
120
121    // Output:
122    //  Group: "::First" - Table: [Position, (Group,First)]
123    //  [Position { x: 3.0, y: 3.0 }]
124    //
125    //  Group: "::First" - Table: [Position, Tag, (Group,First)]
126    //  [Position { x: 6.0, y: 6.0 }]
127    //
128    //  Group: "::Second" - Table: [Position, (Group,Second)]
129    //  [Position { x: 2.0, y: 2.0 }]
130    //
131    //  Group: "::Second" - Table: [Position, Tag, (Group,Second)]
132    //  [Position { x: 5.0, y: 5.0 }]
133    //
134    //  Group: "::Third" - Table: [Position, (Group,Third)]
135    //  [Position { x: 1.0, y: 1.0 }]
136    //
137    //  Group: "::Third" - Table: [Position, Tag, (Group,Third)]
138    //  [Position { x: 4.0, y: 4.0 }]
139}
examples/flecs/queries/query_group_iter.rs (line 109)
52fn main() {
53    let world = World::new();
54
55    // Create npc's in world cell 0_0
56    world
57        .entity()
58        .add::<(WorldCell, Cell_0_0)>()
59        .add::<Merchant>()
60        .add::<Npc>();
61    world
62        .entity()
63        .add::<(WorldCell, Cell_0_0)>()
64        .add::<Merchant>()
65        .add::<Npc>();
66
67    // Create npc's in world cell 0_1
68    world
69        .entity()
70        .add::<(WorldCell, Cell_0_1)>()
71        .add::<Beggar>()
72        .add::<Npc>();
73    world
74        .entity()
75        .add::<(WorldCell, Cell_0_1)>()
76        .add::<Soldier>()
77        .add::<Npc>();
78
79    // Create npc's in world cell 1_0
80    world
81        .entity()
82        .add::<(WorldCell, Cell_1_0)>()
83        .add::<Mage>()
84        .add::<Npc>();
85    world
86        .entity()
87        .add::<(WorldCell, Cell_1_0)>()
88        .add::<Beggar>()
89        .add::<Npc>();
90
91    // Create npc's in world cell 1_1
92    world
93        .entity()
94        .add::<(WorldCell, Cell_1_1)>()
95        .add::<Soldier>()
96        .add::<Npc>();
97
98    let mut query = world
99        .query::<()>()
100        .with::<&Npc>()
101        .group_by::<WorldCell>()
102        .build();
103
104    // Iterate all tables
105    println!("All tables");
106
107    query.run(|mut iter| {
108        while iter.next() {
109            let group = world.entity_from_id(iter.group_id());
110            println!(
111                "group: {:?} - Table [{}]",
112                group.path().unwrap(),
113                iter.table().unwrap().to_string().unwrap()
114            );
115        }
116    });
117
118    println!();
119
120    println!("Tables for cell 1_0:");
121
122    query.set_group::<Cell_1_0>().run(|mut iter| {
123        while iter.next() {
124            let world = iter.world();
125            let group = world.entity_from_id(iter.group_id());
126            println!(
127                "group: {:?} - Table [{}]",
128                group.path().unwrap(),
129                iter.table().unwrap().to_string().unwrap()
130            );
131        }
132    });
133
134    // Output:
135    //  All tables
136    //  group: "::Cell_0_0" - Table [Merchant, Npc, (WorldCell,Cell_0_0)]
137    //  group: "::Cell_0_1" - Table [Npc, Beggar, (WorldCell,Cell_0_1)]
138    //  group: "::Cell_0_1" - Table [Npc, Soldier, (WorldCell,Cell_0_1)]
139    //  group: "::Cell_1_0" - Table [Npc, Mage, (WorldCell,Cell_1_0)]
140    //  group: "::Cell_1_0" - Table [Npc, Beggar, (WorldCell,Cell_1_0)]
141    //  group: "::Cell_1_1" - Table [Npc, Soldier, (WorldCell,Cell_1_1)]
142
143    //  Tables for cell 1_0:
144    //  group: "::Cell_1_0" - Table [Npc, Mage, (WorldCell,Cell_1_0)]
145    //  group: "::Cell_1_0" - Table [Npc, Beggar, (WorldCell,Cell_1_0)]
146}
Source

pub fn prefab(&self) -> EntityView<'_>

Creates a prefab

§Returns

The prefab entity.

§See also
Source

pub fn prefab_named<'a>(&'a self, name: &str) -> EntityView<'a>

Creates a named prefab

§Arguments
  • name - The name to use for the new prefab.
§Returns

The prefab entity.

§See also
Examples found in repository?
examples/flecs/prefabs/prefab_hierarchy.rs (line 11)
7fn main() {
8    let world = World::new();
9
10    // Create a prefab hierarchy.
11    let spaceship = world.prefab_named("SpaceShip");
12    world.prefab_named("Engine").child_of_id(spaceship);
13    world.prefab_named("Cockpit").child_of_id(spaceship);
14
15    // Instantiate the prefab. This also creates an Engine and Cockpit child
16    // for the instance.
17    let inst = world.entity_named("my_spaceship").is_a_id(spaceship);
18
19    // Because of the IsA relationship, the instance now has the Engine and Cockpit
20    // children of the prefab. This means that the instance can look up the Engine
21    // and Cockpit entities.
22    if let Some(inst_engine) = inst.try_lookup_recursive("Engine") {
23        if let Some(inst_cockpit) = inst.try_lookup_recursive("Cockpit") {
24            println!("instance engine:  {:?}", inst_engine.path().unwrap());
25            println!("instance cockpit: {:?}", inst_cockpit.path().unwrap());
26        } else {
27            println!("entity lookup failed");
28        }
29    }
30
31    // Output:
32    //  instance engine:  "::my_spaceship::Engine"
33    //  instance cockpit: "::my_spaceship::Cockpit"
34}
More examples
Hide additional examples
examples/flecs/prefabs/prefab_basics.rs (line 37)
28fn main() {
29    let world = World::new();
30
31    // Add the traits to mark the component to be inherited
32    world
33        .component::<Defence>()
34        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
35
36    // Create a prefab with Position and Velocity components
37    let spaceship = world.prefab_named("Prefab").set(Defence { value: 50.0 });
38
39    // Create a prefab instance
40    let inst = world.entity_named("my_spaceship").is_a_id(spaceship);
41
42    // Because of the IsA relationship, the instance now shares the Defense
43    // component with the prefab, and can be retrieved as a regular component:
44    inst.try_get::<&Defence>(|d_inst| {
45        println!("{:?}", d_inst);
46        // Because the component is shared, changing the value on the prefab will
47        // also change the value for the instance:
48        // this is safe during a table lock because it also has the component and won't cause the table to move.
49        spaceship.set(Defence { value: 100.0 });
50        println!("after set: {:?}", d_inst);
51    });
52
53    // Prefab components can be iterated like regular components:
54    world.each_entity::<&Defence>(|entity, d| {
55        println!("{}: defence: {}", entity.path().unwrap(), d.value);
56    });
57
58    // Output:
59    //  Defence { value: 50.0 }
60    //  after set: Defence { value: 100.0 }
61    //  ::my_spaceship: 100
62}
examples/flecs/prefabs/prefab_nested.rs (line 27)
23fn main() {
24    let world = World::new();
25
26    // Creates a wheel prefab
27    let wheel = world.prefab_named("Wheel");
28    wheel.set(TirePressure { value: 32.0 });
29
30    // Create a Car prefab with four wheels. Note how we're using the scope
31    // method, which has the same effect as adding the (ChildOf, Car) pair.
32    let car = world.prefab_named("Car");
33    car.run_in_scope(|| {
34        world.prefab_named("FrontLeft").is_a_id(wheel);
35
36        world.prefab_named("FrontRight").is_a_id(wheel);
37
38        world.prefab_named("BackLeft").is_a_id(wheel);
39
40        world.prefab_named("BackRight").is_a_id(wheel);
41    });
42
43    // Create a prefab instance.
44    let inst_car = world.entity_named("my_car");
45    inst_car.is_a_id(car);
46
47    // Lookup one of the wheels
48    if let Some(inst) = inst_car.try_lookup_recursive("FrontLeft") {
49        // The type shows that the child has a private copy of the TirePressure
50        // component, and an IsA relationship to the Wheel prefab.
51        println!("{:?}", inst.archetype());
52
53        // Get the TirePressure component & print its value
54        inst.try_get::<Option<&TirePressure>>(|p| {
55            if let Some(p) = p {
56                println!("pressure: {}", p.value);
57            }
58        });
59    } else {
60        println!("entity lookup failed");
61    }
62
63    // Output:
64    //  TirePressure, (Identifier,Name), (ChildOf,my_car), (IsA,Wheel)
65    //  pressure: 32
66}
examples/flecs/prefabs/prefab_slots.rs (line 32)
27fn main() {
28    let world = World::new();
29
30    // Create the same prefab hierarchy as from the hierarchy example, but now
31    // with the SlotOf relationship.
32    let spaceship = world.prefab_named("SpaceShip");
33    let engine = world
34        .prefab_named("Engine")
35        .child_of_id(spaceship)
36        .slot_of_id(spaceship);
37
38    let cockpit = world
39        .prefab_named("Cockpit")
40        .child_of_id(spaceship)
41        .slot_of_id(spaceship);
42
43    // Add an additional child to the Cockpit prefab to demonstrate how
44    // slots can be different from the parent. This slot could have been
45    // added to the Cockpit prefab, but instead we register it on the top
46    // level SpaceShip prefab.
47
48    let pilot_seat = world
49        .prefab_named("PilotSeat")
50        .child_of_id(cockpit)
51        .slot_of_id(spaceship);
52
53    // Create a prefab instance.
54    let inst = world.entity_named("my_spaceship").is_a_id(spaceship);
55
56    // Get the instantiated entities for the prefab slots
57    let inst_engine = inst.target_id(engine, 0).unwrap();
58    let inst_cockpit = inst.target_id(cockpit, 0).unwrap();
59    let inst_seat = inst.target_id(pilot_seat, 0).unwrap();
60
61    println!("instance engine: {}", inst_engine.path().unwrap());
62
63    println!("instance cockpit: {}", inst_cockpit.path().unwrap());
64
65    println!("instance seat: {}", inst_seat.path().unwrap());
66
67    // Output:
68    //  instance engine: ::my_spaceship::Engine
69    //  instance cockpit: ::my_spaceship::Cockpit
70    //  instance seat: ::my_spaceship::Cockpit::PilotSeat
71}
examples/flecs/prefabs/prefab_override.rs (line 51)
36fn main() {
37    let world = World::new();
38
39    // Add the traits to mark the components to be inherited
40    world
41        .component::<Defence>()
42        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
43    world
44        .component::<Attack>()
45        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
46
47    // Attack and Damage are properties that can be shared across many
48    // spaceships. This saves memory, and speeds up prefab creation as we don't
49    // have to copy the values of Attack and Defense to private components.
50    let spaceship = world
51        .prefab_named("SpaceShip")
52        .set(Attack { value: 75.0 })
53        .set(Defence { value: 100.0 })
54        .set(Damage { value: 50.0 });
55
56    // Create a prefab instance.
57    let inst = world.entity_named("my_spaceship").is_a_id(spaceship);
58
59    // The entity will now have a private copy of the Damage component, but not
60    // of the Attack and Defense components. We can see this when we look at the
61    // type of the instance:
62    println!("{}", inst.archetype());
63
64    // Even though Attack was not automatically overridden, we can always
65    // override it manually afterwards by adding it:
66    inst.override_type::<Attack>();
67
68    // The Attack component now shows up in the entity type:
69    println!("{}", inst.archetype());
70
71    // We can get all components on the instance, regardless of whether they
72    // are overridden or not. Note that the overridden components (Attack and
73    // Damage) are initialized with the values from the prefab component:
74    inst.try_get::<(&Attack, &Defence, &Damage)>(|(attack, defence, damage)| {
75        println!("attack: {}", attack.value);
76        println!("defence: {}", defence.value);
77        println!("damage: {}", damage.value);
78    });
79
80    // Output:
81    //  Damage, (Identifier,Name), (IsA,SpaceShip)
82    //  Attack, Damage, (Identifier,Name), (IsA,SpaceShip)
83    //  attack: 75
84    //  defence: 100
85    //  damage: 50
86}
examples/flecs/prefabs/prefab_variant.rs (line 39)
34fn main() {
35    let world = World::new();
36
37    // Create a base prefab for SpaceShips.
38    let spaceship = world
39        .prefab_named("SpaceShip")
40        .set(ImpulseSpeed { value: 50.0 })
41        .set(Defence { value: 25.0 });
42
43    // Create a Freighter variant which inherits from SpaceShip
44    let freighter = world
45        .prefab_named("Freighter")
46        .is_a_id(spaceship)
47        .set(FreightCapacity { value: 100.0 })
48        .set(Defence { value: 50.0 });
49
50    // Create a MammotFreighter variant which inherits from Freighter
51    let mammoth_freighter = world
52        .prefab_named("MammothFreighter")
53        .is_a_id(freighter)
54        .set(FreightCapacity { value: 500.0 });
55
56    // Create a Frigate variant which inherits from SpaceShip
57    world
58        .prefab_named("Frigate")
59        .is_a_id(spaceship)
60        .set(Attack { value: 100.0 })
61        .set(Defence { value: 75.0 })
62        .set(ImpulseSpeed { value: 125.0 });
63
64    // Create an instance of the MammothFreighter. This entity will inherit the
65    // ImpulseSpeed from SpaceShip, Defence from Freighter and FreightCapacity
66    // from MammothFreighter.
67    let inst = world
68        .entity_named("my_freighter")
69        .is_a_id(mammoth_freighter);
70
71    // Add a private Position component.
72    inst.set(Position { x: 10.0, y: 20.0 });
73
74    // Instances can override inherited components to give them a private copy
75    // of the component. This freighter got an armor upgrade:
76    inst.set(Defence { value: 100.0 });
77
78    // Queries can match components from multiple levels of inheritance
79    world.each_entity::<(&Position, &ImpulseSpeed, &Defence, &FreightCapacity)>(
80        |e, (p, s, d, c)| {
81            println!("{}:", e.name());
82            println!(" - position: {}, {}", p.x, p.y);
83            println!(" - impulse speed: {}", s.value);
84            println!(" - defense: {}", d.value);
85            println!(" - capacity: {}", c.value);
86        },
87    );
88
89    // Output:
90    //   my_freighter:
91    //    - position: 10, 20
92    //    - impulse speed: 50
93    //    - defense: 100
94    //    - capacity: 500
95}
Source

pub fn prefab_type<T: ComponentId + TagComponent>(&self) -> EntityView<'_>

Creates a prefab that’s associated with a type

§Type Parameters
  • T - The component type to associate with the new prefab.
§Returns

The prefab entity.

§See also
Examples found in repository?
examples/flecs/prefabs/prefab_typed.rs (line 34)
30fn main() {
31    let world = World::new();
32
33    // Associate types with prefabs
34    world.prefab_type::<Turret>();
35
36    world
37        .prefab_type::<Base>()
38        .child_of::<Turret>()
39        .slot_of::<Turret>();
40
41    world
42        .prefab_type::<Head>()
43        .child_of::<Turret>()
44        .slot_of::<Turret>();
45
46    world.prefab_type::<Railgun>().is_a::<Turret>();
47    world
48        .prefab_type::<Beam>()
49        .slot_of::<Railgun>()
50        .child_of::<Railgun>();
51
52    // Create prefab instance.
53    let inst = world.entity_named("my_railgun").is_a::<Railgun>();
54
55    // Get entities for slots
56    let inst_base = inst.target::<Base>(0).unwrap();
57    let inst_head = inst.target::<Head>(0).unwrap();
58    let inst_beam = inst.target::<Beam>(0).unwrap();
59
60    println!("instance base: {}", inst_base.path().unwrap());
61    println!("instance head: {}", inst_head.path().unwrap());
62    println!("instance beam: {}", inst_beam.path().unwrap());
63
64    // Output:
65    //  instance base: ::my_railgun::Base
66    //  instance head: ::my_railgun::Head
67    //  instance beam: ::my_railgun::Beam
68}
Source

pub fn prefab_type_named<'a, T: ComponentId + TagComponent>( &'a self, name: &str, ) -> EntityView<'a>

Creates a named prefab that’s associated with a type

§Type Parameters
  • T - The component type to associate with the new prefab.
§Arguments
  • name - The name to use for the new prefab.
§Returns

The prefab entity.

§See also
Source

pub fn component_id<T: ComponentId>(&self) -> Entity

Source

pub fn relationship_id<First: ComponentId, Second: ComponentId>(&self) -> Id

Source

pub fn id_from<T: ComponentOrPairId>(&self) -> IdView<'_>

Get the id view of component / pair

§Type Parameters
  • T - The component type.
§Returns

The id of the component.

§See also
  • C++ API: world::id
  • C++ API: world::pair
Examples found in repository?
examples/flecs/relationships/relationships_component_data.rs (line 81)
35fn main() {
36    let world = World::new();
37
38    // When one element of a pair is a component and the other element is a tag,
39    // the pair assumes the type of the component.
40    let e1 = world
41        .entity()
42        .set_pair::<Requires, Gigawatts>(Requires { amount: 1.21 });
43
44    let require = e1.try_get::<Option<&(Requires, Gigawatts)>>(|req| {
45        if let Some((req)) = req {
46            println!("e1: requires: {}", req.amount);
47        } else {
48            println!("e1: does not have a relationship with Requires, Gigawatts");
49        }
50    });
51
52    // The component can be either the first or second part of a pair:
53    let e2 = world
54        .entity()
55        .set_pair::<Gigawatts, Requires>(Requires { amount: 1.5 });
56
57    let require = e2.try_get::<Option<&(Gigawatts, Requires)>>(|req| {
58        if let Some((req)) = req {
59            println!("e2: requires: {}", req.amount);
60        } else {
61            println!("e2: does not have a relationship with Gigawatts, Requires");
62        }
63    });
64
65    // Note that <Requires, Gigawatts> and <Gigawatts, Requires> are two
66    // different pairs, and can be added to an entity at the same time.
67
68    // If both parts of a pair are components, the pair assumes the type of
69    // the first element:
70    let e3 = world
71        .entity()
72        .set_pair::<Expires, Position>(Expires { timeout: 0.5 });
73
74    let expires = e3.try_get::<&(Expires, Position)>(|expires| {
75        println!("expires: {}", expires.timeout);
76    });
77
78    println!(
79        "{}",
80        world
81            .id_from::<(Requires, Gigawatts)>()
82            .type_id()
83            .path()
84            .unwrap()
85    );
86    println!(
87        "{}",
88        world
89            .id_from::<(Gigawatts, Requires)>()
90            .type_id()
91            .path()
92            .unwrap()
93    );
94    println!(
95        "{}",
96        world
97            .id_from::<(Expires, Position)>()
98            .type_id()
99            .path()
100            .unwrap()
101    );
102
103    // When querying for a relationship component, add the pair type as template
104    // argument to the builder:
105    let query = world.query::<&(Requires, Gigawatts)>().build();
106
107    query.each_entity(|entity, requires| {
108        println!("requires: {} gigawatts", requires.amount);
109    });
110
111    // Output:
112    // e1: requires: 1.21
113    // e1: requires: 1.5
114    // expires: 0.5
115    // ::Requires
116    // ::Requires
117    // ::Expires
118    // requires: 1.21 gigawatts
119}
Source

pub fn id_from_id<Id>(&self, id: Id) -> IdView<'_>
where Id: IntoId,

get IdView from an id or from a relationship pair

§Arguments
  • id - The id to convert to an IdView.
§Returns

The IdView from the provided id.

§See also
  • C++ API: world::pair
  • C++ API: world::id
Source

pub fn id_first<First: ComponentId>( &self, second: impl Into<Entity>, ) -> IdView<'_>

get pair id from relationship, object.

§Type Parameters
  • First - The first element of the pair.
§Arguments
  • second - The id of the second element of the pair.
§Returns

The pair as Id

§See also
  • C++ API: world::pair
Source

pub fn id_second<Second: ComponentId>( &self, first: impl Into<Entity>, ) -> IdView<'_>

get pair id from relationship, object.

§Type Parameters
  • Second - The second element of the pair.
§Arguments
  • first - The id of the first element of the pair.
§Returns

The pair as Id

§See also
  • C++ API: world::pair
Source

pub fn component<T: ComponentId>(&self) -> Component<'_, T::UnderlyingType>

Find or register component.

§Type Parameters
  • T - The component type.
§Returns

The found or registered component.

§See also
  • C++ API: world::component
Examples found in repository?
examples/flecs/entities/entity_hooks.rs (line 18)
14fn main() {
15    let world = World::new();
16
17    world
18        .component::<Position>()
19        .on_add(|entity, _pos| {
20            println!("added Position to {:?}", entity.name());
21        })
22        .on_remove(|entity, pos| {
23            println!("removed {:?} from {:?}", pos, entity.name());
24        })
25        .on_set(|entity, pos| {
26            println!("set {:?} for {:?}", pos, entity.name());
27        });
28
29    let entity = world.entity_named("Bob");
30
31    entity.set(Position { x: 10.0, y: 20.0 });
32
33    // This operation changes the entity's archetype, which invokes a move
34    // add is used for adding tags.
35    entity.add::<Tag>();
36
37    entity.destruct();
38
39    // Output:
40    //  added Position { x: 0.0, y: 0.0 } to "Bob"
41    //  set Position { x: 10.0, y: 20.0 } for "Bob"
42    //  removed Position { x: 10.0, y: 20.0 } from "Bob"
43}
More examples
Hide additional examples
examples/flecs/relationships/relationships_symmetric.rs (line 12)
7fn main() {
8    let world = World::new();
9
10    // Register TradesWith as symmetric relationship. Symmetric relationships
11    // go both ways, adding (R, B) to A will also add (R, A) to B.
12    world.component::<TradesWith>().add::<flecs::Symmetric>();
13
14    // Create two players
15    let player_1 = world.entity();
16    let player_2 = world.entity();
17
18    // Add (TradesWith, player_2) to player_1. This also adds
19    // (TradesWith, player_1) to player_2.
20    player_1.add_first::<TradesWith>(player_2);
21
22    // Log platoon of unit
23    println!(
24        "Player 1 trades with Player 2: {}",
25        player_1.has_first::<TradesWith>(player_2)
26    ); // true
27    println!(
28        "Player 2 trades with Player 1: {}",
29        player_2.has_first::<TradesWith>(player_1)
30    ); // true
31
32    // Output:
33    //  Player 1 trades with Player 2: true
34    //  Player 2 trades with Player 1: true
35}
examples/flecs/entities/entity_iterate_components.rs (line 80)
63fn main() {
64    let world = World::new();
65
66    let bob = world
67        .entity_named("Bob")
68        .set(Position { x: 10.0, y: 20.0 })
69        .set(Velocity { x: 1.0, y: 1.0 })
70        .add::<Human>()
71        .add::<(Eats, Apples)>();
72
73    println!("Bob's components:");
74    iterate_components(bob);
75
76    println!();
77
78    // We can use the same function to iterate the components of a component
79    println!("Position's components:");
80    iterate_components(world.component::<Position>().entity());
81
82    // Output:
83    //  Bob's components:
84    //  [Position, Velocity, Human, (Identifier,Name), (Eats,Apples)]
85    //
86    //  0: Position
87    //  1: Velocity
88    //  2: Human
89    //  3: (Identifier,Name)
90    //  4: (Eats,Apples)
91    //
92    //  0: entity: Position
93    //  1: entity: Velocity
94    //  2: entity: Human
95    //  3: rel: Identifier, target: Name
96    //  4: rel: Eats, target: Apples
97    //
98    //  Position's components:
99    //  [Component, (Identifier,Name), (Identifier,Symbol)
100    //
101    //  0: Component
102    //  1: (Identifier,Name)
103    //  2: (Identifier,Symbol)
104    //  3: (ChildOf,entity_iterate_components.common)
105
106    //  0: entity: Component
107    //  1: rel: Identifier, target: Name
108    //  2: rel: Identifier, target: Symbol
109    //  3: rel: ChildOf, target: common
110}
examples/flecs/relationships/relationships_exclusive.rs (line 13)
8fn main() {
9    let world = World::new();
10
11    // Register Platoon as exclusive relationship. This ensures that an entity
12    // can only belong to a single Platoon.
13    world.component::<Platoon>().add::<flecs::Exclusive>();
14
15    // Create two platoons
16    let platoon_1 = world.entity();
17    let platoon_2 = world.entity();
18
19    // Create a unit
20    let unit = world.entity();
21
22    // Add unit to platoon 1
23    unit.add_first::<Platoon>(platoon_1);
24
25    // Log platoon of unit
26    println!(
27        "Unit in platoon 1: {}",
28        unit.has_first::<Platoon>(platoon_1)
29    ); // true
30    println!(
31        "Unit in platoon 2: {}",
32        unit.has_first::<Platoon>(platoon_2)
33    ); // false
34
35    println!();
36
37    // Add unit to platoon 2. Because Platoon is an exclusive relationship, this
38    // both removes (Platoon, platoon_1) and adds (Platoon, platoon_2) in a
39    // single operation.
40    unit.add_first::<Platoon>(platoon_2);
41
42    // Log platoon of unit
43    println!(
44        "Unit in platoon 1: {}",
45        unit.has_first::<Platoon>(platoon_1)
46    ); // false
47    println!(
48        "Unit in platoon 2: {}",
49        unit.has_first::<Platoon>(platoon_2)
50    ); // true
51
52    // Output:
53    //  Unit in platoon 1: true
54    //  Unit in platoon 2: false
55    //
56    //  Unit in platoon 1: false
57    //  Unit in platoon 2: true
58}
examples/flecs/prefabs/prefab_basics.rs (line 33)
28fn main() {
29    let world = World::new();
30
31    // Add the traits to mark the component to be inherited
32    world
33        .component::<Defence>()
34        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
35
36    // Create a prefab with Position and Velocity components
37    let spaceship = world.prefab_named("Prefab").set(Defence { value: 50.0 });
38
39    // Create a prefab instance
40    let inst = world.entity_named("my_spaceship").is_a_id(spaceship);
41
42    // Because of the IsA relationship, the instance now shares the Defense
43    // component with the prefab, and can be retrieved as a regular component:
44    inst.try_get::<&Defence>(|d_inst| {
45        println!("{:?}", d_inst);
46        // Because the component is shared, changing the value on the prefab will
47        // also change the value for the instance:
48        // this is safe during a table lock because it also has the component and won't cause the table to move.
49        spaceship.set(Defence { value: 100.0 });
50        println!("after set: {:?}", d_inst);
51    });
52
53    // Prefab components can be iterated like regular components:
54    world.each_entity::<&Defence>(|entity, d| {
55        println!("{}: defence: {}", entity.path().unwrap(), d.value);
56    });
57
58    // Output:
59    //  Defence { value: 50.0 }
60    //  after set: Defence { value: 100.0 }
61    //  ::my_spaceship: 100
62}
examples/flecs/queries/query_component_inheritance.rs (line 35)
30fn main() {
31    let world = World::new();
32
33    // Make the ECS aware of the inheritance relationships. Note that IsA
34    // relationship used here is the same as in the prefab example.
35    world.component::<CombatUnit>().is_a::<Unit>();
36    world.component::<MeleeUnit>().is_a::<CombatUnit>();
37    world.component::<RangedUnit>().is_a::<CombatUnit>();
38
39    world.component::<Warrior>().is_a::<MeleeUnit>();
40    world.component::<Wizard>().is_a::<RangedUnit>();
41    world.component::<Marksman>().is_a::<RangedUnit>();
42    world.component::<BuilderX>().is_a::<Unit>();
43
44    // Create a few units
45    world.entity_named("warrior_1").add::<Warrior>();
46    world.entity_named("warrior_2").add::<Warrior>();
47
48    world.entity_named("marksman_1").add::<Marksman>();
49    world.entity_named("marksman_2").add::<Marksman>();
50
51    world.entity_named("wizard_1").add::<Wizard>();
52    world.entity_named("wizard_2").add::<Wizard>();
53
54    world.entity_named("builder_1").add::<BuilderX>();
55    world.entity_named("builder_2").add::<BuilderX>();
56
57    // Create a rule to find all ranged units
58    let r = world.query::<&RangedUnit>().build();
59
60    // Iterate the rule
61    r.each_entity(|e, rangedunit| {
62        println!("Unit {} found", e.name());
63    });
64
65    // Output:
66    //  Unit wizard_1 found
67    //  Unit wizard_2 found
68    //  Unit marksman_1 found
69    //  Unit marksman_2 found
70}
Source

pub fn component_named<'a, T: ComponentId>( &'a self, name: &str, ) -> Component<'a, T::UnderlyingType>

Find or register component.

§Type Parameters
  • T - The component type.
§Arguments
  • name - The name of the component.
§Returns

The found or registered component.

§See also
  • C++ API: world::component
Source

pub fn component_untyped<T: ComponentId>(&self) -> UntypedComponent<'_>

Find or register untyped component.

§Type Parameters
  • T - The component type.
§Returns

The found or registered untyped component.

§See also
  • C++ API: world::component
Source

pub fn component_untyped_id( &self, id: impl Into<Entity>, ) -> UntypedComponent<'_>

Find or register untyped component.

§Arguments
  • id - The component id.
§Returns

The found or registered untyped component.

§See also
  • C++ API: world::component
Source

pub fn to_entity<T: ComponentId + ComponentType<Enum> + EnumComponentInfo>( &self, enum_value: T, ) -> EntityView<'_>

Convert enum constant to entity

§Type Parameters
  • T - The enum type.
§Arguments
  • enum_value - The enum value to convert.
§See also
  • C++ API: world::to_entity
Source

pub unsafe fn event_id(&self, event: impl Into<Entity>) -> EventBuilder<'_, ()>

Create a new event builder (untyped) from entity id which represents an event

§Safety

Caller must ensure that event is a ZST or that a pointer to the associated type is set on the builder

§Arguments
  • event - The event id
§Returns

A new (untyped) event builder.

§See also
Source

pub fn event<T: ComponentId>(&self) -> EventBuilder<'_, T>

Create a new event.

§Type Parameters
  • T - The event type.
§Returns

A new (typed) event builder.

§See also
Examples found in repository?
examples/flecs/observers/observer_custom_event.rs (line 36)
14fn main() {
15    let world = World::new();
16
17    // Create an observer for the custom event
18    world
19        .observer::<MyEvent, &Position>()
20        .each_iter(|it, index, _pos| {
21            println!(
22                " - {}: {}: {}",
23                it.event().name(),
24                it.event_id().to_str(),
25                it.entity(index)
26            );
27        });
28
29    // The observer query can be matched against the entity, so make sure it
30    // has the Position component before emitting the event. This does not
31    // trigger the observer yet.
32    let entity = world.entity_named("e1").set(Position { x: 10.0, y: 20.0 });
33
34    // Emit the custom event. This triggers the observer.
35    world
36        .event()
37        .add::<Position>()
38        .entity(entity)
39        .emit(&MyEvent);
40
41    // Output:
42    //  - MyEvent: Position: e1
43}
Source

pub fn new_observer<'a>(&'a self, e: EntityView<'a>) -> Observer<'a>

Upcast entity to an observer. The provided entity must be an observer.

§Arguments
  • e - The entity.
§Returns

An observer object.

§See also
  • C++ API: world::observer
Source

pub fn observer<Event: ComponentId, Components>( &self, ) -> ObserverBuilder<'_, Event, Components>
where Components: QueryTuple,

Create a new observer.

§Type Parameters
  • Components - The components to match on.
§Returns

Observer builder.

§See also
Examples found in repository?
examples/flecs/observers/observer_yield_existing.rs (line 27)
18fn main() {
19    let world = World::new();
20
21    // Create existing entities with Position component
22    world.entity_named("e1").set(Position { x: 10.0, y: 20.0 });
23    world.entity_named("e2").set(Position { x: 20.0, y: 30.0 });
24
25    // Create an observer for three events
26    world
27        .observer::<flecs::OnSet, &Position>()
28        .yield_existing()
29        .each_iter(|it, index, pos| {
30            println!(
31                " - {}: {}: {}: {{ {}, {} }}",
32                it.event().name(),
33                it.event_id().to_str(),
34                it.entity(index),
35                pos.x,
36                pos.y
37            );
38        });
39
40    // Output:
41    //  - OnSet: Position: e1: { 10, 20 }
42    //  - OnSet: Position: e2: { 20, 30 }
43}
More examples
Hide additional examples
examples/flecs/observers/observer_custom_event.rs (line 19)
14fn main() {
15    let world = World::new();
16
17    // Create an observer for the custom event
18    world
19        .observer::<MyEvent, &Position>()
20        .each_iter(|it, index, _pos| {
21            println!(
22                " - {}: {}: {}",
23                it.event().name(),
24                it.event_id().to_str(),
25                it.entity(index)
26            );
27        });
28
29    // The observer query can be matched against the entity, so make sure it
30    // has the Position component before emitting the event. This does not
31    // trigger the observer yet.
32    let entity = world.entity_named("e1").set(Position { x: 10.0, y: 20.0 });
33
34    // Emit the custom event. This triggers the observer.
35    world
36        .event()
37        .add::<Position>()
38        .entity(entity)
39        .emit(&MyEvent);
40
41    // Output:
42    //  - MyEvent: Position: e1
43}
examples/flecs/observers/observer_two_components.rs (line 26)
21fn main() {
22    let world = World::new();
23
24    // Create observer for custom event
25    world
26        .observer::<flecs::OnSet, (&Position, &Velocity)>()
27        .each_iter(|it, index, (pos, vel)| {
28            println!(
29                " - {}: {}: {}: p: {{ {}, {} }}, v: {{ {}, {} }}",
30                it.event().name(),
31                it.event_id().to_str(),
32                it.entity(index).name(),
33                pos.x,
34                pos.y,
35                vel.x,
36                vel.y
37            );
38        });
39
40    // Create entity, set Position (emits EcsOnSet, does not yet match observer)
41    let entity = world.entity_named("e").set(Position { x: 10.0, y: 20.0 });
42
43    // Set Velocity (emits EcsOnSet, matches observer)
44    entity.set(Velocity { x: 1.0, y: 2.0 });
45
46    // Output:
47    //  - OnSet: Velocity: e: p: { 10, 20 }, v: { 1, 2 }
48}
examples/flecs/observers/observer_monitor.rs (line 31)
26fn main() {
27    let world = World::new();
28
29    // Create observer for custom event
30    world
31        .observer::<flecs::Monitor, (&Position, &Velocity)>()
32        .each_iter(|it, index, (_pos, _vel)| {
33            if it.event() == flecs::OnAdd::ID {
34                println!(
35                    " - Enter: {}: {}",
36                    it.event_id().to_str(),
37                    it.entity(index).name()
38                );
39            } else if it.event() == flecs::OnRemove::ID {
40                println!(
41                    " - Leave: {}: {}",
42                    it.event_id().to_str(),
43                    it.entity(index).name()
44                );
45            }
46        });
47
48    // Create entity
49    let entity = world.entity_named("e");
50
51    // This does not yet trigger the monitor, as the entity does not yet match.
52    entity.set(Position { x: 10.0, y: 20.0 });
53
54    // This triggers the monitor with EcsOnAdd, as the entity now matches.
55    entity.set(Velocity { x: 1.0, y: 2.0 });
56
57    // This triggers the monitor with EcsOnRemove, as the entity no longer matches.
58    entity.remove::<Position>();
59
60    // Output:
61    //  - Enter: Velocity: e
62    //  - Leave: Position: e
63}
examples/flecs/observers/observer_propagate.rs (line 27)
22fn main() {
23    let world = World::new();
24
25    // Create observer that listens for events from both self and parent
26    world
27        .observer::<flecs::OnSet, (&Position, &Position)>()
28        .term_at(1)
29        .parent()
30        .each_iter(|it, index, (pos_self, pos_parent)| {
31            println!(
32                " - {}: {}: {}: self: {{ {}, {} }}, parent: {{ {}, {} }}",
33                it.event().name(),
34                it.event_id().to_str(),
35                it.entity(index).name(),
36                pos_self.x,
37                pos_self.y,
38                pos_parent.x,
39                pos_parent.y
40            );
41        });
42
43    // Create entity and parent
44    let parent = world.entity_named("p");
45    let entity = world.entity_named("e").child_of_id(parent);
46
47    // Set Position on entity. This doesn't trigger the observer yet, since the
48    // parent doesn't have Position yet.
49    entity.set(Position { x: 10.0, y: 20.0 });
50
51    // Set Position on parent. This event will be propagated and trigger the
52    // observer, as the observer query now matches.
53    parent.set(Position { x: 1.0, y: 2.0 });
54
55    // Output:
56    //  - OnSet: Position: e: self: { 10, 20 }, parent: { 1, 2 }
57}
examples/flecs/observers/observer_basics.rs (line 16)
11fn main() {
12    let world = World::new();
13
14    // Create an observer for three events
15    world
16        .observer::<flecs::OnAdd, &Position>()
17        .add_event::<flecs::OnRemove>() //or .add_event_id(OnRemove::ID)
18        .add_event::<flecs::OnSet>()
19        .each_iter(|it, index, pos| {
20            if it.event() == flecs::OnAdd::ID {
21                // No assumptions about the component value should be made here. If
22                // a ctor for the component was registered it will be called before
23                // the EcsOnAdd event, but a value assigned by set won't be visible.
24                println!(" - OnAdd: {}: {}", it.event_id().to_str(), it.entity(index));
25            } else {
26                println!(
27                    " - {}: {}: {}: with {:?}",
28                    it.event().name(),
29                    it.event_id().to_str(),
30                    it.entity(index),
31                    pos
32                );
33            }
34        });
35
36    // Create entity, set Position (emits EcsOnAdd and EcsOnSet)
37    let entity = world.entity_named("e1").set(Position { x: 10.0, y: 20.0 });
38
39    // Remove Position (emits EcsOnRemove)
40    entity.remove::<Position>();
41
42    // Remove Position again (no event emitted)
43    entity.remove::<Position>();
44
45    // Output:
46    //  - OnAdd: Position: e1
47    //  - OnSet: Position: e1: with Position { x: 10.0, y: 20.0 }
48    //  - OnRemove: Position: e1: with Position { x: 10.0, y: 20.0 }
49}
Source

pub fn observer_id<Components>( &self, event: impl Into<Entity>, ) -> ObserverBuilder<'_, (), Components>
where Components: QueryTuple,

Source

pub fn observer_named<'a, Event: ComponentId, Components>( &'a self, name: &str, ) -> ObserverBuilder<'a, Event, Components>
where Components: QueryTuple,

Create a new named observer.

§Type Parameters
  • Components - The components to match on.
§Arguments
  • name - The name of the observer.
§Returns

Observer builder.

§See also
Source

pub fn new_query<Components>(&self) -> Query<Components>
where Components: QueryTuple,

Create a new uncached Query.

§Type Parameters
  • Components - The components to match on.
§See also
Examples found in repository?
examples/flecs/queries/query_find_entity.rs (line 19)
11fn main() {
12    let world = World::new();
13    // Create a few test entities for a Position query
14    world.entity_named("e1").set(Position { x: 10.0, y: 20.0 });
15
16    world.entity_named("e2").set(Position { x: 20.0, y: 30.0 });
17
18    // Create a simple query for component Position
19    let query = world.new_query::<&Position>();
20
21    let entity: Option<EntityView> = query.find(|pos| (pos.x - 20.0).abs() < f32::EPSILON);
22
23    if let Some(entity) = entity {
24        println!("Entity found: {:?}", entity.path().unwrap());
25    } else {
26        println!("Entity not found");
27    }
28
29    // Output:
30    //  Entity found: "::e2"
31}
More examples
Hide additional examples
examples/flecs/queries/query_wildcard.rs (line 21)
17fn main() {
18    let world = World::new();
19
20    // Create a query that matches edible components
21    let query = world.new_query::<&(EatsAmount, flecs::Wildcard)>();
22
23    // Create a few entities that match the query
24    world
25        .entity_named("Bob")
26        .set_pair::<EatsAmount, Apples>(EatsAmount { amount: 10 })
27        .set_pair::<EatsAmount, Pears>(EatsAmount { amount: 5 });
28
29    world
30        .entity_named("Alice")
31        .set_pair::<EatsAmount, Apples>(EatsAmount { amount: 4 });
32
33    // Iterate the query with a flecs::iter. This makes it possible to inspect
34    // the pair that we are currently matched with.
35    query.each_iter(|it, index, eats| {
36        let entity = it.entity(index);
37        let pair = it.pair(0).unwrap();
38        let food = pair.second_id();
39
40        println!("{} eats {} {}", entity, eats.amount, food);
41    });
42
43    // Output:
44    //  Alice eats 4 Apples
45    //  Bob eats 10 Apples
46    //  Bob eats 5 Pears
47}
examples/flecs/systems/system_ctx.rs (line 51)
43fn main() {
44    let world = World::new();
45
46    // Applications can pass context data to a system. A common use case where this
47    // comes in handy is when a system needs to iterate more than one query. The
48    // following example shows how to pass a custom query into a system for a simple
49    // collision detection example.
50
51    let mut query_collide = world.new_query::<(&Position, &Radius)>();
52
53    let sys = world
54        .system::<(&Position, &Radius)>()
55        .set_context(&mut query_collide as *mut Query<(&Position, &Radius)> as *mut c_void)
56        .each_iter(|mut it, index, (p1, r1)| {
57            let query = unsafe { it.context::<Query<(&Position, &Radius)>>() };
58            let e1 = it.entity(index);
59
60            query.each_entity(|e2, (p2, r2)| {
61                if e1 == *e2 {
62                    // don't collide with self
63                    return;
64                }
65
66                if e1 > *e2 {
67                    // Simple trick to prevent collisions from being detected
68                    // twice with the entities reversed.
69                    return;
70                }
71
72                // Check for collision
73                let d_sqr = distance_sqr(p1, p2);
74                let r_sqr = sqr(r1.value + r2.value);
75                if r_sqr > d_sqr {
76                    println!("{} and {} collided!", e1, e2);
77                }
78            });
79        });
80
81    // Create a few test entities
82    for _ in 0..10 {
83        world
84            .entity()
85            .set(Position {
86                x: rand(50),
87                y: rand(50),
88            })
89            .set(Radius {
90                value: rand(10) + 1.0,
91            });
92    }
93
94    // Run the system
95    sys.run();
96
97    // Output:
98    //  532 and 539 collided!
99    //  532 and 540 collided!
100    //  534 and 538 collided!
101    //  536 and 537 collided!
102    //  536 and 540 collided!
103    //  537 and 540 collided!
104}
examples/flecs/queries/query_basics.rs (line 22)
17fn main() {
18    let world = World::new();
19
20    // Create a query for Position, Velocity. Queries are the fastest way to
21    // iterate entities as they cache results.
22    let query = world.new_query::<(&mut Position, &Velocity)>();
23
24    // Create a few test entities for a Position, Velocity query
25    world
26        .entity_named("e1")
27        .set(Position { x: 10.0, y: 20.0 })
28        .set(Velocity { x: 1.0, y: 2.0 });
29
30    world
31        .entity_named("e2")
32        .set(Position { x: 10.0, y: 20.0 })
33        .set(Velocity { x: 3.0, y: 4.0 });
34
35    // This entity will not match as it does not have Position, Velocity
36    world.entity_named("e3").set(Position { x: 10.0, y: 20.0 });
37
38    // The next lines show the different ways in which a query can be iterated.
39
40    // `The each_entity()` function iterates each entity individually and accepts an
41    // entity argument plus arguments for each query component:
42    query.each_entity(|e, (pos, vel)| {
43        pos.x += vel.x;
44        pos.y += vel.y;
45        println!("{}: [{:?}]", e.name(), pos);
46    });
47
48    // There's an equivalent function that does not include the entity argument
49    query.each(|(pos, vel)| {
50        pos.x += vel.x;
51        pos.y += vel.y;
52        println!("[{:?}]", pos);
53    });
54
55    // Iter is a bit more verbose, but allows for more control over how entities
56    // are iterated as it provides multiple entities in the same callback.
57    // There's also an `iter_only` function that only provides the iterator.
58    query.run_iter(|it, (pos, vel)| {
59        for i in it.iter() {
60            pos[i].x += vel[i].x;
61            pos[i].y += vel[i].y;
62            println!("[{:?}]", pos[i]);
63        }
64    });
65
66    // Output:
67    //  e1: [Position { x: 11.0, y: 22.0 }]
68    //  e2: [Position { x: 13.0, y: 24.0 }]
69    //  [Position { x: 12.0, y: 24.0 }]
70    //  [Position { x: 16.0, y: 28.0 }]
71    //  [Position { x: 13.0, y: 26.0 }]
72    //  [Position { x: 19.0, y: 32.0 }]
73}
examples/flecs/queries/query_hierarchy.rs (line 73)
17fn main() {
18    let world = World::new();
19
20    let sun = world
21        .entity_named("Sun")
22        .set_pair::<Position, WorldX>(Position::default())
23        .set_pair::<Position, Local>(Position { x: 1.0, y: 1.0 });
24
25    world
26        .entity_named("Mercury")
27        .child_of_id(sun)
28        .set_pair::<Position, WorldX>(Position::default())
29        .set_pair::<Position, Local>(Position { x: 1.0, y: 1.0 });
30
31    world
32        .entity_named("Venus")
33        .child_of_id(sun)
34        .set_pair::<Position, WorldX>(Position::default())
35        .set_pair::<Position, Local>(Position { x: 2.0, y: 2.0 });
36
37    let earth = world
38        .entity_named("Earth")
39        .child_of_id(sun)
40        .set_pair::<Position, WorldX>(Position::default())
41        .set_pair::<Position, Local>(Position { x: 3.0, y: 3.0 });
42
43    world
44        .entity_named("Moon")
45        .child_of_id(earth)
46        .set_pair::<Position, WorldX>(Position::default())
47        .set_pair::<Position, Local>(Position { x: 0.1, y: 0.1 });
48
49    let query = world
50        .query::<(
51            &(Position, Local),
52            Option<&(Position, WorldX)>,
53            &mut (Position, WorldX),
54        )>()
55        .term_at(1)
56        .parent()
57        .cascade()
58        .build();
59
60    query.run_iter(|it, (local, parent_world, world)| {
61        for i in it.iter() {
62            world[i].x = local[i].x;
63            world[i].y = local[i].y;
64            if parent_world.is_some() {
65                let parent_world = parent_world.unwrap();
66                world[i].x += parent_world[i].x;
67                world[i].y += parent_world[i].y;
68            }
69        }
70    });
71
72    world
73        .new_query::<&(Position, WorldX)>()
74        .each_entity(|entity, position| {
75            println!(
76                "Entity {} is at ({}, {})",
77                entity.name(),
78                position.x,
79                position.y
80            );
81        });
82
83    // Output:
84    //  Entity Sun is at (1, 1)
85    //  Entity Mercury is at (2, 2)
86    //  Entity Venus is at (3, 3)
87    //  Entity Earth is at (4, 4)
88    //  Entity Moon is at (4.1, 4.1)
89}
examples/flecs/queries/query_run_iter.rs (line 25)
22fn main() {
23    let world = World::new();
24
25    let query = world.new_query::<(&mut Position, &Velocity)>();
26
27    // Create a few test entities for a Position, Velocity query
28    world
29        .entity_named("e1")
30        .set(Position { x: 10.0, y: 20.0 })
31        .set(Velocity { x: 1.0, y: 2.0 });
32
33    world
34        .entity_named("e2")
35        .set(Position { x: 10.0, y: 20.0 })
36        .set(Velocity { x: 3.0, y: 4.0 });
37
38    world
39        .entity_named("e3")
40        .set(Position { x: 10.0, y: 20.0 })
41        .set(Velocity { x: 4.0, y: 5.0 })
42        .set(Mass { value: 50.0 });
43
44    // The iter function provides a flecs::iter object which contains all sorts
45    // of information on the entities currently being iterated.
46    // The function passed to iter is by default called for each table the query
47    // is matched with.
48    query.run_iter(|it, (position, velocity)| {
49        println!();
50        // Print the table & number of entities matched in current callback
51        println!("Table: {:?}", it.archetype());
52        println!(" - number of entities: {}", it.count());
53        println!();
54
55        // Print information about the components being matched
56        for i in 0..it.field_count() {
57            println!(" - term {} : ", i);
58            println!("   - component: {}", it.id(i).to_str());
59            println!("   - type size: {}", it.size(i));
60        }
61
62        println!();
63
64        for i in it.iter() {
65            position[i].x += velocity[i].x;
66            position[i].y += velocity[i].y;
67            println!(" - entity {}: has {:?}", it.entity(i).name(), position[i]);
68        }
69
70        println!();
71    });
72
73    // Output:
74    //  Table: Position, Velocity, (Identifier,Name)
75    //  - number of entities: 2
76    //
77    //  - term 1 :
78    //    - component: Position
79    //    - type size: 8
80    //  - term 2 :
81    //    - component: Velocity
82    //    - type size: 8
83    //
84    //  - entity e1: has Position { x: 11.0, y: 22.0 }
85    //  - entity e2: has Position { x: 13.0, y: 24.0 }
86    //
87    //
88    // Table: Position, Velocity, Mass, (Identifier,Name)
89    //  - number of entities: 1
90    //
91    //  - term 1 :
92    //    - component: Position
93    //    - type size: 8
94    //  - term 2 :
95    //    - component: Velocity
96    //    - type size: 8
97    //
98    //  - entity e3: has Position { x: 14.0, y: 25.0 }
99    //
100}
Source

pub fn new_query_named<Components>(&self, name: &str) -> Query<Components>
where Components: QueryTuple,

Create a new named Query.

§Type Parameters
  • Components - The components to match on.
§Arguments
  • name - The name of the query.
§Returns

A new query.

§See also
Source

pub fn query<Components>(&self) -> QueryBuilder<'_, Components>
where Components: QueryTuple,

Create a new QueryBuilder.

§Type Parameters
  • Components - The components to match on.
§Returns

A new query builder.

§See also
Examples found in repository?
examples/flecs/queries/query_singleton.rs (line 28)
15fn main() {
16    let world = World::new();
17
18    // Set singleton
19    world.set(Gravity { value: 9.81 });
20
21    // Set Velocity
22    world.entity_named("e1").set(Velocity { x: 0.0, y: 0.0 });
23    world.entity_named("e2").set(Velocity { x: 0.0, y: 1.0 });
24    world.entity_named("e3").set(Velocity { x: 0.0, y: 2.0 });
25
26    // Create query that matches Gravity as singleton
27    let query = world
28        .query::<(&mut Velocity, &Gravity)>()
29        .term_at(1)
30        .singleton()
31        .build();
32
33    // In a query string expression you can use the $ shortcut for singletons:
34    //   Velocity, Gravity($)
35
36    query.each_entity(|entity, (velocity, gravity)| {
37        velocity.y += gravity.value;
38        println!("Entity {} has {:?}", entity.path().unwrap(), velocity);
39    });
40
41    // Output:
42    // Entity ::e1 has Velocity { x: 0.0, y: 9.81 }
43    // Entity ::e2 has Velocity { x: 0.0, y: 10.81 }
44    // Entity ::e3 has Velocity { x: 0.0, y: 11.81 }
45}
More examples
Hide additional examples
examples/flecs/queries/query_with.rs (line 22)
14fn main() {
15    let world = World::new();
16
17    // Create a query for Position, Npc. By adding the Npc component using the
18    // "with" method, the component is not a part of the query type, and as a
19    // result does not become part of the function signatures of each and iter.
20    // This is useful for things like tags, which because they don't have a
21    // value are less useful to pass to the each/iter functions as argument.
22    let query = world.query::<&Position>().with::<&Npc>().build();
23
24    // Create a few test entities for the Position, Npc query
25    world
26        .entity_named("e1")
27        .set(Position { x: 10.0, y: 20.0 })
28        .add::<Npc>();
29
30    world
31        .entity_named("e2")
32        .set(Position { x: 10.0, y: 20.0 })
33        .add::<Npc>();
34
35    // This entity will not match as it does not have Position, Npc
36    world.entity_named("e3").set(Position { x: 10.0, y: 20.0 });
37
38    // Note how the Npc tag is not part of the each signature
39    query.each_entity(|entity, pos| {
40        println!("Entity {}: {:?}", entity.name(), pos);
41    });
42
43    // Output:
44    //  Entity e1: Position { x: 10.0, y: 20.0 }
45    //  Entity e2: Position { x: 10.0, y: 20.0 }
46}
examples/flecs/queries/query_without.rs (line 25)
14fn main() {
15    let world = World::new();
16
17    // Create a query for Position, !Npc. By adding the Npc component using the
18    // "without" method, the component is not a part of the query type, and as a
19    // result does not become part of the function signatures of each and iter.
20    // This is useful for things like tags, which because they don't have a
21    // value are less useful to pass to the each/iter functions as argument.
22    //
23    // The without method is short for:
24    //   .term<Npc>().not_()
25    let query = world.query::<&Position>().without::<&Npc>().build();
26
27    // Create a few test entities for the Position query
28    world.entity_named("e1").set(Position { x: 10.0, y: 20.0 });
29
30    world.entity_named("e2").set(Position { x: 10.0, y: 20.0 });
31
32    // This entity will not match as it has Npc
33    world
34        .entity_named("e3")
35        .set(Position { x: 10.0, y: 20.0 })
36        .add::<Npc>();
37
38    // Note how the Npc tag is not part of the each signature
39    query.each_entity(|entity, pos| {
40        println!("Entity {}: {:?}", entity.name(), pos);
41    });
42
43    // Output:
44    //  Entity e1: Position { x: 10.0, y: 20.0 }
45    //  Entity e2: Position { x: 10.0, y: 20.0 }
46}
examples/flecs/queries/query_component_inheritance.rs (line 58)
30fn main() {
31    let world = World::new();
32
33    // Make the ECS aware of the inheritance relationships. Note that IsA
34    // relationship used here is the same as in the prefab example.
35    world.component::<CombatUnit>().is_a::<Unit>();
36    world.component::<MeleeUnit>().is_a::<CombatUnit>();
37    world.component::<RangedUnit>().is_a::<CombatUnit>();
38
39    world.component::<Warrior>().is_a::<MeleeUnit>();
40    world.component::<Wizard>().is_a::<RangedUnit>();
41    world.component::<Marksman>().is_a::<RangedUnit>();
42    world.component::<BuilderX>().is_a::<Unit>();
43
44    // Create a few units
45    world.entity_named("warrior_1").add::<Warrior>();
46    world.entity_named("warrior_2").add::<Warrior>();
47
48    world.entity_named("marksman_1").add::<Marksman>();
49    world.entity_named("marksman_2").add::<Marksman>();
50
51    world.entity_named("wizard_1").add::<Wizard>();
52    world.entity_named("wizard_2").add::<Wizard>();
53
54    world.entity_named("builder_1").add::<BuilderX>();
55    world.entity_named("builder_2").add::<BuilderX>();
56
57    // Create a rule to find all ranged units
58    let r = world.query::<&RangedUnit>().build();
59
60    // Iterate the rule
61    r.each_entity(|e, rangedunit| {
62        println!("Unit {} found", e.name());
63    });
64
65    // Output:
66    //  Unit wizard_1 found
67    //  Unit wizard_2 found
68    //  Unit marksman_1 found
69    //  Unit marksman_2 found
70}
examples/flecs/relationships/relationships_union.rs (line 46)
35fn main() {
36    let world = World::new();
37
38    // Register Movement and Direction as union relationships. This ensures that
39    // an entity can only have one Movement and one Direction.
40    world.component::<Movement>().add::<flecs::Union>();
41    world.component::<Direction>().add::<flecs::Union>();
42
43    // Create a query that subscribes for all entities that have a Direction
44    // and that are walking.
45    let q = world
46        .query::<()>()
47        .with_enum(Movement::Walking)
48        .with_enum_wildcard::<Direction>()
49        .build();
50
51    // Create a few entities with various state combinations
52    world
53        .entity_named("e1")
54        .add_enum(Movement::Walking)
55        .add_enum(Direction::Front);
56
57    world
58        .entity_named("e2")
59        .add_enum(Movement::Running)
60        .add_enum(Direction::Left);
61
62    let e3 = world
63        .entity_named("e3")
64        .add_enum(Movement::Running)
65        .add_enum(Direction::Back);
66
67    // Add Walking to e3. This will remove the Running case
68    e3.add_enum(Movement::Walking);
69
70    // Iterate the query
71    q.each_iter(|it, index, ()| {
72        let entity = it.entity(index);
73
74        // Movement will always be Walking, Direction can be any state
75        println!(
76            "{}: Movement: {:?}, Direction: {:?}",
77            entity.name(),
78            it.pair(0).unwrap().second_id().name(),
79            it.pair(1).unwrap().second_id().name()
80        );
81    });
82
83    // Output:
84    //   e3: Movement: Walking, Direction: Back
85    //   e1: Movement: Walking, Direction: Front
86}
examples/flecs/queries/query_group_by.rs (line 33)
26fn main() {
27    let world = World::new();
28
29    world.component::<First>();
30    world.component::<Second>();
31    world.component::<Third>();
32
33    let query = world.query::<&Position>().group_by::<Group>().build();
34
35    world
36        .entity()
37        .add::<(Group, Third)>()
38        .set(Position { x: 1.0, y: 1.0 });
39    world
40        .entity()
41        .add::<(Group, Second)>()
42        .set(Position { x: 2.0, y: 2.0 });
43    world
44        .entity()
45        .add::<(Group, First)>()
46        .set(Position { x: 3.0, y: 3.0 });
47
48    world
49        .entity()
50        .add::<(Group, Third)>()
51        .set(Position { x: 4.0, y: 4.0 })
52        .add::<Tag>();
53    world
54        .entity()
55        .add::<(Group, Second)>()
56        .set(Position { x: 5.0, y: 5.0 })
57        .add::<Tag>();
58    world
59        .entity()
60        .add::<(Group, First)>()
61        .set(Position { x: 6.0, y: 6.0 })
62        .add::<Tag>();
63
64    println!();
65
66    query.run_iter(|it, pos| {
67        let group = world.entity_from_id(it.group_id());
68        println!(
69            "Group: {:?} - Table: [{:?}]",
70            group.path().unwrap(),
71            it.archetype()
72        );
73
74        for i in it.iter() {
75            println!(" [{:?}]", pos[i]);
76        }
77
78        println!();
79    });
80
81    // Output:
82    //  Group: "::First" - Table: [Position, (Group,First)]
83    //  [Position { x: 3.0, y: 3.0 }]
84    //
85    //  Group: "::First" - Table: [Position, Tag, (Group,First)]
86    //  [Position { x: 6.0, y: 6.0 }]
87    //
88    //  Group: "::Second" - Table: [Position, (Group,Second)]
89    //  [Position { x: 2.0, y: 2.0 }]
90    //
91    //  Group: "::Second" - Table: [Position, Tag, (Group,Second)]
92    //  [Position { x: 5.0, y: 5.0 }]
93    //
94    //  Group: "::Third" - Table: [Position, (Group,Third)]
95    //  [Position { x: 1.0, y: 1.0 }]
96    //
97    //  Group: "::Third" - Table: [Position, Tag, (Group,Third)]
98    //  [Position { x: 4.0, y: 4.0 }]
99}
Source

pub fn query_named<'a, Components>( &'a self, name: &str, ) -> QueryBuilder<'a, Components>
where Components: QueryTuple,

Create a new named QueryBuilder.

§Type Parameters
  • Components - The components to match on.
§Arguments
  • name - The name of the query.
§Returns

A new query builder.

§See also
Source

pub fn try_query_from( &self, query_entity: impl Into<Entity>, ) -> Option<Query<()>>

Convert a query entity to a query.

§Safety

Proceed with caution. Use .iter_only instead.

§Returns

returns the untyped query if the entity is alive, otherwise None.

Source

pub fn query_from(&self, query_entity: impl Into<Entity>) -> Query<()>

Convert a query entity to a query. this method is the same as try_to_query but it automatically unwraps the result.

§Safety

Proceed with caution. Use .iter_only instead.

§Panics

Panics if the entity is not alive or a query. Use try_to_query if you are unsure.

Source

pub fn each<Components>( &self, func: impl FnMut(Components::TupleType<'_>), ) -> Query<Components>
where Components: QueryTuple,

Create and iterate an uncached query.

This function creates a query and immediately iterates it.

§Returns

The query.

§Type Parameters
  • Components: The components to match on.
§See also
Source

pub fn each_entity<Components>( &self, func: impl FnMut(EntityView<'_>, Components::TupleType<'_>), ) -> Query<Components>
where Components: QueryTuple,

Create and iterate an uncached query.

This function creates a query and immediately iterates it.

§Returns

The query.

§Type Parameters
  • Components: The components to match on.
§See also
Examples found in repository?
examples/flecs/queries/query_world_query.rs (lines 39-43)
17fn main() {
18    let world = World::new();
19
20    // Create a few test entities for a Position, Velocity query
21    world
22        .entity_named("e1")
23        .set(Position { x: 10.0, y: 20.0 })
24        .set(Velocity { x: 1.0, y: 2.0 });
25
26    world
27        .entity_named("e2")
28        .set(Position { x: 10.0, y: 20.0 })
29        .set(Velocity { x: 3.0, y: 4.0 });
30
31    // This entity will not match as it does not have Position, Velocity
32    world.entity_named("e3").set(Position { x: 10.0, y: 20.0 });
33
34    // Ad hoc queries are bit slower to iterate than flecs::query, but are
35    // faster to create, and in most cases require no allocations. Under the
36    // hood this API uses flecs::query, which can be used directly for more
37    // complex queries.
38
39    world.each_entity::<(&mut Position, &Velocity)>(|entity, (pos, vel)| {
40        pos.x += vel.x;
41        pos.y += vel.y;
42        println!("Entity {}: {:?}", entity.name(), pos);
43    });
44
45    // Output:
46    //  Entity e1: Position { x: 11.0, y: 22.0 }
47    //  Entity e2: Position { x: 13.0, y: 24.0 }
48}
More examples
Hide additional examples
examples/flecs/prefabs/prefab_basics.rs (lines 54-56)
28fn main() {
29    let world = World::new();
30
31    // Add the traits to mark the component to be inherited
32    world
33        .component::<Defence>()
34        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
35
36    // Create a prefab with Position and Velocity components
37    let spaceship = world.prefab_named("Prefab").set(Defence { value: 50.0 });
38
39    // Create a prefab instance
40    let inst = world.entity_named("my_spaceship").is_a_id(spaceship);
41
42    // Because of the IsA relationship, the instance now shares the Defense
43    // component with the prefab, and can be retrieved as a regular component:
44    inst.try_get::<&Defence>(|d_inst| {
45        println!("{:?}", d_inst);
46        // Because the component is shared, changing the value on the prefab will
47        // also change the value for the instance:
48        // this is safe during a table lock because it also has the component and won't cause the table to move.
49        spaceship.set(Defence { value: 100.0 });
50        println!("after set: {:?}", d_inst);
51    });
52
53    // Prefab components can be iterated like regular components:
54    world.each_entity::<&Defence>(|entity, d| {
55        println!("{}: defence: {}", entity.path().unwrap(), d.value);
56    });
57
58    // Output:
59    //  Defence { value: 50.0 }
60    //  after set: Defence { value: 100.0 }
61    //  ::my_spaceship: 100
62}
examples/flecs/entities/entity_basics.rs (lines 61-63)
20fn main() {
21    let world = World::new();
22
23    // Create an entity with name Bob
24    let bob = world
25        .entity_named("Bob")
26        // The set operation finds or creates a component, and sets it.
27        // Components are automatically registered with the world
28        .set(Position { x: 10.0, y: 20.0 })
29        // The add operation adds a component without setting a value. This is
30        // useful for tags, or when adding a component with its default value.
31        .add::<Walking>();
32
33    // Get the value for the Position component
34    // - get panics if the component is not present, use try_get for a non-panicking version which does not run the callback.
35    // - or use Option to handle the individual component missing.
36    bob.get::<Option<&Position>>(|pos| {
37        if let Some(pos) = pos {
38            println!("Bob's position: {:?}", pos);
39        }
40    });
41
42    // Overwrite the value of the Position component
43    bob.set(Position { x: 20.0, y: 30.0 });
44
45    // Create another named entity
46    let alice = world
47        .entity_named("Alice")
48        .set(Position { x: 10.0, y: 20.0 });
49
50    // Add a tag after entity is created
51    alice.add::<Walking>();
52
53    // Print all of the components the entity has. This will output:
54    //    Position, Walking, (Identifier,Name)
55    println!("[{}]", alice.archetype());
56
57    // Remove tag
58    alice.remove::<Walking>();
59
60    // Iterate all entities with position
61    world.each_entity::<&Position>(|entity, pos| {
62        println!("{} has {:?}", entity.name(), pos);
63    });
64
65    // Output:
66    //  Bob's position: Position { x: 10.0, y: 20.0 }
67    //  [Position, Walking, (Identifier,Name)]
68    //  Alice has Position { x: 10.0, y: 20.0 }
69    //  Bob has Position { x: 20.0, y: 30.0 }
70}
examples/flecs/prefabs/prefab_variant.rs (lines 79-87)
34fn main() {
35    let world = World::new();
36
37    // Create a base prefab for SpaceShips.
38    let spaceship = world
39        .prefab_named("SpaceShip")
40        .set(ImpulseSpeed { value: 50.0 })
41        .set(Defence { value: 25.0 });
42
43    // Create a Freighter variant which inherits from SpaceShip
44    let freighter = world
45        .prefab_named("Freighter")
46        .is_a_id(spaceship)
47        .set(FreightCapacity { value: 100.0 })
48        .set(Defence { value: 50.0 });
49
50    // Create a MammotFreighter variant which inherits from Freighter
51    let mammoth_freighter = world
52        .prefab_named("MammothFreighter")
53        .is_a_id(freighter)
54        .set(FreightCapacity { value: 500.0 });
55
56    // Create a Frigate variant which inherits from SpaceShip
57    world
58        .prefab_named("Frigate")
59        .is_a_id(spaceship)
60        .set(Attack { value: 100.0 })
61        .set(Defence { value: 75.0 })
62        .set(ImpulseSpeed { value: 125.0 });
63
64    // Create an instance of the MammothFreighter. This entity will inherit the
65    // ImpulseSpeed from SpaceShip, Defence from Freighter and FreightCapacity
66    // from MammothFreighter.
67    let inst = world
68        .entity_named("my_freighter")
69        .is_a_id(mammoth_freighter);
70
71    // Add a private Position component.
72    inst.set(Position { x: 10.0, y: 20.0 });
73
74    // Instances can override inherited components to give them a private copy
75    // of the component. This freighter got an armor upgrade:
76    inst.set(Defence { value: 100.0 });
77
78    // Queries can match components from multiple levels of inheritance
79    world.each_entity::<(&Position, &ImpulseSpeed, &Defence, &FreightCapacity)>(
80        |e, (p, s, d, c)| {
81            println!("{}:", e.name());
82            println!(" - position: {}, {}", p.x, p.y);
83            println!(" - impulse speed: {}", s.value);
84            println!(" - defense: {}", d.value);
85            println!(" - capacity: {}", c.value);
86        },
87    );
88
89    // Output:
90    //   my_freighter:
91    //    - position: 10, 20
92    //    - impulse speed: 50
93    //    - defense: 100
94    //    - capacity: 500
95}
examples/flecs/entities/entity_prefab.rs (lines 105-108)
34fn main() {
35    let world = World::new();
36
37    // Add the traits to mark the components to be inherited
38    world
39        .component::<Position>()
40        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
41    world
42        .component::<Defence>()
43        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
44    world
45        .component::<ImpulseSpeed>()
46        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
47    world
48        .component::<FreightCapacity>()
49        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
50    world
51        .component::<HasFlt>()
52        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
53
54    // Create a prefab hierarchy.
55    let spaceship = world
56        .prefab_named("Spaceship")
57        // Add components to prefab entity as usual
58        .set(ImpulseSpeed { value: 50.0 })
59        .set(Defence { value: 50.0 })
60        .set(Position { x: 0.0, y: 0.0 })
61        // By default components in an inheritance hierarchy are shared between
62        // entities. The override function ensures that instances have a private
63        // copy of the component.
64        .auto_override::<Position>();
65
66    let freighter = world
67        .prefab_named("Freighter")
68        .is_a_id(spaceship)
69        .set(FreightCapacity { value: 100.0 })
70        .set(Defence { value: 100.0 })
71        .add::<HasFlt>();
72
73    let mammoth_freighter = world
74        .prefab_named("MammothFreighter")
75        .is_a_id(freighter)
76        .set(FreightCapacity { value: 500.0 })
77        .set(Defence { value: 300.0 });
78
79    world
80        .prefab_named("Frigate")
81        .is_a_id(spaceship)
82        .add::<HasFlt>()
83        .set(Attack { value: 100.0 })
84        .set(Defence { value: 75.0 })
85        .set(ImpulseSpeed { value: 125.0 });
86
87    // Create a regular entity from a prefab.
88    // The instance will have a private copy of the Position component, because
89    // of the override in the spaceship entity. All other components are shared.
90    let inst = world
91        .entity_named("my_mammoth_freighter")
92        .is_a_id(mammoth_freighter);
93
94    // Inspect the type of the entity. This outputs:
95    //    Position,(Identifier,Name),(IsA,MammothFreighter)
96    println!("Instance type: [{}]", inst.archetype());
97
98    // Even though the instance doesn't have a private copy of ImpulseSpeed, we
99    // can still get it using the regular API (outputs 50)
100    inst.try_get::<&ImpulseSpeed>(|impulse_speed| {
101        println!("ImpulseSpeed: {}", impulse_speed.value);
102    });
103
104    // Prefab components can be iterated just like regular components:
105    world.each_entity::<(&ImpulseSpeed, &mut Position)>(|entity, (impulse_speed, position)| {
106        position.x += impulse_speed.value;
107        println!("Entity {}: {:?}", entity.name(), position);
108    });
109
110    // Output:
111    //  Instance type: [Position, (Identifier,Name), (IsA,MammothFreighter)]
112    //  ImpulseSpeed: 50
113    //  Entity my_mammoth_freighter: Position { x: 50.0, y: 0.0 }
114}
Source

pub fn system_from<'a>(&'a self, entity: EntityView<'a>) -> System<'a>

Available on crate feature flecs_system only.

Constructs a System from an existing entity.

This function upcasts the given entity to a System, assuming the entity represents a system. The purpose is to facilitate the interaction with entities that are specifically systems within the ECS.

§Arguments
  • entity - An EntityView that represents a system within the world.
§See also
  • C++ API: world::system
Source

pub fn system<Components>(&self) -> SystemBuilder<'_, Components>
where Components: QueryTuple,

Available on crate feature flecs_system only.

Creates a new SystemBuilder instance for constructing systems.

This function initializes a SystemBuilder which is used to create systems that match specific components. It is a generic method that works with any component types that implement the QueryTuple trait.

§Type Parameters
  • Components: The components to match on. Must implement the QueryTuple trait.
§See also
Examples found in repository?
examples/flecs/systems/system_time_interval.rs (line 23)
17fn main() {
18    let world = World::new();
19
20    world.set(Timeout { value: 3.5 });
21
22    world
23        .system::<&mut Timeout>()
24        .each_iter(|it, _index, timeout| {
25            timeout.value -= it.delta_time();
26        });
27
28    world.system_named::<()>("Tick").interval(1.0).run(tick);
29
30    world.system_named::<()>("FastTick").interval(0.5).run(tick);
31
32    // Run the main loop at 60 FPS
33    world.set_target_fps(60.0);
34
35    while world.progress() {
36        if world.map::<&Timeout, _>(|timeout| timeout.value <= 0.0) {
37            println!("Timed out!");
38            break;
39        }
40    }
41
42    // Output:
43    // FastTick
44    // Tick
45    // FastTick
46    // FastTick
47    // Tick
48    // FastTick
49    // FastTick
50    // Tick
51    // FastTick
52    // FastTick
53    // Timed out!
54}
More examples
Hide additional examples
examples/flecs/systems/system_custom_pipeline.rs (line 31)
15fn main() {
16    let world = World::new();
17
18    // Create a pipeline that matches systems with Physics. Note that this
19    // pipeline does not require the use of phases (see custom_phases) or of the
20    // DependsOn relationship.
21    let pipeline = world
22        .pipeline()
23        .with_id(flecs::system::System::ID)
24        .with::<&Physics>()
25        .build();
26
27    // Configure the world to use the custom pipeline
28    world.set_pipeline_id(pipeline.entity());
29
30    // Create system with Physics tag
31    world.system::<()>().kind::<Physics>().run(|mut it| {
32        while it.next() {
33            println!("System with Physics ran!");
34        }
35    });
36
37    // Create system without Physics tag
38    world.system::<()>().run(|mut it| {
39        while it.next() {
40            println!("System without Physics ran!");
41        }
42    });
43
44    // Runs the pipeline & system
45    world.progress();
46
47    // Output:
48    //   System with Physics ran!
49}
examples/flecs/systems/system_basics.rs (line 24)
17fn main() {
18    let world = World::new();
19
20    // Create a system for Position, Velocity. Systems are like queries (see
21    // queries) with a function that can be ran or scheduled (see pipeline).
22
23    let s = world
24        .system::<(&mut Position, &Velocity)>()
25        .each_entity(|e, (p, v)| {
26            p.x += v.x;
27            p.y += v.y;
28            println!("{}: {{ {}, {} }}", e.name(), p.x, p.y);
29        });
30
31    // Create a few test entities for a Position, Velocity query
32    world
33        .entity_named("e1")
34        .set(Position { x: 10.0, y: 20.0 })
35        .set(Velocity { x: 1.0, y: 2.0 });
36
37    world
38        .entity_named("e2")
39        .set(Position { x: 10.0, y: 20.0 })
40        .set(Velocity { x: 3.0, y: 4.0 });
41
42    // This entity will not match as it does not have Position, Velocity
43    world.entity_named("e3").set(Position { x: 10.0, y: 20.0 });
44
45    // Run the system
46    s.run();
47
48    // Output:
49    //  e1: { 11, 22 }
50    //  e2: { 13, 24 }
51}
examples/flecs/systems/system_delta_time.rs (line 11)
5fn main() {
6    let world = World::new();
7
8    // Create system that prints delta_time. This system doesn't query for any
9    // components which means it won't match any entities, but will still be ran
10    // once for each call to ecs_progress.
11    world.system::<()>().run(|mut it| {
12        while it.next() {
13            println!("delta_time: {}", it.delta_time());
14        }
15    });
16
17    // Call progress with 0.0f for the delta_time parameter. This will cause
18    // ecs_progress to measure the time passed since the last frame. The
19    // delta_time of the first frame is a best guess (16ms).
20    world.progress();
21
22    // The following calls should print a delta_time of approximately 100ms
23
24    let os_sleep = unsafe { flecs_ecs_sys::ecs_os_api.sleep_ }.unwrap();
25
26    unsafe { os_sleep(0, 100 * 1000 * 1000) };
27    world.progress();
28
29    unsafe { os_sleep(0, 100 * 1000 * 1000) };
30
31    world.progress();
32
33    // Output:
34    //  delta_time: 0.016666668
35    //  delta_time: 0.10155179
36    //  delta_time: 0.10091246
37}
examples/flecs/systems/system_pipeline.rs (line 22)
17fn main() {
18    let world = World::new();
19
20    // Create a system for moving an entity
21    world
22        .system::<(&mut Position, &Velocity)>()
23        .kind::<flecs::pipeline::OnUpdate>()
24        .each(|(p, v)| {
25            p.x += v.x;
26            p.y += v.y;
27        });
28
29    // Create a system for printing the entity position
30    world
31        .system::<&Position>()
32        .kind::<flecs::pipeline::PostUpdate>()
33        .each_entity(|e, p| {
34            println!("{}: {{ {}, {} }}", e.name(), p.x, p.y);
35        });
36
37    // Create a few test entities for a Position, Velocity query
38    world
39        .entity_named("e1")
40        .set(Position { x: 10.0, y: 20.0 })
41        .set(Velocity { x: 1.0, y: 2.0 });
42
43    world
44        .entity_named("e2")
45        .set(Position { x: 10.0, y: 20.0 })
46        .set(Velocity { x: 3.0, y: 4.0 });
47
48    // Run the default pipeline. This will run all systems ordered by their
49    // phase. Systems within the same phase are ran in declaration order. This
50    // function is usually called in a loop.
51    world.progress();
52
53    // Output:
54    //  e1: { 11, 22 }
55    //  e2: { 13, 24 }
56}
examples/flecs/systems/system_custom_runner.rs (line 28)
24fn main() {
25    let world = World::new();
26
27    let system = world
28        .system::<(&mut Position, &Velocity)>()
29        // Forward each result from the run callback to the each callback.
30        .run_each_entity(
31            |mut iter| {
32                println!("Move begin");
33
34                while iter.next() {
35                    iter.each();
36                }
37
38                println!("Move end");
39            },
40            |e, (pos, vel)| {
41                pos.x += vel.x;
42                pos.y += vel.y;
43                println!("{}: {{ {}, {} }}", e.name(), pos.x, pos.y);
44            },
45        );
46
47    // Create a few test entities for a Position, Velocity query
48    world
49        .entity_named("e1")
50        .set(Position { x: 10.0, y: 20.0 })
51        .set(Velocity { x: 1.0, y: 2.0 });
52
53    world
54        .entity_named("e2")
55        .set(Position { x: 10.0, y: 20.0 })
56        .set(Velocity { x: 3.0, y: 4.0 });
57
58    // This entity will not match as it does not have Position, Velocity
59    world.entity_named("e3").set(Position { x: 10.0, y: 20.0 });
60
61    // Run the system
62    system.run();
63
64    // Output:
65    //  Move begin
66    //  e1: {11, 22}
67    //  e2: {13, 24}
68    //  Move end
69}
Source

pub fn system_named<'a, Components>( &'a self, name: &str, ) -> SystemBuilder<'a, Components>
where Components: QueryTuple,

Available on crate feature flecs_system only.

Creates a new named SystemBuilder instance.

Similar to system_builder, but allows naming the system for easier identification and debugging. The name does not affect the system’s behavior.

§Arguments
  • name - A string slice representing the name of the system.
§Type Parameters
  • Components: The components to match on. Must implement the QueryTuple trait.
§See also
Examples found in repository?
examples/flecs/systems/system_startup_system.rs (line 18)
13fn main() {
14    let world = World::new();
15
16    // Startup system
17    world
18        .system_named::<()>("Startup")
19        .kind::<flecs::pipeline::OnStart>()
20        .run(|mut it| {
21            while it.next() {
22                println!("{}", it.system().name());
23            }
24        });
25
26    // Regular system
27    world.system_named::<()>("Update").run(|mut it| {
28        while it.next() {
29            println!("{}", it.system().name());
30        }
31    });
32
33    // First frame. This runs both the Startup and Update systems
34    world.progress();
35
36    // Second frame. This runs only the Update system
37    world.progress();
38
39    // Output:
40    //  Startup
41    //  Update
42    //  Update
43}
More examples
Hide additional examples
examples/flecs/systems/system_time_interval.rs (line 28)
17fn main() {
18    let world = World::new();
19
20    world.set(Timeout { value: 3.5 });
21
22    world
23        .system::<&mut Timeout>()
24        .each_iter(|it, _index, timeout| {
25            timeout.value -= it.delta_time();
26        });
27
28    world.system_named::<()>("Tick").interval(1.0).run(tick);
29
30    world.system_named::<()>("FastTick").interval(0.5).run(tick);
31
32    // Run the main loop at 60 FPS
33    world.set_target_fps(60.0);
34
35    while world.progress() {
36        if world.map::<&Timeout, _>(|timeout| timeout.value <= 0.0) {
37            println!("Timed out!");
38            break;
39        }
40    }
41
42    // Output:
43    // FastTick
44    // Tick
45    // FastTick
46    // FastTick
47    // Tick
48    // FastTick
49    // FastTick
50    // Tick
51    // FastTick
52    // FastTick
53    // Timed out!
54}
examples/flecs/systems/system_custom_phases_no_builtin.rs (line 36)
15fn main() {
16    let world = World::new();
17
18    // Create three custom phases. Note that the phases have the Phase tag,
19    // which is necessary for the builtin pipeline to discover which systems it
20    // should run.
21
22    let update = world.entity().add::<flecs::pipeline::Phase>();
23
24    let physics = world
25        .entity()
26        .add::<flecs::pipeline::Phase>()
27        .depends_on_id(update);
28
29    let collisions = world
30        .entity()
31        .add::<flecs::pipeline::Phase>()
32        .depends_on_id(physics);
33
34    // Create 3 dummy systems.
35    world
36        .system_named::<()>("CollisionSystem")
37        .kind_id(collisions)
38        .run(sys);
39
40    world
41        .system_named::<()>("PhysicsSystem")
42        .kind_id(physics)
43        .run(sys);
44
45    world
46        .system_named::<()>("GameSystem")
47        .kind_id(update)
48        .run(sys);
49
50    // Run pipeline
51    world.progress();
52
53    // Output:
54    //   system GameSystem
55    //   system PhysicsSystem
56    //   system CollisionSystem
57}
examples/flecs/systems/system_custom_phases.rs (line 33)
15fn main() {
16    let world = World::new();
17
18    // Create two custom phases that branch off of EcsOnUpdate. Note that the
19    // phases have the Phase tag, which is necessary for the builtin pipeline
20    // to discover which systems it should run.
21    let physics = world
22        .entity()
23        .add::<flecs::pipeline::Phase>()
24        .depends_on::<flecs::pipeline::OnUpdate>();
25
26    let collisions = world
27        .entity()
28        .add::<flecs::pipeline::Phase>()
29        .depends_on_id(physics);
30
31    // Create 3 dummy systems.
32    world
33        .system_named::<()>("CollisionSystem")
34        .kind_id(collisions)
35        .run(sys);
36
37    world
38        .system_named::<()>("PhysicsSystem")
39        .kind_id(physics)
40        .run(sys);
41
42    world
43        .system_named::<()>("GameSystem")
44        .kind::<flecs::pipeline::OnUpdate>()
45        .run(sys);
46
47    // Run pipeline
48    world.progress();
49
50    // Output:
51    //   system GameSystem
52    //   system PhysicsSystem
53    //   system CollisionSystem
54}
examples/flecs/systems/system_sync_point.rs (line 34)
16fn main() {
17    let world = World::new();
18
19    // System that sets velocity using ecs_set for entities with PositionSP.
20    // While systems are progressing, operations like ecs_set are deferred until
21    // it is safe to merge. By default this merge happens at the end of the
22    // frame, but we can annotate systems to give the scheduler more information
23    // about what it's doing, which allows it to insert sync points earlier.
24    //
25    // Note that sync points are never necessary/inserted for systems that write
26    // components provided by their signature, as these writes directly happen
27    // in the ECS storage and are never deferred.
28    //
29    // .inout_none() for PositionSP tells the scheduler that while we
30    // want to match entities with PositionSP, we're not interested in reading or
31    // writing the component value.
32
33    world
34        .system_named::<()>("SetVelocitySP")
35        .with::<&PositionSP>()
36        .set_inout_none()
37        .write::<VelocitySP>() // VelocitySP is written, but shouldn't be matched
38        .each_entity(|e, ()| {
39            e.set(VelocitySP { x: 1.0, y: 2.0 });
40        });
41
42    // This system reads VelocitySP, which causes the insertion of a sync point.
43    world
44        .system_named::<(&mut PositionSP, &VelocitySP)>("Move")
45        .each(|(p, v)| {
46            p.x += v.x;
47            p.y += v.y;
48        });
49
50    // Print resulting PositionSP
51    world
52        .system_named::<&PositionSP>("PrintPositionSP")
53        .each_entity(|e, p| {
54            println!("{}: {{ {}, {} }}", e.name(), p.x, p.y);
55        });
56
57    // Create a few test entities for a PositionSP, VelocitySP query
58    world
59        .entity_named("e1")
60        .set(PositionSP { x: 10.0, y: 20.0 })
61        .set(VelocitySP { x: 1.0, y: 2.0 });
62
63    world
64        .entity_named("e2")
65        .set(PositionSP { x: 10.0, y: 20.0 })
66        .set(VelocitySP { x: 3.0, y: 4.0 });
67
68    // Run systems. Debug logging enables us to see the generated schedule.
69    // NOTE flecs C / flecs_ecs_sys needs to be build in debug mode to see the logging.
70    // use the feature flag "sys_build_debug" to enable debug build of flecs C.
71    set_log_level(1);
72    world.progress();
73    set_log_level(-1);
74
75    // Output:
76    // info: pipeline rebuild
77    // info: | schedule: threading: 0, staging: 1:
78    // info: | | system SetVelocitySP
79    // info: | | merge
80    // info: | schedule: threading: 0, staging: 1:
81    // info: | | system Move
82    // info: | | system PrintPositionSP
83    // info: | | merge
84    // e1: { 11, 22 }
85    // e2: { 11, 22 }
86
87    // The "merge" lines indicate sync points.
88    //
89    // Removing `.write::<VelocitySP>()` from the system will remove the first
90    // sync point from the schedule.
91}
examples/flecs/systems/system_sync_point_delete.rs (line 35)
17fn main() {
18    let world = World::new();
19
20    // This example shows how to annotate systems that delete entities, in a way
21    // that allows the scheduler to correctly insert sync points. See the
22    // sync_point example for more details on sync points.
23    //
24    // While annotating a system for a delete operation follows the same
25    // design as other operations, one key difference is that a system often
26    // does not know which components a to be deleted entity has. This makes it
27    // impossible to annotate the system in advance for specific components.
28    //
29    // To ensure the scheduler is still able to insert the correct sync points,
30    // a system can use a wildcard to indicate that any component could be
31    // modified by the system, which forces the scheduler to insert a sync.
32
33    // Basic move system.
34    world
35        .system_named::<(&mut Position, &Velocity)>("Move")
36        .each(|(p, v)| {
37            p.x += v.x;
38            p.y += v.y;
39        });
40
41    // Delete entities when p.x >= 3. Add wildcard annotation to indicate any
42    // component could be written by the system. Position itself is added as
43    // const, since inside the system we're only reading it.
44    world
45        .system_named::<&Position>("DeleteEntity")
46        .write::<flecs::Wildcard>()
47        .each_entity(|e, p| {
48            if p.x >= 3.0 {
49                println!("Delete entity {}", e.name());
50                e.destruct();
51            }
52        });
53
54    // Print resulting Position. Note that this system will never print entities
55    // that have been deleted by the previous system.
56    world
57        .system_named::<&Position>("PrintPosition")
58        .each_entity(|e, p| {
59            println!("{}: {{ {}, {} }}", e.name(), p.x, p.y);
60        });
61
62    // Create a few test entities for a Position, Velocity query
63    world
64        .entity_named("e1")
65        .set(Position { x: 0.0, y: 0.0 })
66        .set(Velocity { x: 1.0, y: 2.0 });
67
68    world
69        .entity_named("e2")
70        .set(Position { x: 1.0, y: 2.0 })
71        .set(Velocity { x: 1.0, y: 2.0 });
72
73    // Run systems. Debug logging enables us to see the generated schedule.
74    // NOTE flecs C / flecs_ecs_sys needs to be build in debug mode to see the logging.
75    // use the feature flag "sys_build_debug" to enable debug build of flecs C.
76
77    set_log_level(1);
78
79    while world.progress() {
80        if world.count::<Position>() == 0 {
81            break; // No more entities left with Position
82        }
83    }
84    set_log_level(-1);
85
86    // world
87    //     .get::<Snap>()
88    //     .test("system_sync_point_delete".to_string()));
89
90    // Output:
91    //  info: pipeline rebuild
92    //  info: | schedule: threading: 0, staging: 1:
93    //  info: | | system Move
94    //  info: | | system DeleteEntity
95    //  info: | | merge
96    //  info: | schedule: threading: 0, staging: 1:
97    //  info: | | system PrintPosition
98    //  info: | | merge
99    //  e1: { 1, 2 }
100    //  e2: { 2, 4 }
101    //  Delete entity e2
102    //  e1: { 2, 4 }
103    //  Delete entity e1
104
105    // Removing the wildcard annotation from the DeleteEntity system will
106    // remove the first sync point.
107
108    // Note how after both entities are deleted, all three systems will be de-activated and not ran by the scheduler
109}
Source

pub fn system_builder_from_desc<Components>( &self, desc: ecs_system_desc_t, ) -> SystemBuilder<'_, Components>
where Components: QueryTuple,

Available on crate feature flecs_system only.

Creates a SystemBuilder from a system description.

This function allows creating a system based on a predefined system description, facilitating more dynamic or configuration-driven system creation.

§Arguments
  • desc - A system description that outlines the parameters for the system builder.
§Type Parameters
  • Components: The components to match on. Must implement the QueryTuple trait.
§See also
  • C++ API: world::system_builder
Source

pub fn pipeline(&self) -> PipelineBuilder<'_, ()>

Available on crate feature flecs_pipeline only.

Create a new Pipeline.

§See also
Examples found in repository?
examples/flecs/systems/system_custom_pipeline.rs (line 22)
15fn main() {
16    let world = World::new();
17
18    // Create a pipeline that matches systems with Physics. Note that this
19    // pipeline does not require the use of phases (see custom_phases) or of the
20    // DependsOn relationship.
21    let pipeline = world
22        .pipeline()
23        .with_id(flecs::system::System::ID)
24        .with::<&Physics>()
25        .build();
26
27    // Configure the world to use the custom pipeline
28    world.set_pipeline_id(pipeline.entity());
29
30    // Create system with Physics tag
31    world.system::<()>().kind::<Physics>().run(|mut it| {
32        while it.next() {
33            println!("System with Physics ran!");
34        }
35    });
36
37    // Create system without Physics tag
38    world.system::<()>().run(|mut it| {
39        while it.next() {
40            println!("System without Physics ran!");
41        }
42    });
43
44    // Runs the pipeline & system
45    world.progress();
46
47    // Output:
48    //   System with Physics ran!
49}
Source

pub fn pipeline_named<'a>(&'a self, name: &str) -> PipelineBuilder<'a, ()>

Available on crate feature flecs_pipeline only.

Create a new named Pipeline.

§Arguments
  • name - The name of the pipeline.
§See also
Source

pub fn pipeline_type<Pipeline>(&self) -> PipelineBuilder<'_, ()>
where Pipeline: ComponentType<Struct> + ComponentId,

Available on crate feature flecs_pipeline only.

Create a new Pipeline with the provided associated type.

§Type Parameters
  • Pipeline - The associated type to use for the pipeline.
§See also
Source

pub fn set_pipeline_id(&self, pipeline: impl Into<Entity>)

Available on crate feature flecs_pipeline only.

Set a custom pipeline. This operation sets the pipeline to run when World::progress() is invoked.

§Arguments
  • pipeline - The pipeline to set.
§See also
Examples found in repository?
examples/flecs/systems/system_custom_pipeline.rs (line 28)
15fn main() {
16    let world = World::new();
17
18    // Create a pipeline that matches systems with Physics. Note that this
19    // pipeline does not require the use of phases (see custom_phases) or of the
20    // DependsOn relationship.
21    let pipeline = world
22        .pipeline()
23        .with_id(flecs::system::System::ID)
24        .with::<&Physics>()
25        .build();
26
27    // Configure the world to use the custom pipeline
28    world.set_pipeline_id(pipeline.entity());
29
30    // Create system with Physics tag
31    world.system::<()>().kind::<Physics>().run(|mut it| {
32        while it.next() {
33            println!("System with Physics ran!");
34        }
35    });
36
37    // Create system without Physics tag
38    world.system::<()>().run(|mut it| {
39        while it.next() {
40            println!("System without Physics ran!");
41        }
42    });
43
44    // Runs the pipeline & system
45    world.progress();
46
47    // Output:
48    //   System with Physics ran!
49}
Source

pub fn set_pipeline<Pipeline>(&self)
where Pipeline: ComponentType<Struct> + ComponentId,

Available on crate feature flecs_pipeline only.

Set a custom pipeline by type. This operation sets the pipeline to run when World::progress() is invoked.

§Type Parameters
  • Pipeline - The associated type to use for the pipeline.
§See also
Source

pub fn get_pipeline(&self) -> EntityView<'_>

Available on crate feature flecs_pipeline only.

Get the current pipeline.

§Returns

The current pipeline as an entity.

§See also
Source

pub fn progress(&self) -> bool

Available on crate feature flecs_pipeline only.

Progress world one tick.

Progresses the world by running all enabled and periodic systems on their matching entities.

This is a wrapper around World::progress_time(). It passes 0.0 as the delta_time to automatically measure the time passed since the last frame. This mode is useful for applications that do not manage time explicitly and want the system to measure the time automatically.

§Returns

True if the world has been progressed, false if World::quit() has been called.

§See also
Examples found in repository?
examples/flecs/systems/system_startup_system.rs (line 34)
13fn main() {
14    let world = World::new();
15
16    // Startup system
17    world
18        .system_named::<()>("Startup")
19        .kind::<flecs::pipeline::OnStart>()
20        .run(|mut it| {
21            while it.next() {
22                println!("{}", it.system().name());
23            }
24        });
25
26    // Regular system
27    world.system_named::<()>("Update").run(|mut it| {
28        while it.next() {
29            println!("{}", it.system().name());
30        }
31    });
32
33    // First frame. This runs both the Startup and Update systems
34    world.progress();
35
36    // Second frame. This runs only the Update system
37    world.progress();
38
39    // Output:
40    //  Startup
41    //  Update
42    //  Update
43}
More examples
Hide additional examples
examples/flecs/systems/system_time_interval.rs (line 35)
17fn main() {
18    let world = World::new();
19
20    world.set(Timeout { value: 3.5 });
21
22    world
23        .system::<&mut Timeout>()
24        .each_iter(|it, _index, timeout| {
25            timeout.value -= it.delta_time();
26        });
27
28    world.system_named::<()>("Tick").interval(1.0).run(tick);
29
30    world.system_named::<()>("FastTick").interval(0.5).run(tick);
31
32    // Run the main loop at 60 FPS
33    world.set_target_fps(60.0);
34
35    while world.progress() {
36        if world.map::<&Timeout, _>(|timeout| timeout.value <= 0.0) {
37            println!("Timed out!");
38            break;
39        }
40    }
41
42    // Output:
43    // FastTick
44    // Tick
45    // FastTick
46    // FastTick
47    // Tick
48    // FastTick
49    // FastTick
50    // Tick
51    // FastTick
52    // FastTick
53    // Timed out!
54}
examples/flecs/systems/system_custom_pipeline.rs (line 45)
15fn main() {
16    let world = World::new();
17
18    // Create a pipeline that matches systems with Physics. Note that this
19    // pipeline does not require the use of phases (see custom_phases) or of the
20    // DependsOn relationship.
21    let pipeline = world
22        .pipeline()
23        .with_id(flecs::system::System::ID)
24        .with::<&Physics>()
25        .build();
26
27    // Configure the world to use the custom pipeline
28    world.set_pipeline_id(pipeline.entity());
29
30    // Create system with Physics tag
31    world.system::<()>().kind::<Physics>().run(|mut it| {
32        while it.next() {
33            println!("System with Physics ran!");
34        }
35    });
36
37    // Create system without Physics tag
38    world.system::<()>().run(|mut it| {
39        while it.next() {
40            println!("System without Physics ran!");
41        }
42    });
43
44    // Runs the pipeline & system
45    world.progress();
46
47    // Output:
48    //   System with Physics ran!
49}
examples/flecs/systems/system_custom_phases_no_builtin.rs (line 51)
15fn main() {
16    let world = World::new();
17
18    // Create three custom phases. Note that the phases have the Phase tag,
19    // which is necessary for the builtin pipeline to discover which systems it
20    // should run.
21
22    let update = world.entity().add::<flecs::pipeline::Phase>();
23
24    let physics = world
25        .entity()
26        .add::<flecs::pipeline::Phase>()
27        .depends_on_id(update);
28
29    let collisions = world
30        .entity()
31        .add::<flecs::pipeline::Phase>()
32        .depends_on_id(physics);
33
34    // Create 3 dummy systems.
35    world
36        .system_named::<()>("CollisionSystem")
37        .kind_id(collisions)
38        .run(sys);
39
40    world
41        .system_named::<()>("PhysicsSystem")
42        .kind_id(physics)
43        .run(sys);
44
45    world
46        .system_named::<()>("GameSystem")
47        .kind_id(update)
48        .run(sys);
49
50    // Run pipeline
51    world.progress();
52
53    // Output:
54    //   system GameSystem
55    //   system PhysicsSystem
56    //   system CollisionSystem
57}
examples/flecs/systems/system_custom_phases.rs (line 48)
15fn main() {
16    let world = World::new();
17
18    // Create two custom phases that branch off of EcsOnUpdate. Note that the
19    // phases have the Phase tag, which is necessary for the builtin pipeline
20    // to discover which systems it should run.
21    let physics = world
22        .entity()
23        .add::<flecs::pipeline::Phase>()
24        .depends_on::<flecs::pipeline::OnUpdate>();
25
26    let collisions = world
27        .entity()
28        .add::<flecs::pipeline::Phase>()
29        .depends_on_id(physics);
30
31    // Create 3 dummy systems.
32    world
33        .system_named::<()>("CollisionSystem")
34        .kind_id(collisions)
35        .run(sys);
36
37    world
38        .system_named::<()>("PhysicsSystem")
39        .kind_id(physics)
40        .run(sys);
41
42    world
43        .system_named::<()>("GameSystem")
44        .kind::<flecs::pipeline::OnUpdate>()
45        .run(sys);
46
47    // Run pipeline
48    world.progress();
49
50    // Output:
51    //   system GameSystem
52    //   system PhysicsSystem
53    //   system CollisionSystem
54}
examples/flecs/systems/system_delta_time.rs (line 20)
5fn main() {
6    let world = World::new();
7
8    // Create system that prints delta_time. This system doesn't query for any
9    // components which means it won't match any entities, but will still be ran
10    // once for each call to ecs_progress.
11    world.system::<()>().run(|mut it| {
12        while it.next() {
13            println!("delta_time: {}", it.delta_time());
14        }
15    });
16
17    // Call progress with 0.0f for the delta_time parameter. This will cause
18    // ecs_progress to measure the time passed since the last frame. The
19    // delta_time of the first frame is a best guess (16ms).
20    world.progress();
21
22    // The following calls should print a delta_time of approximately 100ms
23
24    let os_sleep = unsafe { flecs_ecs_sys::ecs_os_api.sleep_ }.unwrap();
25
26    unsafe { os_sleep(0, 100 * 1000 * 1000) };
27    world.progress();
28
29    unsafe { os_sleep(0, 100 * 1000 * 1000) };
30
31    world.progress();
32
33    // Output:
34    //  delta_time: 0.016666668
35    //  delta_time: 0.10155179
36    //  delta_time: 0.10091246
37}
Source

pub fn progress_time(&self, delta_time: f32) -> bool

Available on crate feature flecs_pipeline only.

Progress world by delta time.

Progresses the world by running all enabled and periodic systems on their matching entities for the specified time since the last frame.

When delta_time is 0, World::progress_time() will automatically measure the time passed since the last frame. For applications not using time management, passing a non-zero delta_time (1.0 recommended) skips automatic time measurement to avoid overhead.

§Arguments
  • delta_time - The time to progress the world by. Pass 0.0 for automatic time measurement.
§Returns

True if the world has been progressed, false if World::quit() has been called.

§See also
Source

pub fn run_pipeline_id(&self, pipeline: impl Into<Entity>)

Available on crate feature flecs_pipeline only.

Run pipeline. Runs all systems in the specified pipeline. Can be invoked from multiple threads if staging is disabled, managing staging and, if needed, thread synchronization.

Providing 0 for pipeline id runs the default pipeline (builtin or set via set_pipeline_id()). Using World::progress() auto-invokes this for the default pipeline. Additional pipelines may be run explicitly.

§Note

Only supports single-threaded applications with a single stage when called from an application.

§Arguments
  • pipeline - Pipeline to run.
§See also
Source

pub fn run_pipeline_id_time( &self, pipeline: impl Into<Entity>, delta_time: FTime, )

Available on crate feature flecs_pipeline only.

Run pipeline. Runs all systems in the specified pipeline. Can be invoked from multiple threads if staging is disabled, managing staging and, if needed, thread synchronization.

Providing 0 for pipeline id runs the default pipeline (builtin or set via set_pipeline_id()). Using World::progress() auto-invokes this for the default pipeline. Additional pipelines may be run explicitly.

§Note

Only supports single-threaded applications with a single stage when called from an application.

§Arguments
  • pipeline - Pipeline to run.
  • delta_time - Time to advance the world.
§See also
Source

pub fn run_pipeline_time<Component>(&self, delta_time: FTime)
where Component: ComponentType<Struct> + ComponentId,

Available on crate feature flecs_pipeline only.

Run pipeline. Runs all systems in the specified pipeline. Can be invoked from multiple threads if staging is disabled, managing staging and, if needed, thread synchronization.

Using World::progress() auto-invokes this for the default pipeline. Additional pipelines may be run explicitly.

§Note

Only supports single-threaded applications with a single stage when called from an application.

§Type Parameters
  • Component - The associated type to use for the pipeline.
§Arguments
  • delta_time - Time to advance the world.
§See also
Source

pub fn run_pipeline<Component>(&self)
where Component: ComponentType<Struct> + ComponentId,

Available on crate feature flecs_pipeline only.

Run pipeline. Runs all systems in the specified pipeline. Can be invoked from multiple threads if staging is disabled, managing staging and, if needed, thread synchronization.

Using World::progress() auto-invokes this for the default pipeline. Additional pipelines may be run explicitly.

§Note

Only supports single-threaded applications with a single stage when called from an application.

§Type Parameters
  • Component - The associated type to use for the pipeline.
§See also
Source

pub fn set_time_scale(&self, mul: FTime)

Available on crate feature flecs_pipeline only.

Set time scale. Increase or decrease simulation speed by the provided multiplier.

§Arguments
  • mul - The multiplier to set the time scale to.
§See also
  • C++ API: world::set_time_scale
Source

pub fn get_time_scale(&self) -> FTime

Available on crate feature flecs_pipeline only.

Get time scale.

Retrieves the current time scale of the world, which affects the speed at which time passes within the simulation. A time scale of 1.0 means real-time, values greater than 1.0 speed up the simulation, and values less than 1.0 slow it down.

§Returns

The current time scale as a floating point number.

§See also
  • C++ API: world::get_time_scale
Source

pub fn get_target_fps(&self) -> FTime

Available on crate feature flecs_pipeline only.

Get target frames per second (FPS).

Retrieves the target FPS for the world. This value is used to calculate the time step for each simulation tick when the automatic time step is enabled. Adjusting the target FPS can be used to control simulation speed.

§Returns

The target FPS as a floating point number.

§See also
  • C++ API: world::get_target_fps
Source

pub fn set_target_fps(&self, target_fps: FTime)

Available on crate feature flecs_pipeline only.

Set target frames per second (FPS).

Configures the world to run at the specified target FPS, ensuring that World::progress() is not called more frequently than this rate. This mechanism enables tracking the elapsed time since the last World::progress() call and sleeping for any remaining time in the frame, if applicable.

Utilizing this feature promotes consistent system execution intervals and conserves CPU resources by avoiding more frequent system runs than necessary.

It’s important to note that World::progress() will only introduce sleep periods when there is surplus time within a frame. This accounts for time consumed both within Flecs and in external operations.

§Arguments
  • world - The world context.
  • fps - The desired target FPS as a floating-point number.
§See also
  • C++ API: world::set_target_fps
Examples found in repository?
examples/flecs/systems/system_time_interval.rs (line 33)
17fn main() {
18    let world = World::new();
19
20    world.set(Timeout { value: 3.5 });
21
22    world
23        .system::<&mut Timeout>()
24        .each_iter(|it, _index, timeout| {
25            timeout.value -= it.delta_time();
26        });
27
28    world.system_named::<()>("Tick").interval(1.0).run(tick);
29
30    world.system_named::<()>("FastTick").interval(0.5).run(tick);
31
32    // Run the main loop at 60 FPS
33    world.set_target_fps(60.0);
34
35    while world.progress() {
36        if world.map::<&Timeout, _>(|timeout| timeout.value <= 0.0) {
37            println!("Timed out!");
38            break;
39        }
40    }
41
42    // Output:
43    // FastTick
44    // Tick
45    // FastTick
46    // FastTick
47    // Tick
48    // FastTick
49    // FastTick
50    // Tick
51    // FastTick
52    // FastTick
53    // Timed out!
54}
More examples
Hide additional examples
examples/flecs/systems/system_target_fps.rs (line 18)
5fn main() {
6    let world = World::new();
7
8    // Create system that prints delta_time. This system doesn't query for any
9    // components which means it won't match any entities, but will still be ran
10    // once for each call to ecs_progress.
11    world.system::<()>().run(|mut it| {
12        while it.next() {
13            println!("Delta time: {}", it.delta_time());
14        }
15    });
16
17    // Set target FPS to 1 frame per second
18    world.set_target_fps(1.0);
19
20    // Run 3 frames
21    for _ in 0..3 {
22        // To make sure the frame doesn't run faster than the specified target
23        // FPS ecs_progress will insert a sleep if the measured delta_time is
24        // smaller than 1 / target_fps.
25        //
26        // By default ecs_progress uses the sleep function provided by the OS
27        // which is not always very accurate. If more accuracy is required the
28        // sleep function of the OS API can be overridden with a custom one.
29        //
30        // If a value other than 0 is provided to the delta_time argument of
31        // ecs_progress, this value will be used to calculate the length of
32        // the sleep to insert.
33        world.progress();
34    }
35
36    // Output:
37    //  Delta time: 1
38    //  Delta time: 1.0182016
39    //  Delta time: 1.0170991
40}
examples/flecs/systems/system_mutate_entity.rs (line 53)
10fn main() {
11    let world = World::new();
12
13    // System that deletes an entity after a timeout expires
14    world
15        .system::<&mut Timeout>()
16        .each_iter(|it, index, timeout| {
17            timeout.value -= it.delta_time();
18            if timeout.value <= 0.0 {
19                // Delete the entity
20
21                // To make sure that the storage doesn't change while a system
22                // is iterating entities, and multiple threads can safely access
23                // the data, mutations (like a delete) are added to a command
24                // queue and executed when it's safe to do so.
25
26                // When the entity to be mutated is not the same as the entity
27                // provided by the system, an additional mut() call is required.
28                // See the mutate_entity_handle example.
29                let e = it.entity(index);
30                e.destruct();
31                println!("Expire: {} deleted!", e.name());
32            }
33        });
34
35    // System that prints remaining expiry time
36    world.system::<&Timeout>().each_entity(|e, timeout| {
37        println!(
38            "PrintExpire: {} has {:.2} seconds left",
39            e.name(),
40            timeout.value
41        );
42    });
43
44    // Observer that triggers when entity is actually deleted
45    world
46        .observer::<flecs::OnRemove, &Timeout>()
47        .each_entity(|e, _timeout| {
48            println!("Expired: {} actually deleted", e.name());
49        });
50
51    let e = world.entity_named("MyEntity").set(Timeout { value: 2.5 });
52
53    world.set_target_fps(1.0);
54
55    while world.progress() {
56        // If entity is no longer alive, exit
57        if !e.is_alive() {
58            break;
59        }
60
61        println!("Tick...");
62    }
63
64    // Output:
65    //  PrintExpire: MyEntity has 2.00 seconds left
66    //  Tick...
67    //  PrintExpire: MyEntity has 0.99 seconds left
68    //  Tick...
69    //  Expire: MyEntity deleted!
70    //  PrintExpire: MyEntity has -0.03 seconds left
71    //  Expired: MyEntity actually deleted
72}
examples/flecs/systems/system_mutate_entity_handle.rs (line 79)
16fn main() {
17    let world = World::new();
18
19    // System that deletes an entity after a timeout expires
20    world
21        .system::<&mut Timeout>()
22        .each_iter(|it, _index, timeout| {
23            timeout.value -= it.delta_time();
24            if timeout.value <= 0.0 {
25                // Delete the entity
26
27                // To make sure the delete operation is enqueued (see
28                // mutate_entity example for more details) we need to provide it
29                // with a mutable context (stage) using the mut() function. If
30                // we don't provide a mutable context, the operation will be
31                // attempted on the context stored in the flecs::entity object,
32                // which would throw a readonly error.
33
34                // To catch these errors at compile time, replace the type of
35                // to_delete with flecs::entity_view. This class does not have
36                // any methods for mutating the entity, which forces the code to
37                // first call mut().
38
39                // The it.world() function can be used to provide the context:
40                //   t.to_delete.mut(it.world()).destruct();
41                //
42                // The current entity can also be used to provide context. This
43                // is useful for functions that accept a flecs::entity:
44                //   t.to_delete.mut(it.entity(index)).destruct();
45                //
46                // A shortcut is to use the iterator directly:
47                let world = it.world();
48                let to_delete = world.get_alive(timeout.to_delete);
49                println!("Expire: {} deleted!", to_delete.name());
50                to_delete.destruct();
51            }
52        });
53
54    // System that prints remaining expiry time
55    world.system::<&Timeout>().each_entity(|e, timeout| {
56        let world = e.world();
57        let to_delete = world.get_alive(timeout.to_delete);
58        println!(
59            "PrintExpire: {} has {:.2} seconds left",
60            to_delete.name(),
61            timeout.value
62        );
63    });
64
65    // Observer that triggers when entity is actually deleted
66    world
67        .observer::<flecs::OnRemove, &Tag>()
68        .each_entity(|e, _tag| {
69            println!("Expired: {} actually deleted", e.name());
70        });
71
72    let to_delete = world.entity_named("ToDelete").add::<Tag>();
73
74    world.entity_named("MyEntity").set(Timeout {
75        to_delete: to_delete.id(),
76        value: 2.5,
77    });
78
79    world.set_target_fps(1.0);
80
81    while world.progress() {
82        // If entity is no longer alive, exit
83        if !to_delete.is_alive() {
84            break;
85        }
86
87        println!("Tick...");
88    }
89
90    // Output:
91    //  PrintExpire: ToDelete has 2.00 seconds left
92    //  Tick...
93    //  PrintExpire: ToDelete has 0.98 seconds left
94    //  Tick...
95    //  Expire: ToDelete deleted!
96    //  PrintExpire: ToDelete has -0.03 seconds left
97    //  Expired: ToDelete actually deleted
98}
Source

pub fn reset_clock(&self)

Available on crate feature flecs_pipeline only.

Reset world clock. Reset the clock that keeps track of the total time passed in the simulation.

§See also
  • C++ API: world::reset_clock
Source

pub fn set_threads(&self, threads: i32)

Available on crate feature flecs_pipeline only.

Set number of worker threads.

Setting this value to a value higher than 1 will start as many threads and will cause systems to evenly distribute matched entities across threads. The operation may be called multiple times to reconfigure the number of threads used, but never while running a system / pipeline. Calling World::set_threads() will also end the use of task threads setup with World::set_task_threads() and vice-versa

§Arguments
  • threads - The number of threads to use.
§See also
Source

pub fn get_threads(&self) -> i32

Available on crate feature flecs_pipeline only.

Get number of configured stages. Return number of stages set by World::set_stage_count().

§Returns

The number of stages as an integer.

§See also
Source

pub fn set_task_threads(&self, task_threads: i32)

Available on crate feature flecs_pipeline only.

Set number of worker task threads.

Configures the world to use a specified number of short-lived task threads, distinct from World::set_threads() where threads persist. Here, threads are created and joined for each world update, leveraging the os_api_t tasks APIs for task management instead of traditional thread APIs. This approach is advantageous for integrating with external asynchronous job systems, allowing for the dynamic creation and synchronization of tasks specific to each world update.

This function can be invoked multiple times to adjust the count of task threads, but must not be called concurrently with system or pipeline execution. Switching to World::set_task_threads() from World::set_threads() (or vice versa) will terminate the use of the previously configured threading model.

§Arguments
  • task_threads - The number of task threads to use.
§See also
Source

pub fn using_task_threads(&self) -> bool

Available on crate feature flecs_pipeline only.

Returns true if task thread use have been requested.

§Returns

True if task threads are being used, false otherwise.

§See also
Source

pub fn delete_empty_tables( &self, id: impl Into<Id>, clear_generation: u16, delete_generation: u16, min_id_count: i32, time_budget_seconds: f64, ) -> i32

Available on crate feature flecs_pipeline only.

Delete empty tables within the world

§See also
  • C API: ecs_delete_empty_tables
Source

pub fn app(&self) -> App<'_>

Available on crate feature flecs_app only.

Create a new app. The app builder is a convenience wrapper around a loop that runs World::progress(). An app allows for writing platform agnostic code, as it provides hooks to modules for overtaking the main loop which is required for frameworks like emscripten.

§See also
Source

pub fn set_doc_name<T: ComponentId>(&self, name: &str)

Available on crate feature flecs_doc only.

Add human-readable name to entity.

Contrary to entity names, human readable names do not have to be unique and can contain special characters used in the query language like ‘*’.

§Type Parameters
  • T - The type that implements ComponentId.
§Arguments
  • name - The name to add.
§See also
Source

pub fn set_doc_name_id(&self, entity: impl Into<Entity>, name: &str)

Available on crate feature flecs_doc only.

Add human-readable name to entity.

Contrary to entity names, human readable names do not have to be unique and can contain special characters used in the query language like ‘*’.

§Arguments
  • entity - The entity to which to add the name.
  • name - The name to add.
§See also
Source

pub fn set_doc_brief<T: ComponentId>(&self, brief: &str)

Available on crate feature flecs_doc only.

Add brief description to entity.

§Type Parameters
  • T - The type that implements ComponentId.
§Arguments
  • brief - The brief description to add.
§See also
Source

pub fn set_doc_brief_id(&self, entity: impl Into<Entity>, brief: &str)

Available on crate feature flecs_doc only.

Add brief description to entity.

§Arguments
  • entity - The entity to which to add the brief description.
  • brief - The brief description to add.
§See also
Source

pub fn set_doc_detail<T: ComponentId>(&self, detail: &str)

Available on crate feature flecs_doc only.

Add detailed description to entity.

§Type Parameters
  • T - The type that implements ComponentId.
§Arguments
  • detail - The detailed description to add.
§See also
Source

pub fn set_doc_detail_id(&self, entity: impl Into<Entity>, detail: &str)

Available on crate feature flecs_doc only.

Add detailed description to entity.

§Arguments
  • entity - The entity to which to add the detailed description.
  • detail - The detailed description to add.
§See also
Available on crate feature flecs_doc only.

Add link to external documentation to entity.

§Type Parameters
  • T - The type that implements ComponentId.
§Arguments
  • link - The link to add.
§See also
Available on crate feature flecs_doc only.

Add link to external documentation to entity.

§Arguments
  • entity - The entity to which to add the link.
  • link - The link to add.
§See also
Source

pub fn set_doc_color<T: ComponentId>(&self, color: &str)

Available on crate feature flecs_doc only.

Add color to entity.

UIs can use color as hint to improve visualizing entities.

§Type Parameters
  • T - The type that implements ComponentId.
§Arguments
  • color - The color to add.
§See also
Source

pub fn set_doc_color_id(&self, entity: impl Into<Entity>, color: &str)

Available on crate feature flecs_doc only.

Add color to entity.

UIs can use color as hint to improve visualizing entities.

§Arguments
  • entity - The entity to which to add the color.
  • color - The color to add.
§See also
Source

pub fn import<T: Module>(&self) -> EntityView<'_>

Available on crate feature flecs_module only.

Import a module.

This operation will load a module. The module name will be used to verify if the module was already loaded, in which case it won’t be reimported.

Module contents will be stored as children of the module entity. This prevents modules from accidentally defining conflicting identifiers. This is enforced by setting the scope before and after loading the module to the module entity id.

world.import::<MyModule>();
§See also
Source

pub fn module<M: ComponentId>(&self, name: &str) -> EntityView<'_>

Available on crate feature flecs_module only.

Define a module.

This operation is not mandatory, but can be called inside the module ctor to obtain the entity associated with the module, or override the module name.

§Type Parameters
  • M - The type of the module.
§Arguments
  • name - The name to give the module.
§Returns

The module entity.

§See also
Source

pub fn timer(&self) -> Timer<'_>

Available on crate feature flecs_timer only.

Find or register a singleton Timer

§See also
  • C++ API: world::timer
Source

pub fn timer_from<T: ComponentId>(&self) -> Timer<'_>

Available on crate feature flecs_timer only.

Find or register a Timer

§See also
  • C++ API: world::timer
Source

pub fn randomize_timers(&self)

Available on crate feature flecs_timer only.

Enable randomizing initial time value of timers. Initializes timers with a random time value, which can improve scheduling as systems/timers for the same interval don’t all happen on the same tick.

§See also
  • C++ API: world::randomize_timers

Trait Implementations§

Source§

impl<'a> Clone for WorldRef<'a>

Source§

fn clone(&self) -> WorldRef<'a>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> Debug for WorldRef<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a> Deref for WorldRef<'a>

Source§

type Target = World

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl<'a> From<&'a World> for WorldRef<'a>

Source§

fn from(world: &'a World) -> Self

Converts to this type from the input type.
Source§

impl<'a> PartialEq for WorldRef<'a>

Source§

fn eq(&self, other: &WorldRef<'a>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<'a> WorldProvider<'a> for &WorldRef<'a>

Source§

fn world(&self) -> WorldRef<'a>

Source§

impl<'a> WorldProvider<'a> for WorldRef<'a>

Source§

fn world(&self) -> WorldRef<'a>

Source§

impl<'a> Copy for WorldRef<'a>

Source§

impl<'a> Eq for WorldRef<'a>

Source§

impl<'a> Send for WorldRef<'a>

Source§

impl<'a> StructuralPartialEq for WorldRef<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for WorldRef<'a>

§

impl<'a> RefUnwindSafe for WorldRef<'a>

§

impl<'a> !Sync for WorldRef<'a>

§

impl<'a> Unpin for WorldRef<'a>

§

impl<'a> UnwindSafe for WorldRef<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DoesNotImpl for T

Source§

const IMPLS: bool = false

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.