Skip to main content

World

Struct World 

Source
pub struct World {
Show 16 fields id: WorldId, pub(crate) entities: Entities, pub(crate) entity_allocator: EntityAllocator, pub(crate) components: Components, pub(crate) component_ids: ComponentIds, pub(crate) resource_entities: ResourceEntities, pub(crate) archetypes: Archetypes, pub(crate) storages: Storages, pub(crate) bundles: Bundles, pub(crate) observers: Observers, pub(crate) removed_components: RemovedComponentMessages, pub(crate) change_tick: Atomic<u32>, pub(crate) last_change_tick: Tick, pub(crate) last_check_tick: Tick, pub(crate) last_trigger_id: u32, pub(crate) command_queue: RawCommandQueue,
}
Expand description

Stores and exposes operations on entities, components, resources, and their associated metadata.

Each Entity has a set of unique components, based on their type. Entity components can be created, updated, removed, and queried using a given World.

For complex access patterns involving SystemParam, consider using SystemState.

To mutate different parts of the world simultaneously, use World::resource_scope or SystemState.

§Resources

Worlds can also store Resources, which are unique instances of a given type that belong to a specific unique Entity. There are also non send resources, which can only be accessed on the main thread. These are stored outside of the ECS. See Resource for usage.

Fields§

§id: WorldId§entities: Entities§entity_allocator: EntityAllocator§components: Components§component_ids: ComponentIds§resource_entities: ResourceEntities§archetypes: Archetypes§storages: Storages§bundles: Bundles§observers: Observers§removed_components: RemovedComponentMessages§change_tick: Atomic<u32>§last_change_tick: Tick§last_check_tick: Tick§last_trigger_id: u32§command_queue: RawCommandQueue

Implementations§

Source§

impl World

Source

pub fn register_event_key<E>(&mut self) -> EventKey
where E: Event,

Generates the EventKey for this event type.

If this type has already been registered, this will return the existing EventKey.

This is used by various dynamically typed observer APIs, such as DeferredWorld::trigger_raw.

Source

pub fn event_key<E>(&self) -> Option<EventKey>
where E: Event,

Fetches the EventKey for this event type, if it has already been generated.

This is used by various dynamically typed observer APIs, such as DeferredWorld::trigger_raw.

Source§

impl World

Source

pub fn add_observer<M>( &mut self, observer: impl IntoObserver<M>, ) -> EntityWorldMut<'_>

Spawns a “global” Observer which will watch for the given event. Returns its Entity as a EntityWorldMut.

system can be any system whose first parameter is On.

§Example
#[derive(Component)]
struct A;

world.add_observer(|_: On<Add, A>| {
    // ...
});
world.add_observer(|_: On<Remove, A>| {
    // ...
});

Calling observe on the returned EntityWorldMut will observe the observer itself, which you very likely do not want.

§Panics

Panics if the given system is an exclusive system.

Source

pub fn trigger<'a, E>(&mut self, event: E)
where E: Event, <E as Event>::Trigger<'a>: Default,

Triggers the given Event, which will run any Observers watching for it.

For a variant that borrows the event rather than consuming it, use World::trigger_ref instead.

Source

pub fn trigger_with<'a, E>( &mut self, event: E, trigger: <E as Event>::Trigger<'a>, )
where E: Event,

Triggers the given Event using the given Trigger, which will run any Observers watching for it.

For a variant that borrows the event rather than consuming it, use World::trigger_ref instead.

Source

pub fn trigger_ref<'a, E>(&mut self, event: &mut E)
where E: Event, <E as Event>::Trigger<'a>: Default,

Triggers the given mutable Event reference, which will run any Observers watching for it.

Compared to World::trigger, this method is most useful when it’s necessary to check or use the event after it has been modified by observers.

Source

pub fn trigger_ref_with<'a, E>( &mut self, event: &mut E, trigger: &mut <E as Event>::Trigger<'a>, )
where E: Event,

Triggers the given mutable Event reference using the given mutable Trigger reference, which will run any Observers watching for it.

Compared to World::trigger, this method is most useful when it’s necessary to check or use the event after it has been modified by observers.

Source

pub unsafe fn trigger_dynamic( &mut self, event_key: EventKey, event_data: PtrMut<'_>, trigger_data: PtrMut<'_>, )

Triggers global Observers for event_key with untyped event and trigger data.

Dynamic equivalent of World::trigger. Only fires global observers, not entity- or component-scoped ones.

Use World::trigger_dynamic_targets to also fire entity-scoped observers.

§Safety
  • event_data must point to a valid, aligned value whose layout matches what observers registered for this event_key expect.
  • trigger_data must point to a valid, aligned value whose layout matches what observers registered for this event_key expect.
Examples found in repository?
examples/ecs/dynamic.rs (lines 274-278)
69fn main() {
70    let mut world = World::new();
71    let mut lines = std::io::stdin().lines();
72    let mut component_names = HashMap::<String, ComponentId>::new();
73    let mut component_info = HashMap::<ComponentId, ComponentInfo>::new();
74    let mut event_names = HashMap::<String, EventKey>::new();
75
76    println!("{PROMPT}");
77    loop {
78        print!("\n> ");
79        let _ = std::io::stdout().flush();
80        let Some(Ok(line)) = lines.next() else {
81            return;
82        };
83
84        if line.is_empty() {
85            return;
86        };
87
88        let Some((first, rest)) = line.trim().split_once(|c: char| c.is_whitespace()) else {
89            match &line.chars().next() {
90                Some('c') => println!("{COMPONENT_PROMPT}"),
91                Some('s') => println!("{ENTITY_PROMPT}"),
92                Some('q') => println!("{QUERY_PROMPT}"),
93                Some('e') => println!("{EVENT_PROMPT}"),
94                Some('t') => println!("{EMIT_PROMPT}"),
95                _ => println!("{PROMPT}"),
96            }
97            continue;
98        };
99
100        match &first[0..1] {
101            "c" => {
102                rest.split(',').for_each(|component| {
103                    let mut component = component.split_whitespace();
104                    let Some(name) = component.next() else {
105                        return;
106                    };
107                    let size = match component.next().map(str::parse) {
108                        Some(Ok(size)) => size,
109                        _ => 0,
110                    };
111                    // Register our new component to the world with a layout specified by it's size
112                    // SAFETY: [u64] is Send + Sync
113                    let id = world.register_component_with_descriptor(unsafe {
114                        ComponentDescriptor::new_with_layout(
115                            name.to_string(),
116                            StorageType::Table,
117                            Layout::array::<u64>(size).unwrap(),
118                            None,
119                            true,
120                            ComponentCloneBehavior::Default,
121                            None,
122                        )
123                    });
124                    let Some(info) = world.components().get_info(id) else {
125                        return;
126                    };
127                    component_names.insert(name.to_string(), id);
128                    component_info.insert(id, info.clone());
129                    println!("Component {} created with id: {}", name, id.index());
130                });
131            }
132            "s" => {
133                let mut to_insert_ids = Vec::new();
134                let mut to_insert_data = Vec::new();
135                rest.split(',').for_each(|component| {
136                    let mut component = component.split_whitespace();
137                    let Some(name) = component.next() else {
138                        return;
139                    };
140
141                    // Get the id for the component with the given name
142                    let Some(&id) = component_names.get(name) else {
143                        println!("Component {name} does not exist");
144                        return;
145                    };
146
147                    // Calculate the length for the array based on the layout created for this component id
148                    let info = world.components().get_info(id).unwrap();
149                    let len = info.layout().size() / size_of::<u64>();
150                    let mut values: Vec<u64> = component
151                        .take(len)
152                        .filter_map(|value| value.parse::<u64>().ok())
153                        .collect();
154                    values.resize(len, 0);
155
156                    // Collect the id and array to be inserted onto our entity
157                    to_insert_ids.push(id);
158                    to_insert_data.push(values);
159                });
160
161                let mut entity = world.spawn_empty();
162
163                // Construct an `OwningPtr` for each component in `to_insert_data`
164                let to_insert_ptr = to_owning_ptrs(&mut to_insert_data);
165
166                // SAFETY:
167                // - Component ids have been taken from the same world
168                // - Each array is created to the layout specified in the world
169                unsafe {
170                    entity.insert_by_ids(&to_insert_ids, to_insert_ptr.into_iter());
171                }
172
173                println!("Entity spawned with id: {}", entity.id());
174            }
175            "q" => {
176                let mut builder = QueryBuilder::<FilteredEntityMut>::new(&mut world);
177                parse_query(rest, &mut builder, &component_names);
178                let mut query = builder.build();
179                query.iter_mut(&mut world).for_each(|filtered_entity| {
180                    let terms = filtered_entity
181                        .access()
182                        .try_iter_access()
183                        .unwrap()
184                        .map(|component_access| {
185                            let id = *component_access.index();
186                            let ptr = filtered_entity.get_by_id(id).unwrap();
187                            let info = component_info.get(&id).unwrap();
188                            let len = info.layout().size() / size_of::<u64>();
189
190                            // SAFETY:
191                            // - All components are created with layout [u64]
192                            // - len is calculated from the component descriptor
193                            let data = unsafe {
194                                std::slice::from_raw_parts_mut(
195                                    ptr.assert_unique().as_ptr().cast::<u64>(),
196                                    len,
197                                )
198                            };
199
200                            // If we have write access, increment each value once
201                            if matches!(component_access, ComponentAccessKind::Exclusive(_)) {
202                                data.iter_mut().for_each(|data| {
203                                    *data += 1;
204                                });
205                            }
206
207                            format!("{}: {:?}", info.name(), data[0..len].to_vec())
208                        })
209                        .collect::<Vec<_>>()
210                        .join(", ");
211
212                    println!("{}: {}", filtered_entity.id(), terms);
213                });
214            }
215            "e" => {
216                rest.split(',').for_each(|event| {
217                    let name = event.trim();
218                    if name.is_empty() {
219                        return;
220                    }
221
222                    // Register a ComponentId for this event, no Rust type needed.
223                    // SAFETY: ZST with no drop
224                    let event_component_id = world.register_component_with_descriptor(unsafe {
225                        ComponentDescriptor::new_with_layout(
226                            format!("event:{name}"),
227                            StorageType::Table,
228                            Layout::new::<()>(),
229                            None,
230                            false,
231                            ComponentCloneBehavior::Ignore,
232                            None,
233                        )
234                    });
235                    // SAFETY: event_component_id was just registered for this event
236                    let event_key = unsafe { EventKey::new(event_component_id) };
237                    event_names.insert(name.to_string(), event_key);
238
239                    // Build a dynamic observer that prints when the event fires.
240                    let runner: ObserverRunner = |mut world, _observer, ctx, _event, _trigger| {
241                        println!("  Observer fired!");
242                        if let Some(mut counts) = world.get_resource_mut::<EventFireCount>() {
243                            *counts.0.entry(ctx.event_key).or_insert(0) += 1;
244                        }
245                    };
246
247                    // SAFETY: event_key was just registered, runner ignores pointers
248                    let observer =
249                        unsafe { Observer::with_dynamic_runner(runner).with_event_key(event_key) };
250                    world.spawn(observer);
251
252                    println!(
253                        "Event '{name}' registered (key: {}) with a dynamic observer",
254                        event_component_id.index()
255                    );
256                });
257
258                // Ensure the counter resource exists.
259                world.init_resource::<EventFireCount>();
260            }
261            "t" => {
262                let name = rest.trim();
263                let Some(&event_key) = event_names.get(name) else {
264                    println!(
265                        "Event '{name}' does not exist. Register it first with 'event {name}'"
266                    );
267                    continue;
268                };
269
270                let mut event_data = ();
271                let mut trigger_data = ();
272                // SAFETY: event_key was registered in this world, both pointers are valid ZSTs
273                unsafe {
274                    world.trigger_dynamic(
275                        event_key,
276                        PtrMut::from(&mut event_data),
277                        PtrMut::from(&mut trigger_data),
278                    );
279                }
280
281                let count = world
282                    .get_resource::<EventFireCount>()
283                    .map_or(0, |c| c.0.get(&event_key).copied().unwrap_or(0));
284                println!("Event '{name}' triggered ({count} fires)");
285            }
286            _ => continue,
287        }
288    }
289}
Source

pub unsafe fn trigger_dynamic_targets( &mut self, event_key: EventKey, entity: Entity, event_data: PtrMut<'_>, trigger_data: PtrMut<'_>, )

Triggers Observers for event_key targeting entity, with untyped event and trigger data.

Fires global and entity-scoped observers. Dynamic equivalent of EntityWorldMut::trigger.

§Safety
  • event_data must point to a valid, aligned value whose layout matches what observers registered for this event_key expect.
  • trigger_data must point to a valid, aligned value whose layout matches what observers registered for this event_key expect.
Source

pub unsafe fn trigger_dynamic_targets_components( &mut self, event_key: EventKey, entity: Entity, components: &[ComponentId], event_data: PtrMut<'_>, trigger_data: PtrMut<'_>, )

Triggers Observers for event_key targeting entity and components, with untyped event and trigger data.

Fires global, entity-scoped, and component-scoped observers. Dynamic equivalent of EntityComponentsTrigger.

§Safety
  • event_data must point to a valid, aligned value whose layout matches what observers registered for this event_key expect.
  • trigger_data must point to a valid, aligned value whose layout matches what observers registered for this event_key expect.
Source§

impl World

Source

pub fn register_system<I, O, M>( &mut self, system: impl IntoSystem<I, O, M> + 'static, ) -> SystemId<I, O>
where I: SystemInput + 'static, O: 'static,

Registers a system and returns a SystemId so it can later be called by World::run_system.

It’s possible to register multiple copies of the same system by calling this function multiple times. If that’s not what you want, consider using World::register_system_cached instead.

This is different from adding systems to a Schedule, because the SystemId that is returned can be used anywhere in the World to run the associated system. This allows for running systems in a pushed-based fashion. Using a Schedule is still preferred for most cases due to its better performance and ability to run non-conflicting systems simultaneously.

Examples found in repository?
examples/ecs/one_shot_systems.rs (line 51)
47fn setup_with_world(world: &mut World) {
48    // We can run it once manually
49    world.run_system_once(system_b).unwrap();
50    // Or with a Callback
51    let system_id = world.register_system(system_b);
52    world.spawn((Callback(system_id), B));
53}
Source

pub fn register_boxed_system<I, O>( &mut self, system: Box<dyn System<In = I, Out = O>>, ) -> SystemId<I, O>
where I: SystemInput + 'static, O: 'static,

Similar to Self::register_system, but allows passing in a BoxedSystem.

This is useful if the IntoSystem implementor has already been turned into a System trait object and put in a Box.

Source

pub fn unregister_system<I, O>( &mut self, id: SystemId<I, O>, ) -> Result<RemovedSystem<I, O>, RegisteredSystemError<I, O>>
where I: SystemInput + 'static, O: 'static,

Removes a registered system and returns the system, if it exists. After removing a system, the SystemId becomes invalid and attempting to use it afterwards will result in errors. Re-adding the removed system will register it on a new SystemId.

If no system corresponds to the given SystemId, this method returns an error. Systems are also not allowed to remove themselves, this returns an error too.

Source

pub fn run_system<O>( &mut self, id: SystemId<(), O>, ) -> Result<O, RegisteredSystemError<(), O>>
where O: 'static,

Run stored systems by their SystemId. Before running a system, it must first be registered. The method World::register_system stores a given system and returns a SystemId. This is different from RunSystemOnce::run_system_once, because it keeps local state between calls and change detection works correctly.

Also runs any queued-up commands.

In order to run a chained system with an input, use World::run_system_with instead.

§Examples
§Running a system
fn increment(mut counter: Local<u8>) {
   *counter += 1;
   println!("{}", *counter);
}

let mut world = World::default();
let counter_one = world.register_system(increment);
let counter_two = world.register_system(increment);
world.run_system(counter_one); // -> 1
world.run_system(counter_one); // -> 2
world.run_system(counter_two); // -> 1
§Change detection
#[derive(Resource, Default)]
struct ChangeDetector;

let mut world = World::default();
world.init_resource::<ChangeDetector>();
let detector = world.register_system(|change_detector: ResMut<ChangeDetector>| {
    if change_detector.is_changed() {
        println!("Something happened!");
    } else {
        println!("Nothing happened.");
    }
});

// Resources are changed when they are first added
let _ = world.run_system(detector); // -> Something happened!
let _ = world.run_system(detector); // -> Nothing happened.
world.resource_mut::<ChangeDetector>().set_changed();
let _ = world.run_system(detector); // -> Something happened!
§Getting system output

#[derive(Resource)]
struct PlayerScore(i32);

#[derive(Resource)]
struct OpponentScore(i32);

fn get_player_score(player_score: Res<PlayerScore>) -> i32 {
  player_score.0
}

fn get_opponent_score(opponent_score: Res<OpponentScore>) -> i32 {
  opponent_score.0
}

let mut world = World::default();
world.insert_resource(PlayerScore(3));
world.insert_resource(OpponentScore(2));

let scoring_systems = [
  ("player", world.register_system(get_player_score)),
  ("opponent", world.register_system(get_opponent_score)),
];

for (label, scoring_system) in scoring_systems {
  println!("{label} has score {}", world.run_system(scoring_system).expect("system succeeded"));
}
Source

pub fn run_system_with<I, O>( &mut self, id: SystemId<I, O>, input: <I as SystemInput>::Inner<'_>, ) -> Result<O, RegisteredSystemError<I, O>>
where I: SystemInput + 'static, O: 'static,

Run a stored chained system by its SystemId, providing an input value. Before running a system, it must first be registered. The method World::register_system stores a given system and returns a SystemId.

To use the supplied input, the system should have a SystemInput as the first parameter. Also runs any queued-up commands.

§Examples
fn increment(In(increment_by): In<u8>, mut counter: Local<u8>) -> u8 {
  *counter += increment_by;
  *counter
}

let mut world = World::default();
let counter_one = world.register_system(increment);
let counter_two = world.register_system(increment);
assert_eq!(world.run_system_with(counter_one, 1).unwrap(), 1);
assert_eq!(world.run_system_with(counter_one, 20).unwrap(), 21);
assert_eq!(world.run_system_with(counter_two, 30).unwrap(), 30);

See World::run_system for more examples.

Source

pub fn register_system_cached<I, O, M, S>( &mut self, system: S, ) -> SystemId<I, O>
where I: SystemInput + 'static, O: 'static, S: IntoSystem<I, O, M> + 'static,

Registers a system or returns its cached SystemId.

If you want to run the system immediately and you don’t need its SystemId, see World::run_system_cached.

The first time this function is called for a particular system, it will register it and store its SystemId in a CachedSystemId resource for later. If you would rather manage the SystemId yourself, or register multiple copies of the same system, use World::register_system instead.

§Limitations

This function only accepts ZST (zero-sized) systems to guarantee that any two systems of the same type must be equal. This means that closures that capture the environment, and function pointers, are not accepted.

If you want to access values from the environment within a system, consider passing them in as inputs via World::run_system_cached_with. If that’s not an option, consider World::register_system instead.

Source

pub fn unregister_system_cached<I, O, M, S>( &mut self, _system: S, ) -> Result<RemovedSystem<I, O>, RegisteredSystemError<I, O>>
where I: SystemInput + 'static, O: 'static, S: IntoSystem<I, O, M> + 'static,

Removes a cached system and its CachedSystemId resource.

See World::register_system_cached for more information.

Source

pub fn run_system_cached<O, M, S>( &mut self, system: S, ) -> Result<O, RegisteredSystemError<(), O>>
where O: 'static, S: IntoSystem<(), O, M> + 'static,

Runs a cached system, registering it if necessary.

See World::register_system_cached for more information.

Source

pub fn run_system_cached_with<I, O, M, S>( &mut self, system: S, input: <I as SystemInput>::Inner<'_>, ) -> Result<O, RegisteredSystemError<I, O>>
where I: SystemInput + 'static, O: 'static, S: IntoSystem<I, O, M> + 'static,

Runs a cached system with an input, registering it if necessary.

To use the supplied input, the system should have a SystemInput as the first parameter. See World::register_system_cached for more information.

Source§

impl World

Source

pub fn get_reflect( &self, entity: Entity, type_id: TypeId, ) -> Result<&(dyn Reflect + 'static), GetComponentReflectError>

Retrieves a reference to the given entity’s Component of the given type_id using reflection.

Requires implementing Reflect for the Component (e.g., using #[derive(Reflect)) and app.register_type::<TheComponent>() to have been called1.

If you want to call this with a ComponentId, see World::components and Components::get_id to get the corresponding TypeId.

Also see the crate documentation for bevy_reflect for more information on Reflect and bevy’s reflection capabilities.

§Errors

See GetComponentReflectError for the possible errors and their descriptions.

§Example
use bevy_ecs::prelude::*;
use bevy_reflect::Reflect;
use std::any::TypeId;

// define a `Component` and derive `Reflect` for it
#[derive(Component, Reflect)]
struct MyComponent;

// create a `World` for this example
let mut world = World::new();

// Note: This is usually handled by `App::register_type()`, but this example cannot use `App`.
world.init_resource::<AppTypeRegistry>();
world.get_resource_mut::<AppTypeRegistry>().unwrap().write().register::<MyComponent>();

// spawn an entity with a `MyComponent`
let entity = world.spawn(MyComponent).id();

// retrieve a reflected reference to the entity's `MyComponent`
let comp_reflected: &dyn Reflect = world.get_reflect(entity, TypeId::of::<MyComponent>()).unwrap();

// make sure we got the expected type
assert!(comp_reflected.is::<MyComponent>());
§Note

Requires the bevy_reflect feature (included in the default features).


  1. More specifically: Requires TypeData for ReflectFromPtr to be registered for the given type_id, which is automatically handled when deriving Reflect and calling App::register_type

Source

pub fn get_reflect_mut( &mut self, entity: Entity, type_id: TypeId, ) -> Result<Mut<'_, dyn Reflect>, GetComponentReflectError>

Retrieves a mutable reference to the given entity’s Component of the given type_id using reflection.

Requires implementing Reflect for the Component (e.g., using #[derive(Reflect)) and app.register_type::<TheComponent>() to have been called.

This is the mutable version of World::get_reflect, see its docs for more information and an example.

Just calling this method does not trigger change detection.

§Errors

See GetComponentReflectError for the possible errors and their descriptions.

§Example

See the documentation for World::get_reflect.

§Note

Requires the feature bevy_reflect (included in the default features).

Source

pub fn insert_reflect_resource( &mut self, resource_id: ComponentId, reflected_resource: Box<dyn PartialReflect>, )

Inserts a reflected resource into the world. If the resource already exists, it is overwritten.

Source§

impl World

Source

pub fn new() -> World

Creates a new empty World.

§Panics

If usize::MAX Worlds have been created. This guarantee allows System Parameters to safely uniquely identify a World, since its WorldId is unique

Examples found in repository?
examples/ecs/custom_executor.rs (line 46)
45fn main() {
46    let mut world = World::new();
47    world.init_resource::<Counter>();
48
49    let mut schedule = Schedule::default();
50    schedule.set_executor(CustomExecutor);
51    schedule.add_systems((increment, print_counter).chain());
52
53    for _ in 0..5 {
54        schedule.run(&mut world);
55    }
56}
More examples
Hide additional examples
crates/bevy_ecs/examples/resources.rs (line 16)
14fn main() {
15    // Create a world
16    let mut world = World::new();
17
18    // Add the counter resource
19    world.insert_resource(Counter { value: 0 });
20
21    // Create a schedule
22    let mut schedule = Schedule::default();
23
24    // Add systems to increase the counter and to print out the current value
25    schedule.add_systems((increase_counter, print_counter).chain());
26
27    for iteration in 1..=10 {
28        println!("Simulating frame {iteration}/10");
29        schedule.run(&mut world);
30    }
31}
crates/bevy_ecs/examples/change_detection.rs (line 21)
19fn main() {
20    // Create a new empty World to hold our Entities, Components and Resources
21    let mut world = World::new();
22
23    // Add the counter resource to remember how many entities where spawned
24    world.insert_resource(EntityCounter { value: 0 });
25
26    // Create a new Schedule, which stores systems and controls their relative ordering
27    let mut schedule = Schedule::default();
28
29    // Add systems to the Schedule to execute our app logic
30    // We can label our systems to force a specific run-order between some of them
31    schedule.add_systems((
32        spawn_entities.in_set(SimulationSystems::Spawn),
33        print_counter_when_changed.after(SimulationSystems::Spawn),
34        age_all_entities.in_set(SimulationSystems::Age),
35        remove_old_entities.after(SimulationSystems::Age),
36        print_changed_entities.after(SimulationSystems::Age),
37    ));
38
39    // Simulate 10 frames in our world
40    for iteration in 1..=10 {
41        println!("Simulating frame {iteration}/10");
42        schedule.run(&mut world);
43    }
44}
crates/bevy_ecs/examples/events.rs (line 10)
8fn main() {
9    // Create a new empty world.
10    let mut world = World::new();
11    // The message registry is stored as a resource, and allows us to quickly update all messages at once.
12    // This call adds both the registry resource and the `Messages` resource into the world.
13    MessageRegistry::register_message::<MyMessage>(&mut world);
14
15    // Create a schedule to store our systems
16    let mut schedule = Schedule::default();
17
18    // Messages need to be updated every frame in order to clear our buffers.
19    // This update should happen before we use the messages.
20    // Here, we use system sets to control the ordering.
21    #[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
22    pub struct EventFlusherSystems;
23
24    schedule.add_systems(bevy_ecs::message::message_update_system.in_set(EventFlusherSystems));
25
26    // Add systems sending and receiving messages after the messages are flushed.
27    schedule.add_systems((
28        sending_system.after(EventFlusherSystems),
29        receiving_system.after(sending_system),
30    ));
31
32    // Simulate 10 frames of our world
33    for iteration in 1..=10 {
34        println!("Simulating frame {iteration}/10");
35        schedule.run(&mut world);
36    }
37}
examples/scene/world_serialization.rs (line 175)
166fn save_world_system(world: &mut World) {
167    let asset_server = world.resource::<AssetServer>().clone();
168    // The `TypeRegistry` resource contains information about all registered types (including components).
169    // This is used to construct worlds, so we'll want to ensure that we use the registry from the
170    // main world. To do this, we can simply clone the `AppTypeRegistry` resource.
171    let type_registry = world.resource::<AppTypeRegistry>().clone();
172
173    // Any ECS World can be serialized.
174    // For demonstration purposes, we'll create a new one.
175    let mut scene_world = World::new();
176
177    let mut component_b = ComponentB::from_world(world);
178    component_b.value = "hello".to_string();
179    scene_world.spawn((
180        component_b,
181        ComponentA { x: 1.0, y: 2.0 },
182        Transform::IDENTITY,
183        Name::new("joe"),
184        WorldAssetRoot(asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0")),
185    ));
186    scene_world.spawn(ComponentA { x: 3.0, y: 4.0 });
187    scene_world.insert_resource(ResourceA { score: 1 });
188
189    // With our sample world ready to go, we can now create a DynamicWorld from it.
190    // For simplicity, we will create our scene using DynamicWorld directly, but if
191    // you need more control, you can use DynamicWorldBuilder.
192    let dynamic_world = DynamicWorld::from_world_with(&scene_world, &type_registry.read());
193
194    // Dynamic Worlds can be serialized like this:
195    let type_registry = world.resource::<AppTypeRegistry>();
196    let type_registry = type_registry.read();
197    let serialized_world = dynamic_world.serialize(&type_registry).unwrap();
198
199    // Shows the serialized world in the console
200    info!("{}", serialized_world);
201
202    // Writing the world to a new file. Using a task to avoid calling the filesystem APIs in a system
203    // as they are blocking.
204    //
205    // This can't work in Wasm as there is no filesystem access.
206    #[cfg(not(target_arch = "wasm32"))]
207    IoTaskPool::get()
208        .spawn(async move {
209            // Write the world RON data to file
210            File::create(format!("assets/{NEW_WORLD_FILE_PATH}"))
211                .and_then(|mut file| file.write(serialized_world.as_bytes()))
212                .expect("Error while writing world to file");
213        })
214        .detach();
215}
examples/ecs/relationships.rs (line 39)
36fn main() {
37    // Operating on a raw `World` and running systems one at a time
38    // is great for writing tests and teaching abstract concepts!
39    let mut world = World::new();
40
41    // We're going to spawn a few entities and relate them to each other in a complex way.
42    // To start, Bob will target Alice, Charlie will target Bob,
43    // and Alice will target Charlie. This creates a loop in the relationship graph.
44    //
45    // Then, we'll spawn Devon, who will target Charlie,
46    // creating a more complex graph with a branching structure.
47    fn spawning_entities_with_relationships(mut commands: Commands) {
48        // Calling .id() after spawning an entity will return the `Entity` identifier of the spawned entity,
49        // even though the entity itself is not yet instantiated in the world.
50        // This works because Commands will reserve the entity ID before actually spawning the entity,
51        // through the use of atomic counters.
52        let alice = commands.spawn(Name::new("Alice")).id();
53        // Relations are just components, so we can add them into the bundle that we're spawning.
54        let bob = commands.spawn((Name::new("Bob"), Targeting(alice))).id();
55
56        // The `with_related` and `with_related_entities` helper methods on `EntityCommands` can be used to add relations in a more ergonomic way.
57        let charlie = commands
58            .spawn((Name::new("Charlie"), Targeting(bob)))
59            // The `with_related` method will spawn a bundle with `Targeting` relationship
60            .with_related::<Targeting>(Name::new("James"))
61            // The `with_related_entities` method will automatically add the `Targeting` component to any entities spawned within the closure,
62            // targeting the entity that we're calling `with_related` on.
63            .with_related_entities::<Targeting>(|related_spawner_commands| {
64                // We could spawn multiple entities here, and they would all target `charlie`.
65                related_spawner_commands.spawn(Name::new("Devon"));
66            })
67            .id();
68
69        // Simply inserting the `Targeting` component will automatically create and update the `TargetedBy` component on the target entity.
70        // We can do this at any point; not just when the entity is spawned.
71        commands.entity(alice).insert(Targeting(charlie));
72    }
73
74    world
75        .run_system_once(spawning_entities_with_relationships)
76        .unwrap();
77
78    fn debug_relationships(
79        // Not all of our entities are targeted by something, so we use `Option` in our query to handle this case.
80        relations_query: Query<(&Name, &Targeting, Option<&TargetedBy>)>,
81        name_query: Query<&Name>,
82    ) {
83        let mut relationships = String::new();
84
85        for (name, targeting, maybe_targeted_by) in relations_query.iter() {
86            let targeting_name = name_query.get(targeting.0).unwrap();
87            let targeted_by_string = if let Some(targeted_by) = maybe_targeted_by {
88                let mut vec_of_names = Vec::<&Name>::new();
89
90                for entity in targeted_by.iter() {
91                    let name = name_query.get(entity).unwrap();
92                    vec_of_names.push(name);
93                }
94
95                // Convert this to a nice string for printing.
96                let vec_of_str: Vec<&str> = vec_of_names.iter().map(|name| name.as_str()).collect();
97                vec_of_str.join(", ")
98            } else {
99                "nobody".to_string()
100            };
101
102            relationships.push_str(&format!(
103                "{name} is targeting {targeting_name}, and is targeted by {targeted_by_string}\n",
104            ));
105        }
106
107        println!("{relationships}");
108    }
109
110    world.run_system_once(debug_relationships).unwrap();
111
112    // Demonstrates how to correctly mutate relationships.
113    // Relationship components are immutable! We can't query for the `Targeting` component mutably and modify it directly,
114    // but we can insert a new `Targeting` component to replace the old one.
115    // This allows the hooks on the `Targeting` component to update the `TargetedBy` component correctly.
116    // The `TargetedBy` component will be updated automatically!
117    fn mutate_relationships(name_query: Query<(Entity, &Name)>, mut commands: Commands) {
118        // Let's find Devon by doing a linear scan of the entity names.
119        let devon = name_query
120            .iter()
121            .find(|(_entity, name)| name.as_str() == "Devon")
122            .unwrap()
123            .0;
124
125        let alice = name_query
126            .iter()
127            .find(|(_entity, name)| name.as_str() == "Alice")
128            .unwrap()
129            .0;
130
131        println!("Making Devon target Alice.\n");
132        commands.entity(devon).insert(Targeting(alice));
133    }
134
135    world.run_system_once(mutate_relationships).unwrap();
136    world.run_system_once(debug_relationships).unwrap();
137
138    // Systems can return errors,
139    // which can be used to signal that something went wrong during the system's execution.
140    #[derive(Debug)]
141    #[expect(
142        dead_code,
143        reason = "Rust considers types that are only used by their debug trait as dead code."
144    )]
145    struct TargetingCycle {
146        initial_entity: Entity,
147        visited: EntityHashSet,
148    }
149
150    /// Bevy's relationships come with all sorts of useful methods for traversal.
151    /// Here, we're going to look for cycles using a depth-first search.
152    fn check_for_cycles(
153        // We want to check every entity for cycles
154        query_to_check: Query<Entity, With<Targeting>>,
155        // Fetch the names for easier debugging.
156        name_query: Query<&Name>,
157        // The targeting_query allows us to traverse the relationship graph.
158        targeting_query: Query<&Targeting>,
159    ) -> Result<(), TargetingCycle> {
160        for initial_entity in query_to_check.iter() {
161            let mut visited = EntityHashSet::new();
162            let mut targeting_name = name_query.get(initial_entity).unwrap().clone();
163            println!("Checking for cycles starting at {targeting_name}",);
164
165            // There's all sorts of methods like this; check the `Query` docs for more!
166            // This would also be easy to do by just manually checking the `Targeting` component,
167            // and calling `query.get(targeted_entity)` on the entity that it targets in a loop.
168            for targeting in targeting_query.iter_ancestors(initial_entity) {
169                let target_name = name_query.get(targeting).unwrap();
170                println!("{targeting_name} is targeting {target_name}",);
171                targeting_name = target_name.clone();
172
173                if !visited.insert(targeting) {
174                    return Err(TargetingCycle {
175                        initial_entity,
176                        visited,
177                    });
178                }
179            }
180        }
181
182        // If we've checked all the entities and haven't found a cycle, we're good!
183        Ok(())
184    }
185
186    // Calling `world.run_system_once` on systems which return Results gives us two layers of errors:
187    // the first checks if running the system failed, and the second checks if the system itself returned an error.
188    // We're unwrapping the first, but checking the output of the system itself.
189    let cycle_result = world.run_system_once(check_for_cycles).unwrap();
190    println!("{cycle_result:?} \n");
191    // We deliberately introduced a cycle during spawning!
192    assert!(cycle_result.is_err());
193
194    // Now, let's demonstrate removing relationships and break the cycle.
195    fn untarget(mut commands: Commands, name_query: Query<(Entity, &Name)>) {
196        // Let's find Charlie by doing a linear scan of the entity names.
197        let charlie = name_query
198            .iter()
199            .find(|(_entity, name)| name.as_str() == "Charlie")
200            .unwrap()
201            .0;
202
203        // We can remove the `Targeting` component to remove the relationship
204        // and break the cycle we saw earlier.
205        println!("Removing Charlie's targeting relationship.\n");
206        commands.entity(charlie).remove::<Targeting>();
207    }
208
209    world.run_system_once(untarget).unwrap();
210    world.run_system_once(debug_relationships).unwrap();
211    // Cycle free!
212    let cycle_result = world.run_system_once(check_for_cycles).unwrap();
213    println!("{cycle_result:?} \n");
214    assert!(cycle_result.is_ok());
215}
Source

pub fn id(&self) -> WorldId

Retrieves this World’s unique ID

Source

pub fn as_unsafe_world_cell(&mut self) -> UnsafeWorldCell<'_>

Creates a new UnsafeWorldCell view with complete read+write access.

Source

pub fn as_unsafe_world_cell_readonly(&self) -> UnsafeWorldCell<'_>

Creates a new UnsafeWorldCell view with only read access to everything.

Source

pub fn entities(&self) -> &Entities

Retrieves this world’s Entities collection.

Examples found in repository?
examples/ecs/callbacks.rs (line 37)
21fn setup_callbacks(mut commands: Commands) {
22    let trivial_callback = Callback {
23        system_id: commands.register_system(|| {
24            println!("This is the trivial callback system");
25        }),
26    };
27
28    let ordinary_system_callback = Callback {
29        system_id: commands.register_system(|query: Query<&Callback>| {
30            let n_callbacks = query.iter().len();
31            println!("This is the ordinary callback system. There are currently {n_callbacks} callbacks in the world.");
32        }),
33    };
34
35    let exclusive_callback = Callback {
36        system_id: commands.register_system(|world: &mut World| {
37            let n_entities = world.entities().len();
38            println!("This is the exclusive callback system. There are currently {n_entities} entities in the world.");
39        }),
40    };
41
42    commands.spawn(trivial_callback);
43    commands.spawn(ordinary_system_callback);
44    commands.spawn(exclusive_callback);
45}
Source

pub fn entity_allocator(&self) -> &EntityAllocator

Retrieves this world’s EntityAllocator collection.

Source

pub fn entity_allocator_mut(&mut self) -> &mut EntityAllocator

Retrieves this world’s EntityAllocator collection mutably.

Source

pub unsafe fn entities_mut(&mut self) -> &mut Entities

Retrieves this world’s Entities collection mutably.

§Safety

Mutable reference must not be used to put the Entities data in an invalid state for this World

Source

pub fn entity_count(&self) -> u32

Retrieves the number of Entities in the world.

This is helpful as a diagnostic, but it can also be used effectively in tests.

Source

pub fn archetypes(&self) -> &Archetypes

Retrieves this world’s Archetypes collection.

Source

pub fn components(&self) -> &Components

Retrieves this world’s Components collection.

Examples found in repository?
examples/ecs/dynamic.rs (line 124)
69fn main() {
70    let mut world = World::new();
71    let mut lines = std::io::stdin().lines();
72    let mut component_names = HashMap::<String, ComponentId>::new();
73    let mut component_info = HashMap::<ComponentId, ComponentInfo>::new();
74    let mut event_names = HashMap::<String, EventKey>::new();
75
76    println!("{PROMPT}");
77    loop {
78        print!("\n> ");
79        let _ = std::io::stdout().flush();
80        let Some(Ok(line)) = lines.next() else {
81            return;
82        };
83
84        if line.is_empty() {
85            return;
86        };
87
88        let Some((first, rest)) = line.trim().split_once(|c: char| c.is_whitespace()) else {
89            match &line.chars().next() {
90                Some('c') => println!("{COMPONENT_PROMPT}"),
91                Some('s') => println!("{ENTITY_PROMPT}"),
92                Some('q') => println!("{QUERY_PROMPT}"),
93                Some('e') => println!("{EVENT_PROMPT}"),
94                Some('t') => println!("{EMIT_PROMPT}"),
95                _ => println!("{PROMPT}"),
96            }
97            continue;
98        };
99
100        match &first[0..1] {
101            "c" => {
102                rest.split(',').for_each(|component| {
103                    let mut component = component.split_whitespace();
104                    let Some(name) = component.next() else {
105                        return;
106                    };
107                    let size = match component.next().map(str::parse) {
108                        Some(Ok(size)) => size,
109                        _ => 0,
110                    };
111                    // Register our new component to the world with a layout specified by it's size
112                    // SAFETY: [u64] is Send + Sync
113                    let id = world.register_component_with_descriptor(unsafe {
114                        ComponentDescriptor::new_with_layout(
115                            name.to_string(),
116                            StorageType::Table,
117                            Layout::array::<u64>(size).unwrap(),
118                            None,
119                            true,
120                            ComponentCloneBehavior::Default,
121                            None,
122                        )
123                    });
124                    let Some(info) = world.components().get_info(id) else {
125                        return;
126                    };
127                    component_names.insert(name.to_string(), id);
128                    component_info.insert(id, info.clone());
129                    println!("Component {} created with id: {}", name, id.index());
130                });
131            }
132            "s" => {
133                let mut to_insert_ids = Vec::new();
134                let mut to_insert_data = Vec::new();
135                rest.split(',').for_each(|component| {
136                    let mut component = component.split_whitespace();
137                    let Some(name) = component.next() else {
138                        return;
139                    };
140
141                    // Get the id for the component with the given name
142                    let Some(&id) = component_names.get(name) else {
143                        println!("Component {name} does not exist");
144                        return;
145                    };
146
147                    // Calculate the length for the array based on the layout created for this component id
148                    let info = world.components().get_info(id).unwrap();
149                    let len = info.layout().size() / size_of::<u64>();
150                    let mut values: Vec<u64> = component
151                        .take(len)
152                        .filter_map(|value| value.parse::<u64>().ok())
153                        .collect();
154                    values.resize(len, 0);
155
156                    // Collect the id and array to be inserted onto our entity
157                    to_insert_ids.push(id);
158                    to_insert_data.push(values);
159                });
160
161                let mut entity = world.spawn_empty();
162
163                // Construct an `OwningPtr` for each component in `to_insert_data`
164                let to_insert_ptr = to_owning_ptrs(&mut to_insert_data);
165
166                // SAFETY:
167                // - Component ids have been taken from the same world
168                // - Each array is created to the layout specified in the world
169                unsafe {
170                    entity.insert_by_ids(&to_insert_ids, to_insert_ptr.into_iter());
171                }
172
173                println!("Entity spawned with id: {}", entity.id());
174            }
175            "q" => {
176                let mut builder = QueryBuilder::<FilteredEntityMut>::new(&mut world);
177                parse_query(rest, &mut builder, &component_names);
178                let mut query = builder.build();
179                query.iter_mut(&mut world).for_each(|filtered_entity| {
180                    let terms = filtered_entity
181                        .access()
182                        .try_iter_access()
183                        .unwrap()
184                        .map(|component_access| {
185                            let id = *component_access.index();
186                            let ptr = filtered_entity.get_by_id(id).unwrap();
187                            let info = component_info.get(&id).unwrap();
188                            let len = info.layout().size() / size_of::<u64>();
189
190                            // SAFETY:
191                            // - All components are created with layout [u64]
192                            // - len is calculated from the component descriptor
193                            let data = unsafe {
194                                std::slice::from_raw_parts_mut(
195                                    ptr.assert_unique().as_ptr().cast::<u64>(),
196                                    len,
197                                )
198                            };
199
200                            // If we have write access, increment each value once
201                            if matches!(component_access, ComponentAccessKind::Exclusive(_)) {
202                                data.iter_mut().for_each(|data| {
203                                    *data += 1;
204                                });
205                            }
206
207                            format!("{}: {:?}", info.name(), data[0..len].to_vec())
208                        })
209                        .collect::<Vec<_>>()
210                        .join(", ");
211
212                    println!("{}: {}", filtered_entity.id(), terms);
213                });
214            }
215            "e" => {
216                rest.split(',').for_each(|event| {
217                    let name = event.trim();
218                    if name.is_empty() {
219                        return;
220                    }
221
222                    // Register a ComponentId for this event, no Rust type needed.
223                    // SAFETY: ZST with no drop
224                    let event_component_id = world.register_component_with_descriptor(unsafe {
225                        ComponentDescriptor::new_with_layout(
226                            format!("event:{name}"),
227                            StorageType::Table,
228                            Layout::new::<()>(),
229                            None,
230                            false,
231                            ComponentCloneBehavior::Ignore,
232                            None,
233                        )
234                    });
235                    // SAFETY: event_component_id was just registered for this event
236                    let event_key = unsafe { EventKey::new(event_component_id) };
237                    event_names.insert(name.to_string(), event_key);
238
239                    // Build a dynamic observer that prints when the event fires.
240                    let runner: ObserverRunner = |mut world, _observer, ctx, _event, _trigger| {
241                        println!("  Observer fired!");
242                        if let Some(mut counts) = world.get_resource_mut::<EventFireCount>() {
243                            *counts.0.entry(ctx.event_key).or_insert(0) += 1;
244                        }
245                    };
246
247                    // SAFETY: event_key was just registered, runner ignores pointers
248                    let observer =
249                        unsafe { Observer::with_dynamic_runner(runner).with_event_key(event_key) };
250                    world.spawn(observer);
251
252                    println!(
253                        "Event '{name}' registered (key: {}) with a dynamic observer",
254                        event_component_id.index()
255                    );
256                });
257
258                // Ensure the counter resource exists.
259                world.init_resource::<EventFireCount>();
260            }
261            "t" => {
262                let name = rest.trim();
263                let Some(&event_key) = event_names.get(name) else {
264                    println!(
265                        "Event '{name}' does not exist. Register it first with 'event {name}'"
266                    );
267                    continue;
268                };
269
270                let mut event_data = ();
271                let mut trigger_data = ();
272                // SAFETY: event_key was registered in this world, both pointers are valid ZSTs
273                unsafe {
274                    world.trigger_dynamic(
275                        event_key,
276                        PtrMut::from(&mut event_data),
277                        PtrMut::from(&mut trigger_data),
278                    );
279                }
280
281                let count = world
282                    .get_resource::<EventFireCount>()
283                    .map_or(0, |c| c.0.get(&event_key).copied().unwrap_or(0));
284                println!("Event '{name}' triggered ({count} fires)");
285            }
286            _ => continue,
287        }
288    }
289}
Source

pub fn resource_entities(&self) -> &ResourceEntities

Retrieves this world’s ResourceEntities.

Source

pub fn components_queue(&self) -> ComponentsQueuedRegistrator<'_>

Prepares a ComponentsQueuedRegistrator for the world. NOTE: ComponentsQueuedRegistrator is easily misused. See its docs for important notes on when and how it should be used.

Source

pub fn components_registrator(&mut self) -> ComponentsRegistrator<'_>

Prepares a ComponentsRegistrator for the world.

Source

pub fn storages(&self) -> &Storages

Retrieves this world’s Storages collection.

Source

pub fn bundles(&self) -> &Bundles

Retrieves this world’s Bundles collection.

Source

pub fn removed_components(&self) -> &RemovedComponentMessages

Retrieves this world’s RemovedComponentMessages collection

Source

pub fn observers(&self) -> &Observers

Retrieves this world’s Observers list

Source

pub fn commands(&mut self) -> Commands<'_, '_>

Creates a new Commands instance that writes to the world’s command queue Use World::flush to apply all queued commands

Source

pub fn register_component<T>(&mut self) -> ComponentId
where T: Component,

Registers a new Component type and returns the ComponentId created for it.

§Usage Notes

In most cases, you don’t need to call this method directly since component registration happens automatically during system initialization.

Source

pub fn register_disabling_component<C>(&mut self)
where C: Component,

Registers a component type as “disabling”, using default query filters to exclude entities with the component from queries.

Source

pub fn register_component_hooks<T>(&mut self) -> &mut ComponentHooks
where T: Component,

Returns a mutable reference to the ComponentHooks for a Component type.

Will panic if T exists in any archetypes.

Examples found in repository?
examples/ecs/component_hooks.rs (line 67)
61fn setup(world: &mut World) {
62    // In order to register component hooks the component must:
63    // - not be currently in use by any entities in the world
64    // - not already have a hook of that kind registered
65    // This is to prevent overriding hooks defined in plugins and other crates as well as keeping things fast
66    world
67        .register_component_hooks::<MyComponent>()
68        // There are 4 component lifecycle hooks: `on_add`, `on_insert`, `on_discard` and `on_remove`
69        // A hook has 2 arguments:
70        // - a `DeferredWorld`, this allows access to resource and component data as well as `Commands`
71        // - a `HookContext`, this provides access to the following contextual information:
72        //   - the entity that triggered the hook
73        //   - the component id of the triggering component, this is mostly used for dynamic components
74        //   - the location of the code that caused the hook to trigger
75        //
76        // `on_add` will trigger when a component is inserted onto an entity without it
77        .on_add(
78            |mut world,
79             HookContext {
80                 entity,
81                 component_id,
82                 caller,
83                 ..
84             }| {
85                // You can access component data from within the hook
86                let value = world.get::<MyComponent>(entity).unwrap().0;
87                println!(
88                    "{component_id:?} added to {entity} with value {value:?}{}",
89                    caller
90                        .map(|location| format!("due to {location}"))
91                        .unwrap_or_default()
92                );
93                // Or access resources
94                world
95                    .resource_mut::<MyComponentIndex>()
96                    .insert(value, entity);
97                // Or send messages
98                world.write_message(MyMessage);
99            },
100        )
101        // `on_insert` will trigger when a component is inserted onto an entity,
102        // regardless of whether or not it already had it and after `on_add` if it ran
103        .on_insert(|world, _| {
104            println!("Current Index: {:?}", world.resource::<MyComponentIndex>());
105        })
106        // `on_discard` will trigger when a component is inserted onto an entity that already had it,
107        // and runs before the value is replaced.
108        // Also triggers when a component is removed from an entity, and runs before `on_remove`
109        .on_discard(|mut world, context| {
110            let value = world.get::<MyComponent>(context.entity).unwrap().0;
111            world.resource_mut::<MyComponentIndex>().remove(&value);
112        })
113        // `on_remove` will trigger when a component is removed from an entity,
114        // since it runs before the component is removed you can still access the component data
115        .on_remove(
116            |mut world,
117             HookContext {
118                 entity,
119                 component_id,
120                 caller,
121                 ..
122             }| {
123                let value = world.get::<MyComponent>(entity).unwrap().0;
124                println!(
125                    "{component_id:?} removed from {entity} with value {value:?}{}",
126                    caller
127                        .map(|location| format!("due to {location}"))
128                        .unwrap_or_default()
129                );
130                // You can also issue commands through `.commands()`
131                world.commands().entity(entity).despawn();
132            },
133        );
134}
Source

pub fn register_component_hooks_by_id( &mut self, id: ComponentId, ) -> Option<&mut ComponentHooks>

Returns a mutable reference to the ComponentHooks for a Component with the given id if it exists.

Will panic if id exists in any archetypes.

Source

pub fn register_required_components<T, R>(&mut self)
where T: Component, R: Component + Default,

Registers the given component R as a required component for T.

When T is added to an entity, R and its own required components will also be added if R was not already provided. The Default constructor will be used for the creation of R. If a custom constructor is desired, use World::register_required_components_with instead.

For the non-panicking version, see World::try_register_required_components.

Note that requirements must currently be registered before T is inserted into the world for the first time. This limitation may be fixed in the future.

§Panics

Panics if R is already a directly required component for T, or if T has ever been added on an entity before the registration.

Indirect requirements through other components are allowed. In those cases, any existing requirements will only be overwritten if the new requirement is more specific.

§Example
#[derive(Component)]
struct A;

#[derive(Component, Default, PartialEq, Eq, Debug)]
struct B(usize);

#[derive(Component, Default, PartialEq, Eq, Debug)]
struct C(u32);

// Register B as required by A and C as required by B.
world.register_required_components::<A, B>();
world.register_required_components::<B, C>();

// This will implicitly also insert B and C with their Default constructors.
let id = world.spawn(A).id();
assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());
assert_eq!(&C(0), world.entity(id).get::<C>().unwrap());
Source

pub fn register_required_components_with<T, R>( &mut self, constructor: fn() -> R, )
where T: Component, R: Component,

Registers the given component R as a required component for T.

When T is added to an entity, R and its own required components will also be added if R was not already provided. The given constructor will be used for the creation of R. If a Default constructor is desired, use World::register_required_components instead.

For the non-panicking version, see World::try_register_required_components_with.

Note that requirements must currently be registered before T is inserted into the world for the first time. This limitation may be fixed in the future.

§Panics

Panics if R is already a directly required component for T, or if T has ever been added on an entity before the registration.

Indirect requirements through other components are allowed. In those cases, any existing requirements will only be overwritten if the new requirement is more specific.

§Example
#[derive(Component)]
struct A;

#[derive(Component, Default, PartialEq, Eq, Debug)]
struct B(usize);

#[derive(Component, PartialEq, Eq, Debug)]
struct C(u32);

// Register B and C as required by A and C as required by B.
// A requiring C directly will overwrite the indirect requirement through B.
world.register_required_components::<A, B>();
world.register_required_components_with::<B, C>(|| C(1));
world.register_required_components_with::<A, C>(|| C(2));

// This will implicitly also insert B with its Default constructor and C
// with the custom constructor defined by A.
let id = world.spawn(A).id();
assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());
assert_eq!(&C(2), world.entity(id).get::<C>().unwrap());
Source

pub fn try_register_required_components<T, R>( &mut self, ) -> Result<(), RequiredComponentsError>
where T: Component, R: Component + Default,

Tries to register the given component R as a required component for T.

When T is added to an entity, R and its own required components will also be added if R was not already provided. The Default constructor will be used for the creation of R. If a custom constructor is desired, use World::register_required_components_with instead.

For the panicking version, see World::register_required_components.

Note that requirements must currently be registered before T is inserted into the world for the first time. This limitation may be fixed in the future.

§Errors

Returns a RequiredComponentsError if R is already a directly required component for T, or if T has ever been added on an entity before the registration.

Indirect requirements through other components are allowed. In those cases, any existing requirements will only be overwritten if the new requirement is more specific.

§Example
#[derive(Component)]
struct A;

#[derive(Component, Default, PartialEq, Eq, Debug)]
struct B(usize);

#[derive(Component, Default, PartialEq, Eq, Debug)]
struct C(u32);

// Register B as required by A and C as required by B.
world.register_required_components::<A, B>();
world.register_required_components::<B, C>();

// Duplicate registration! This will fail.
assert!(world.try_register_required_components::<A, B>().is_err());

// This will implicitly also insert B and C with their Default constructors.
let id = world.spawn(A).id();
assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());
assert_eq!(&C(0), world.entity(id).get::<C>().unwrap());
Source

pub fn try_register_required_components_with<T, R>( &mut self, constructor: fn() -> R, ) -> Result<(), RequiredComponentsError>
where T: Component, R: Component,

Tries to register the given component R as a required component for T.

When T is added to an entity, R and its own required components will also be added if R was not already provided. The given constructor will be used for the creation of R. If a Default constructor is desired, use World::register_required_components instead.

For the panicking version, see World::register_required_components_with.

Note that requirements must currently be registered before T is inserted into the world for the first time. This limitation may be fixed in the future.

§Errors

Returns a RequiredComponentsError if R is already a directly required component for T, or if T has ever been added on an entity before the registration.

Indirect requirements through other components are allowed. In those cases, any existing requirements will only be overwritten if the new requirement is more specific.

§Example
#[derive(Component)]
struct A;

#[derive(Component, Default, PartialEq, Eq, Debug)]
struct B(usize);

#[derive(Component, PartialEq, Eq, Debug)]
struct C(u32);

// Register B and C as required by A and C as required by B.
// A requiring C directly will overwrite the indirect requirement through B.
world.register_required_components::<A, B>();
world.register_required_components_with::<B, C>(|| C(1));
world.register_required_components_with::<A, C>(|| C(2));

// Duplicate registration! Even if the constructors were different, this would fail.
assert!(world.try_register_required_components_with::<B, C>(|| C(1)).is_err());

// This will implicitly also insert B with its Default constructor and C
// with the custom constructor defined by A.
let id = world.spawn(A).id();
assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());
assert_eq!(&C(2), world.entity(id).get::<C>().unwrap());
Source

pub fn get_required_components<C>(&self) -> Option<&RequiredComponents>
where C: Component,

Retrieves the required components for the given component type, if it exists.

Source

pub fn get_required_components_by_id( &self, id: ComponentId, ) -> Option<&RequiredComponents>

Retrieves the required components for the component of the given ComponentId, if it exists.

Source

pub fn register_component_with_descriptor( &mut self, descriptor: ComponentDescriptor, ) -> ComponentId

Registers a new Component type and returns the ComponentId created for it.

This method differs from World::register_component in that it uses a ComponentDescriptor to register the new component type instead of statically available type information. This enables the dynamic registration of new component definitions at runtime for advanced use cases.

While the option to register a component from a descriptor is useful in type-erased contexts, the standard World::register_component function should always be used instead when type information is available at compile time.

Examples found in repository?
examples/ecs/immutable_components.rs (line 164)
135fn demo_3(world: &mut World) {
136    // This is a list of dynamic components we will create.
137    // The first item is the name of the component, and the second is the size
138    // in bytes.
139    let my_dynamic_components = [("Foo", 1), ("Bar", 2), ("Baz", 4)];
140
141    // This pipeline takes our component descriptions, registers them, and gets
142    // their ComponentId's.
143    let my_registered_components = my_dynamic_components
144        .into_iter()
145        .map(|(name, size)| {
146            // SAFETY:
147            // - No drop command is required
148            // - The component will store [u8; size], which is Send + Sync
149            let descriptor = unsafe {
150                ComponentDescriptor::new_with_layout(
151                    name.to_string(),
152                    StorageType::Table,
153                    Layout::array::<u8>(size).unwrap(),
154                    None,
155                    false,
156                    ComponentCloneBehavior::Default,
157                    None,
158                )
159            };
160
161            (name, size, descriptor)
162        })
163        .map(|(name, size, descriptor)| {
164            let component_id = world.register_component_with_descriptor(descriptor);
165
166            (name, size, component_id)
167        })
168        .collect::<Vec<(&str, usize, ComponentId)>>();
169
170    // Now that our components are registered, let's add them to an entity
171    let mut entity = world.spawn_empty();
172
173    for (_name, size, component_id) in &my_registered_components {
174        // We're just storing some zeroes for the sake of demonstration.
175        let data = core::iter::repeat_n(0, *size).collect::<Vec<u8>>();
176
177        OwningPtr::make(data, |ptr| {
178            // SAFETY:
179            // - ComponentId has been taken from the same world
180            // - Array is created to the layout specified in the world
181            unsafe {
182                entity.insert_by_id(*component_id, ptr);
183            }
184        });
185    }
186
187    for (_name, _size, component_id) in &my_registered_components {
188        // With immutable components, we can read the values...
189        assert!(entity.get_by_id(*component_id).is_ok());
190
191        // ...but we cannot gain a mutable reference.
192        assert!(entity.get_mut_by_id(*component_id).is_err());
193
194        // Instead, you must either remove or replace the value.
195    }
196}
More examples
Hide additional examples
examples/stress_tests/many_components.rs (lines 86-101)
78fn stress_test(num_entities: u32, num_components: u32, num_systems: u32) {
79    let mut rng = ChaCha8Rng::seed_from_u64(42);
80    let mut app = App::default();
81    let world = app.world_mut();
82
83    // register a bunch of components
84    let component_ids: Vec<ComponentId> = (1..=num_components)
85        .map(|i| {
86            world.register_component_with_descriptor(
87                // SAFETY:
88                // * We don't implement a drop function
89                // * u8 is Sync and Send
90                unsafe {
91                    ComponentDescriptor::new_with_layout(
92                        format!("Component{i}").to_string(),
93                        StorageType::Table,
94                        Layout::new::<u8>(),
95                        None,
96                        true, // is mutable
97                        ComponentCloneBehavior::Default,
98                        None,
99                    )
100                },
101            )
102        })
103        .collect();
104
105    // fill the schedule with systems
106    let mut schedule = Schedule::new(Update);
107    for _ in 1..=num_systems {
108        let num_access_components = rng.random_range(1..10);
109        let access_components: Vec<ComponentId> = component_ids
110            .sample(&mut rng, num_access_components)
111            .copied()
112            .collect();
113        let system = (QueryParamBuilder::new(|builder| {
114            for &access_component in &access_components {
115                if rand::random::<bool>() {
116                    builder.mut_id(access_component);
117                } else {
118                    builder.ref_id(access_component);
119                }
120            }
121        }),)
122            .build_state(world)
123            .build_any_system(base_system);
124        schedule.add_systems((move || access_components.clone()).pipe(system));
125    }
126
127    // spawn a bunch of entities
128    for _ in 1..=num_entities {
129        let num_components = rng.random_range(1..10);
130        let components: Vec<ComponentId> = component_ids
131            .sample(&mut rng, num_components)
132            .copied()
133            .collect();
134
135        let mut entity = world.spawn_empty();
136        // We use `ManuallyDrop` here as we need to avoid dropping the u8's when `values` is dropped
137        // since ownership of the values is passed to the world in `insert_by_ids`.
138        // But we do want to deallocate the memory when values is dropped.
139        let mut values: Vec<ManuallyDrop<u8>> = components
140            .iter()
141            .map(|_id| ManuallyDrop::new(rng.random_range(0..255)))
142            .collect();
143        let ptrs: Vec<OwningPtr> = values
144            .iter_mut()
145            .map(|value| {
146                // SAFETY:
147                // * We don't read/write `values` binding after this and values are `ManuallyDrop`,
148                // so we have the right to drop/move the values
149                unsafe { PtrMut::from(value).promote() }
150            })
151            .collect();
152        // SAFETY:
153        // * component_id's are from the same world
154        // * `values` was initialized above, so references are valid
155        unsafe {
156            entity.insert_by_ids(&components, ptrs.into_iter());
157        }
158    }
159
160    // overwrite Update schedule in the app
161    app.add_schedule(schedule);
162    app.add_plugins(MinimalPlugins)
163        .add_plugins(DiagnosticsPlugin)
164        .add_plugins(LogPlugin::default())
165        .add_plugins(FrameTimeDiagnosticsPlugin::default())
166        .add_plugins(LogDiagnosticsPlugin::filtered(HashSet::from_iter([
167            DiagnosticPath::new("fps"),
168        ])));
169    app.run();
170}
examples/ecs/dynamic.rs (lines 113-123)
69fn main() {
70    let mut world = World::new();
71    let mut lines = std::io::stdin().lines();
72    let mut component_names = HashMap::<String, ComponentId>::new();
73    let mut component_info = HashMap::<ComponentId, ComponentInfo>::new();
74    let mut event_names = HashMap::<String, EventKey>::new();
75
76    println!("{PROMPT}");
77    loop {
78        print!("\n> ");
79        let _ = std::io::stdout().flush();
80        let Some(Ok(line)) = lines.next() else {
81            return;
82        };
83
84        if line.is_empty() {
85            return;
86        };
87
88        let Some((first, rest)) = line.trim().split_once(|c: char| c.is_whitespace()) else {
89            match &line.chars().next() {
90                Some('c') => println!("{COMPONENT_PROMPT}"),
91                Some('s') => println!("{ENTITY_PROMPT}"),
92                Some('q') => println!("{QUERY_PROMPT}"),
93                Some('e') => println!("{EVENT_PROMPT}"),
94                Some('t') => println!("{EMIT_PROMPT}"),
95                _ => println!("{PROMPT}"),
96            }
97            continue;
98        };
99
100        match &first[0..1] {
101            "c" => {
102                rest.split(',').for_each(|component| {
103                    let mut component = component.split_whitespace();
104                    let Some(name) = component.next() else {
105                        return;
106                    };
107                    let size = match component.next().map(str::parse) {
108                        Some(Ok(size)) => size,
109                        _ => 0,
110                    };
111                    // Register our new component to the world with a layout specified by it's size
112                    // SAFETY: [u64] is Send + Sync
113                    let id = world.register_component_with_descriptor(unsafe {
114                        ComponentDescriptor::new_with_layout(
115                            name.to_string(),
116                            StorageType::Table,
117                            Layout::array::<u64>(size).unwrap(),
118                            None,
119                            true,
120                            ComponentCloneBehavior::Default,
121                            None,
122                        )
123                    });
124                    let Some(info) = world.components().get_info(id) else {
125                        return;
126                    };
127                    component_names.insert(name.to_string(), id);
128                    component_info.insert(id, info.clone());
129                    println!("Component {} created with id: {}", name, id.index());
130                });
131            }
132            "s" => {
133                let mut to_insert_ids = Vec::new();
134                let mut to_insert_data = Vec::new();
135                rest.split(',').for_each(|component| {
136                    let mut component = component.split_whitespace();
137                    let Some(name) = component.next() else {
138                        return;
139                    };
140
141                    // Get the id for the component with the given name
142                    let Some(&id) = component_names.get(name) else {
143                        println!("Component {name} does not exist");
144                        return;
145                    };
146
147                    // Calculate the length for the array based on the layout created for this component id
148                    let info = world.components().get_info(id).unwrap();
149                    let len = info.layout().size() / size_of::<u64>();
150                    let mut values: Vec<u64> = component
151                        .take(len)
152                        .filter_map(|value| value.parse::<u64>().ok())
153                        .collect();
154                    values.resize(len, 0);
155
156                    // Collect the id and array to be inserted onto our entity
157                    to_insert_ids.push(id);
158                    to_insert_data.push(values);
159                });
160
161                let mut entity = world.spawn_empty();
162
163                // Construct an `OwningPtr` for each component in `to_insert_data`
164                let to_insert_ptr = to_owning_ptrs(&mut to_insert_data);
165
166                // SAFETY:
167                // - Component ids have been taken from the same world
168                // - Each array is created to the layout specified in the world
169                unsafe {
170                    entity.insert_by_ids(&to_insert_ids, to_insert_ptr.into_iter());
171                }
172
173                println!("Entity spawned with id: {}", entity.id());
174            }
175            "q" => {
176                let mut builder = QueryBuilder::<FilteredEntityMut>::new(&mut world);
177                parse_query(rest, &mut builder, &component_names);
178                let mut query = builder.build();
179                query.iter_mut(&mut world).for_each(|filtered_entity| {
180                    let terms = filtered_entity
181                        .access()
182                        .try_iter_access()
183                        .unwrap()
184                        .map(|component_access| {
185                            let id = *component_access.index();
186                            let ptr = filtered_entity.get_by_id(id).unwrap();
187                            let info = component_info.get(&id).unwrap();
188                            let len = info.layout().size() / size_of::<u64>();
189
190                            // SAFETY:
191                            // - All components are created with layout [u64]
192                            // - len is calculated from the component descriptor
193                            let data = unsafe {
194                                std::slice::from_raw_parts_mut(
195                                    ptr.assert_unique().as_ptr().cast::<u64>(),
196                                    len,
197                                )
198                            };
199
200                            // If we have write access, increment each value once
201                            if matches!(component_access, ComponentAccessKind::Exclusive(_)) {
202                                data.iter_mut().for_each(|data| {
203                                    *data += 1;
204                                });
205                            }
206
207                            format!("{}: {:?}", info.name(), data[0..len].to_vec())
208                        })
209                        .collect::<Vec<_>>()
210                        .join(", ");
211
212                    println!("{}: {}", filtered_entity.id(), terms);
213                });
214            }
215            "e" => {
216                rest.split(',').for_each(|event| {
217                    let name = event.trim();
218                    if name.is_empty() {
219                        return;
220                    }
221
222                    // Register a ComponentId for this event, no Rust type needed.
223                    // SAFETY: ZST with no drop
224                    let event_component_id = world.register_component_with_descriptor(unsafe {
225                        ComponentDescriptor::new_with_layout(
226                            format!("event:{name}"),
227                            StorageType::Table,
228                            Layout::new::<()>(),
229                            None,
230                            false,
231                            ComponentCloneBehavior::Ignore,
232                            None,
233                        )
234                    });
235                    // SAFETY: event_component_id was just registered for this event
236                    let event_key = unsafe { EventKey::new(event_component_id) };
237                    event_names.insert(name.to_string(), event_key);
238
239                    // Build a dynamic observer that prints when the event fires.
240                    let runner: ObserverRunner = |mut world, _observer, ctx, _event, _trigger| {
241                        println!("  Observer fired!");
242                        if let Some(mut counts) = world.get_resource_mut::<EventFireCount>() {
243                            *counts.0.entry(ctx.event_key).or_insert(0) += 1;
244                        }
245                    };
246
247                    // SAFETY: event_key was just registered, runner ignores pointers
248                    let observer =
249                        unsafe { Observer::with_dynamic_runner(runner).with_event_key(event_key) };
250                    world.spawn(observer);
251
252                    println!(
253                        "Event '{name}' registered (key: {}) with a dynamic observer",
254                        event_component_id.index()
255                    );
256                });
257
258                // Ensure the counter resource exists.
259                world.init_resource::<EventFireCount>();
260            }
261            "t" => {
262                let name = rest.trim();
263                let Some(&event_key) = event_names.get(name) else {
264                    println!(
265                        "Event '{name}' does not exist. Register it first with 'event {name}'"
266                    );
267                    continue;
268                };
269
270                let mut event_data = ();
271                let mut trigger_data = ();
272                // SAFETY: event_key was registered in this world, both pointers are valid ZSTs
273                unsafe {
274                    world.trigger_dynamic(
275                        event_key,
276                        PtrMut::from(&mut event_data),
277                        PtrMut::from(&mut trigger_data),
278                    );
279                }
280
281                let count = world
282                    .get_resource::<EventFireCount>()
283                    .map_or(0, |c| c.0.get(&event_key).copied().unwrap_or(0));
284                println!("Event '{name}' triggered ({count} fires)");
285            }
286            _ => continue,
287        }
288    }
289}
Source

pub fn component_id<T>(&self) -> Option<ComponentId>
where T: Component,

Returns the ComponentId of the given Component type T.

The returned ComponentId is specific to the World instance it was retrieved from and should not be used with another World instance.

Returns None if the Component type has not yet been initialized within the World using World::register_component.

use bevy_ecs::prelude::*;

let mut world = World::new();

#[derive(Component)]
struct ComponentA;

let component_a_id = world.register_component::<ComponentA>();

assert_eq!(component_a_id, world.component_id::<ComponentA>().unwrap())
§See also
Source

pub fn register_resource<R>(&mut self) -> ComponentId
where R: Resource,

Registers a new Resource type and returns the ComponentId created for it.

The Resource doesn’t have a value in the World, it’s only registered. If you want to insert the Resource in the World, use World::init_resource or World::insert_resource instead.

Source

pub fn resource_id<T>(&self) -> Option<ComponentId>
where T: Resource,

👎Deprecated since 0.19.0:

use component_id

Returns the ComponentId of the given Resource type T.

The returned ComponentId is specific to the World instance it was retrieved from and should not be used with another World instance.

Returns None if the Resource type has not yet been initialized within the World using World::register_resource, World::init_resource or World::insert_resource.

Source

pub fn entity<F>(&self, entities: F) -> <F as WorldEntityFetch>::Ref<'_>

Returns EntityRefs that expose read-only operations for the given entities. This will panic if any of the given entities do not exist. Use World::get_entity if you want to check for entity existence instead of implicitly panicking.

This function supports fetching a single entity or multiple entities:

§Panics

If any of the given entities do not exist in the world.

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

let mut world = World::new();
let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();

let position = world.entity(entity).get::<Position>().unwrap();
assert_eq!(position.x, 0.0);
§Array of Entitys
#[derive(Component)]
struct Position {
  x: f32,
  y: f32,
}

let mut world = World::new();
let e1 = world.spawn(Position { x: 0.0, y: 0.0 }).id();
let e2 = world.spawn(Position { x: 1.0, y: 1.0 }).id();

let [e1_ref, e2_ref] = world.entity([e1, e2]);
let e1_position = e1_ref.get::<Position>().unwrap();
assert_eq!(e1_position.x, 0.0);
let e2_position = e2_ref.get::<Position>().unwrap();
assert_eq!(e2_position.x, 1.0);
§Slice of Entitys
#[derive(Component)]
struct Position {
  x: f32,
  y: f32,
}

let mut world = World::new();
let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();

let ids = vec![e1, e2, e3];
for eref in world.entity(&ids[..]) {
    assert_eq!(eref.get::<Position>().unwrap().y, 1.0);
}
§EntityHashSet
#[derive(Component)]
struct Position {
  x: f32,
  y: f32,
}

let mut world = World::new();
let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();

let ids = EntityHashSet::from_iter([e1, e2, e3]);
for (_id, eref) in world.entity(&ids) {
    assert_eq!(eref.get::<Position>().unwrap().y, 1.0);
}
Examples found in repository?
examples/ecs/immutable_components.rs (line 78)
77fn on_insert_name(mut world: DeferredWorld<'_>, HookContext { entity, .. }: HookContext) {
78    let Some(&name) = world.entity(entity).get::<Name>() else {
79        unreachable!("Insert hook guarantees `Name` is available on entity")
80    };
81    let Some(mut index) = world.get_resource_mut::<NameIndex>() else {
82        return;
83    };
84
85    index.name_to_entity.insert(name, entity);
86}
87
88/// When a [`Name`] is removed or replaced, remove it from our [`NameIndex`].
89///
90/// Since all mutations to [`Name`] are captured by hooks, we know it is currently
91/// inserted in the index.
92fn on_discard_name(mut world: DeferredWorld<'_>, HookContext { entity, .. }: HookContext) {
93    let Some(&name) = world.entity(entity).get::<Name>() else {
94        unreachable!("Discard hook guarantees `Name` is available on entity")
95    };
96    let Some(mut index) = world.get_resource_mut::<NameIndex>() else {
97        return;
98    };
99
100    index.name_to_entity.remove(&name);
101}
Source

pub fn entity_mut<F>(&mut self, entities: F) -> <F as WorldEntityFetch>::Mut<'_>

Returns EntityMuts that expose read and write operations for the given entities. This will panic if any of the given entities do not exist. Use World::get_entity_mut if you want to check for entity existence instead of implicitly panicking.

This function supports fetching a single entity or multiple entities:

In order to perform structural changes on the returned entity reference, such as adding or removing components, or despawning the entity, only a single Entity can be passed to this function. Allowing multiple entities at the same time with structural access would lead to undefined behavior, so EntityMut is returned when requesting multiple entities.

§Panics

If any of the given entities do not exist in the world.

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

let mut world = World::new();
let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();

let mut entity_mut = world.entity_mut(entity);
let mut position = entity_mut.get_mut::<Position>().unwrap();
position.y = 1.0;
assert_eq!(position.x, 0.0);
entity_mut.despawn();
§Array of Entitys
#[derive(Component)]
struct Position {
  x: f32,
  y: f32,
}

let mut world = World::new();
let e1 = world.spawn(Position { x: 0.0, y: 0.0 }).id();
let e2 = world.spawn(Position { x: 1.0, y: 1.0 }).id();

let [mut e1_ref, mut e2_ref] = world.entity_mut([e1, e2]);
let mut e1_position = e1_ref.get_mut::<Position>().unwrap();
e1_position.x = 1.0;
assert_eq!(e1_position.x, 1.0);
let mut e2_position = e2_ref.get_mut::<Position>().unwrap();
e2_position.x = 2.0;
assert_eq!(e2_position.x, 2.0);
§Slice of Entitys
#[derive(Component)]
struct Position {
  x: f32,
  y: f32,
}

let mut world = World::new();
let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();

let ids = vec![e1, e2, e3];
for mut eref in world.entity_mut(&ids[..]) {
    let mut pos = eref.get_mut::<Position>().unwrap();
    pos.y = 2.0;
    assert_eq!(pos.y, 2.0);
}
§EntityHashSet
#[derive(Component)]
struct Position {
  x: f32,
  y: f32,
}

let mut world = World::new();
let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();

let ids = EntityHashSet::from_iter([e1, e2, e3]);
for (_id, mut eref) in world.entity_mut(&ids) {
    let mut pos = eref.get_mut::<Position>().unwrap();
    pos.y = 2.0;
    assert_eq!(pos.y, 2.0);
}
Examples found in repository?
examples/ecs/immutable_components.rs (line 118)
103fn demo_2(world: &mut World) {
104    // Setup our name index
105    world.init_resource::<NameIndex>();
106
107    // Spawn some entities!
108    let alyssa = world.spawn(Name("Alyssa")).id();
109    let javier = world.spawn(Name("Javier")).id();
110
111    // Check our index
112    let index = world.resource::<NameIndex>();
113
114    assert_eq!(index.get_entity("Alyssa"), Some(alyssa));
115    assert_eq!(index.get_entity("Javier"), Some(javier));
116
117    // Changing the name of an entity is also fully capture by our index
118    world.entity_mut(javier).insert(Name("Steven"));
119
120    // Javier changed their name to Steven
121    let steven = javier;
122
123    // Check our index
124    let index = world.resource::<NameIndex>();
125
126    assert_eq!(index.get_entity("Javier"), None);
127    assert_eq!(index.get_entity("Steven"), Some(steven));
128}
More examples
Hide additional examples
examples/gltf/gltf_extension_animation_graph.rs (line 278)
257    fn on_scene_completed(
258        &mut self,
259        load_context: &mut LoadContext<'_>,
260        _scene: &gltf::Scene,
261        _world_root_id: Entity,
262        world: &mut World,
263    ) {
264        // Create an AnimationGraph from the desired clip
265        let (graph, index) = AnimationGraph::from_clip(self.clip.clone().unwrap());
266        // Store the animation graph as an asset with an arbitrary label
267        // We only have one graph, so this label will be unique
268        let graph_handle =
269            load_context.add_labeled_asset("MyAnimationGraphLabel".to_string(), graph);
270
271        // Create a component that stores a reference to our animation
272        let animation_to_play = AnimationToPlay {
273            graph_handle,
274            index,
275        };
276
277        // Insert the `AnimationToPlay` component on the first animation root
278        let mut entity = world.entity_mut(*self.animation_root_entities.iter().next().unwrap());
279        entity.insert(animation_to_play);
280    }
examples/async_tasks/async_compute.rs (line 100)
66fn spawn_tasks(mut commands: Commands) {
67    let thread_pool = AsyncComputeTaskPool::get();
68    for x in 0..NUM_CUBES {
69        for y in 0..NUM_CUBES {
70            for z in 0..NUM_CUBES {
71                // Spawn new task on the AsyncComputeTaskPool; the task will be
72                // executed in the background, and the Task future returned by
73                // spawn() can be used to poll for the result
74                let entity = commands.spawn_empty().id();
75                let task = thread_pool.spawn(async move {
76                    let duration = Duration::from_secs_f32(rand::rng().random_range(0.05..5.0));
77
78                    // Pretend this is a time-intensive function. :)
79                    Delay::new(duration).await;
80
81                    // Such hard work, all done!
82                    let transform = Transform::from_xyz(x as f32, y as f32, z as f32);
83                    let mut command_queue = CommandQueue::default();
84
85                    // we use a raw command queue to pass a FnOnce(&mut World) back to be
86                    // applied in a deferred manner.
87                    command_queue.push(move |world: &mut World| {
88                        let (box_mesh_handle, box_material_handle) = {
89                            let mut system_state = SystemState::<(
90                                Res<BoxMeshHandle>,
91                                Res<BoxMaterialHandle>,
92                            )>::new(world);
93                            let (box_mesh_handle, box_material_handle) =
94                                system_state.get_mut(world).unwrap();
95
96                            (box_mesh_handle.clone(), box_material_handle.clone())
97                        };
98
99                        world
100                            .entity_mut(entity)
101                            // Add our new `Mesh3d` and `MeshMaterial3d` to our tagged entity
102                            .insert((
103                                Mesh3d(box_mesh_handle),
104                                MeshMaterial3d(box_material_handle),
105                                transform,
106                            ));
107                    });
108
109                    command_queue
110                });
111
112                // Add our new task as a component
113                commands.entity(entity).insert(ComputeTransform(task));
114            }
115        }
116    }
117}
Source

pub fn inspect_entity( &self, entity: Entity, ) -> Result<impl Iterator<Item = &ComponentInfo>, EntityNotSpawnedError>

Returns the components of an Entity through ComponentInfo.

Source

pub fn get_entity<F>( &self, entities: F, ) -> Result<<F as WorldEntityFetch>::Ref<'_>, EntityNotSpawnedError>

Returns EntityRefs that expose read-only operations for the given entities, returning Err if any of the given entities do not exist. Instead of immediately unwrapping the value returned from this function, prefer World::entity.

This function supports fetching a single entity or multiple entities:

§Errors

If any of the given entities do not exist in the world, the first Entity found to be missing will return an EntityNotSpawnedError.

§Examples

For examples, see World::entity.

Source

pub fn get_entity_mut<F>( &mut self, entities: F, ) -> Result<<F as WorldEntityFetch>::Mut<'_>, EntityMutableFetchError>

Returns EntityMuts that expose read and write operations for the given entities, returning Err if any of the given entities do not exist. Instead of immediately unwrapping the value returned from this function, prefer World::entity_mut.

This function supports fetching a single entity or multiple entities:

In order to perform structural changes on the returned entity reference, such as adding or removing components, or despawning the entity, only a single Entity can be passed to this function. Allowing multiple entities at the same time with structural access would lead to undefined behavior, so EntityMut is returned when requesting multiple entities.

§Errors
§Examples

For examples, see World::entity_mut.

Examples found in repository?
examples/no_std/library/src/lib.rs (line 129)
128fn unwrap<B: Bundle>(event: On<Unwrap>, world: &mut World) {
129    if let Ok(mut target) = world.get_entity_mut(event.event_target())
130        && let Some(DelayedComponent(bundle)) = target.take::<DelayedComponent<B>>()
131    {
132        target.insert(bundle);
133    }
134
135    world.despawn(event.observer());
136}
Source

pub fn iter_entities(&self) -> impl Iterator<Item = EntityRef<'_>>

Returns an Entity iterator of current entities.

This is useful in contexts where you only have immutable access to the World. If you have mutable access to the World, use query()::<EntityRef>().iter(&world) instead.

Note that this does iterate through all entities, including resource entities.

Source

pub fn entities_and_commands(&mut self) -> (EntityFetcher<'_>, Commands<'_, '_>)

Simultaneously provides access to entity data and a command queue, which will be applied when the world is next flushed.

This allows using borrowed entity data to construct commands where the borrow checker would otherwise prevent it.

See DeferredWorld::entities_and_commands for the deferred version.

§Example
#[derive(Component)]
struct Targets(Vec<Entity>);
#[derive(Component)]
struct TargetedBy(Entity);

let mut world: World = // ...
let (entities, mut commands) = world.entities_and_commands();

let entity = entities.get(eid).unwrap();
for &target in entity.get::<Targets>().unwrap().0.iter() {
    commands.entity(target).insert(TargetedBy(eid));
}
Source

pub fn spawn_at<B>( &mut self, entity: Entity, bundle: B, ) -> Result<EntityWorldMut<'_>, SpawnError>
where B: Bundle,

Spawns the bundle on the valid but not spawned entity. If the entity can not be spawned for any reason, returns an error.

If it succeeds, this declares the entity to have this bundle.

In general, you should prefer spawn. Spawn internally calls this method, but it takes care of finding a suitable Entity for you. This is made available for advanced use, which you can see at EntityAllocator::alloc.

§Risk

It is possible to spawn an entity that has not been allocated yet; however, doing so is currently a bad idea as the allocator may hand out this entity index in the future, assuming it to be not spawned. This would cause a panic.

Manual spawning is a powerful tool, but must be used carefully.

§Example

Currently, this is primarily used to spawn entities that come from EntityAllocator::alloc. See that for an example.

Source

pub fn spawn_empty_at( &mut self, entity: Entity, ) -> Result<EntityWorldMut<'_>, SpawnError>

A faster version of spawn_at for the empty bundle.

Examples found in repository?
examples/ecs/error_handling.rs (line 164)
151fn failing_system(world: &mut World) -> Result {
152    world
153        // `get_resource` returns an `Option<T>`, so we use `ok_or` to convert it to a `Result` on
154        // which we can call `?` to propagate the error.
155        .get_resource::<UninitializedResource>()
156        // We can provide a `str` here because `BevyError` implements `From<&str>`.
157        .ok_or("Resource not initialized")
158        // The default error severity is Severity::Panic.
159        // We can add a Severity level to any Result locally to downgrade it appropriately.
160        .with_severity(Severity::Warning)?;
161
162    world
163        // This entity doesn't exist!
164        .spawn_empty_at(Entity::from_raw_u32(12345678).unwrap())
165        .map_severity(|e| match e {
166            // Not that concerning, we just need to make sure to find a different entity
167            SpawnError::AlreadySpawned => Severity::Debug,
168            // Oh no
169            SpawnError::Invalid(_) => Severity::Error,
170        })?;
171
172    Ok(())
173}
Source

pub fn spawn<B>(&mut self, bundle: B) -> EntityWorldMut<'_>
where B: Bundle,

Spawns a new Entity with a given Bundle of components and returns a corresponding EntityWorldMut, which can be used to add components to the entity or retrieve its id. In case large batches of entities need to be spawned, consider using World::spawn_batch instead.

use bevy_ecs::{bundle::Bundle, component::Component, world::World};

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

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

#[derive(Component)]
struct Name(&'static str);

#[derive(Bundle)]
struct PhysicsBundle {
    position: Position,
    velocity: Velocity,
}

let mut world = World::new();

// `spawn` can accept a single component:
world.spawn(Position { x: 0.0, y: 0.0 });

// It can also accept a tuple of components:
world.spawn((
    Position { x: 0.0, y: 0.0 },
    Velocity { x: 1.0, y: 1.0 },
));

// Or it can accept a pre-defined Bundle of components:
world.spawn(PhysicsBundle {
    position: Position { x: 2.0, y: 2.0 },
    velocity: Velocity { x: 0.0, y: 4.0 },
});

let entity = world
    // Tuples can also mix Bundles and Components
    .spawn((
        PhysicsBundle {
            position: Position { x: 2.0, y: 2.0 },
            velocity: Velocity { x: 0.0, y: 4.0 },
        },
        Name("Elaina Proctor"),
    ))
    // Calling id() will return the unique identifier for the spawned entity
    .id();
let position = world.entity(entity).get::<Position>().unwrap();
assert_eq!(position.x, 2.0);
Examples found in repository?
examples/app/externally_driven_headless_renderer.rs (line 100)
96    fn spawn_camera(&mut self, target: RenderTarget) -> Entity {
97        self.0
98            .main
99            .world_mut()
100            .spawn((Camera3d::default(), target, Transform::IDENTITY))
101            .id()
102    }
103
104    // Run one world update and wait for rendering to finish.
105    fn update(&mut self) {
106        self.0.update();
107        // Wait for frame to finish rendering by wait polling the device
108        self.0
109            .main
110            .world()
111            .resource::<RenderDevice>()
112            .wgpu_device()
113            .poll(PollType::Wait {
114                submission_index: None,
115                timeout: None,
116            })
117            .unwrap();
118    }
119
120    // Schedules a screenshot to be captured on the next update.
121    fn screenshot(&mut self, target: RenderTarget, i: u32) {
122        self.0
123            .main
124            .world_mut()
125            .spawn(Screenshot::image(target.as_image().unwrap().clone()))
126            .observe(save_to_disk(format!("test_images/screenshot{i}.png")));
127    }
More examples
Hide additional examples
examples/ecs/one_shot_systems.rs (line 52)
47fn setup_with_world(world: &mut World) {
48    // We can run it once manually
49    world.run_system_once(system_b).unwrap();
50    // Or with a Callback
51    let system_id = world.register_system(system_b);
52    world.spawn((Callback(system_id), B));
53}
examples/ecs/ecs_guide.rs (lines 255-261)
244fn exclusive_player_system(world: &mut World) {
245    // this does the same thing as "new_player_system"
246    let total_players = world.resource_mut::<GameState>().total_players;
247    let should_add_player = {
248        let game_rules = world.resource::<GameRules>();
249        let add_new_player = random::<bool>();
250        add_new_player && total_players < game_rules.max_players
251    };
252    // Randomly add a new player
253    if should_add_player {
254        println!("Player {} has joined the game!", total_players + 1);
255        world.spawn((
256            Player {
257                name: format!("Player {}", total_players + 1),
258            },
259            Score { value: 0 },
260            PlayerStreak::None,
261        ));
262
263        let mut game_state = world.resource_mut::<GameState>();
264        game_state.total_players += 1;
265    }
266}
examples/ecs/immutable_components.rs (line 32)
30fn demo_1(world: &mut World) {
31    // Immutable components can be inserted just like mutable components.
32    let mut entity = world.spawn((MyMutableComponent(false), MyImmutableComponent(false)));
33
34    // But where mutable components can be mutated...
35    let mut my_mutable_component = entity.get_mut::<MyMutableComponent>().unwrap();
36    my_mutable_component.0 = true;
37
38    // ...immutable ones cannot. The below fails to compile as `MyImmutableComponent`
39    // is declared as immutable.
40    // let mut my_immutable_component = entity.get_mut::<MyImmutableComponent>().unwrap();
41
42    // Instead, you could take or replace the immutable component to update its value.
43    let mut my_immutable_component = entity.take::<MyImmutableComponent>().unwrap();
44    my_immutable_component.0 = true;
45    entity.insert(my_immutable_component);
46}
47
48/// This is an example of a component like [`Name`](bevy::prelude::Name), but immutable.
49#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Component, Reflect)]
50#[reflect(Hash, Component)]
51#[component(
52    immutable,
53    // Since this component is immutable, we can fully capture all mutations through
54    // these component hooks. This allows for keeping other parts of the ECS synced
55    // to a component's value at all times.
56    on_insert = on_insert_name,
57    on_discard = on_discard_name,
58)]
59pub struct Name(pub &'static str);
60
61/// This index allows for O(1) lookups of an [`Entity`] by its [`Name`].
62#[derive(Resource, Default)]
63struct NameIndex {
64    name_to_entity: HashMap<Name, Entity>,
65}
66
67impl NameIndex {
68    fn get_entity(&self, name: &'static str) -> Option<Entity> {
69        self.name_to_entity.get(&Name(name)).copied()
70    }
71}
72
73/// When a [`Name`] is inserted, we will add it to our [`NameIndex`].
74///
75/// Since all mutations to [`Name`] are captured by hooks, we know it is not currently
76/// inserted in the index, and its value will not change without triggering a hook.
77fn on_insert_name(mut world: DeferredWorld<'_>, HookContext { entity, .. }: HookContext) {
78    let Some(&name) = world.entity(entity).get::<Name>() else {
79        unreachable!("Insert hook guarantees `Name` is available on entity")
80    };
81    let Some(mut index) = world.get_resource_mut::<NameIndex>() else {
82        return;
83    };
84
85    index.name_to_entity.insert(name, entity);
86}
87
88/// When a [`Name`] is removed or replaced, remove it from our [`NameIndex`].
89///
90/// Since all mutations to [`Name`] are captured by hooks, we know it is currently
91/// inserted in the index.
92fn on_discard_name(mut world: DeferredWorld<'_>, HookContext { entity, .. }: HookContext) {
93    let Some(&name) = world.entity(entity).get::<Name>() else {
94        unreachable!("Discard hook guarantees `Name` is available on entity")
95    };
96    let Some(mut index) = world.get_resource_mut::<NameIndex>() else {
97        return;
98    };
99
100    index.name_to_entity.remove(&name);
101}
102
103fn demo_2(world: &mut World) {
104    // Setup our name index
105    world.init_resource::<NameIndex>();
106
107    // Spawn some entities!
108    let alyssa = world.spawn(Name("Alyssa")).id();
109    let javier = world.spawn(Name("Javier")).id();
110
111    // Check our index
112    let index = world.resource::<NameIndex>();
113
114    assert_eq!(index.get_entity("Alyssa"), Some(alyssa));
115    assert_eq!(index.get_entity("Javier"), Some(javier));
116
117    // Changing the name of an entity is also fully capture by our index
118    world.entity_mut(javier).insert(Name("Steven"));
119
120    // Javier changed their name to Steven
121    let steven = javier;
122
123    // Check our index
124    let index = world.resource::<NameIndex>();
125
126    assert_eq!(index.get_entity("Javier"), None);
127    assert_eq!(index.get_entity("Steven"), Some(steven));
128}
examples/scene/world_serialization.rs (lines 179-185)
166fn save_world_system(world: &mut World) {
167    let asset_server = world.resource::<AssetServer>().clone();
168    // The `TypeRegistry` resource contains information about all registered types (including components).
169    // This is used to construct worlds, so we'll want to ensure that we use the registry from the
170    // main world. To do this, we can simply clone the `AppTypeRegistry` resource.
171    let type_registry = world.resource::<AppTypeRegistry>().clone();
172
173    // Any ECS World can be serialized.
174    // For demonstration purposes, we'll create a new one.
175    let mut scene_world = World::new();
176
177    let mut component_b = ComponentB::from_world(world);
178    component_b.value = "hello".to_string();
179    scene_world.spawn((
180        component_b,
181        ComponentA { x: 1.0, y: 2.0 },
182        Transform::IDENTITY,
183        Name::new("joe"),
184        WorldAssetRoot(asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0")),
185    ));
186    scene_world.spawn(ComponentA { x: 3.0, y: 4.0 });
187    scene_world.insert_resource(ResourceA { score: 1 });
188
189    // With our sample world ready to go, we can now create a DynamicWorld from it.
190    // For simplicity, we will create our scene using DynamicWorld directly, but if
191    // you need more control, you can use DynamicWorldBuilder.
192    let dynamic_world = DynamicWorld::from_world_with(&scene_world, &type_registry.read());
193
194    // Dynamic Worlds can be serialized like this:
195    let type_registry = world.resource::<AppTypeRegistry>();
196    let type_registry = type_registry.read();
197    let serialized_world = dynamic_world.serialize(&type_registry).unwrap();
198
199    // Shows the serialized world in the console
200    info!("{}", serialized_world);
201
202    // Writing the world to a new file. Using a task to avoid calling the filesystem APIs in a system
203    // as they are blocking.
204    //
205    // This can't work in Wasm as there is no filesystem access.
206    #[cfg(not(target_arch = "wasm32"))]
207    IoTaskPool::get()
208        .spawn(async move {
209            // Write the world RON data to file
210            File::create(format!("assets/{NEW_WORLD_FILE_PATH}"))
211                .and_then(|mut file| file.write(serialized_world.as_bytes()))
212                .expect("Error while writing world to file");
213        })
214        .detach();
215}
examples/ecs/dynamic.rs (line 250)
69fn main() {
70    let mut world = World::new();
71    let mut lines = std::io::stdin().lines();
72    let mut component_names = HashMap::<String, ComponentId>::new();
73    let mut component_info = HashMap::<ComponentId, ComponentInfo>::new();
74    let mut event_names = HashMap::<String, EventKey>::new();
75
76    println!("{PROMPT}");
77    loop {
78        print!("\n> ");
79        let _ = std::io::stdout().flush();
80        let Some(Ok(line)) = lines.next() else {
81            return;
82        };
83
84        if line.is_empty() {
85            return;
86        };
87
88        let Some((first, rest)) = line.trim().split_once(|c: char| c.is_whitespace()) else {
89            match &line.chars().next() {
90                Some('c') => println!("{COMPONENT_PROMPT}"),
91                Some('s') => println!("{ENTITY_PROMPT}"),
92                Some('q') => println!("{QUERY_PROMPT}"),
93                Some('e') => println!("{EVENT_PROMPT}"),
94                Some('t') => println!("{EMIT_PROMPT}"),
95                _ => println!("{PROMPT}"),
96            }
97            continue;
98        };
99
100        match &first[0..1] {
101            "c" => {
102                rest.split(',').for_each(|component| {
103                    let mut component = component.split_whitespace();
104                    let Some(name) = component.next() else {
105                        return;
106                    };
107                    let size = match component.next().map(str::parse) {
108                        Some(Ok(size)) => size,
109                        _ => 0,
110                    };
111                    // Register our new component to the world with a layout specified by it's size
112                    // SAFETY: [u64] is Send + Sync
113                    let id = world.register_component_with_descriptor(unsafe {
114                        ComponentDescriptor::new_with_layout(
115                            name.to_string(),
116                            StorageType::Table,
117                            Layout::array::<u64>(size).unwrap(),
118                            None,
119                            true,
120                            ComponentCloneBehavior::Default,
121                            None,
122                        )
123                    });
124                    let Some(info) = world.components().get_info(id) else {
125                        return;
126                    };
127                    component_names.insert(name.to_string(), id);
128                    component_info.insert(id, info.clone());
129                    println!("Component {} created with id: {}", name, id.index());
130                });
131            }
132            "s" => {
133                let mut to_insert_ids = Vec::new();
134                let mut to_insert_data = Vec::new();
135                rest.split(',').for_each(|component| {
136                    let mut component = component.split_whitespace();
137                    let Some(name) = component.next() else {
138                        return;
139                    };
140
141                    // Get the id for the component with the given name
142                    let Some(&id) = component_names.get(name) else {
143                        println!("Component {name} does not exist");
144                        return;
145                    };
146
147                    // Calculate the length for the array based on the layout created for this component id
148                    let info = world.components().get_info(id).unwrap();
149                    let len = info.layout().size() / size_of::<u64>();
150                    let mut values: Vec<u64> = component
151                        .take(len)
152                        .filter_map(|value| value.parse::<u64>().ok())
153                        .collect();
154                    values.resize(len, 0);
155
156                    // Collect the id and array to be inserted onto our entity
157                    to_insert_ids.push(id);
158                    to_insert_data.push(values);
159                });
160
161                let mut entity = world.spawn_empty();
162
163                // Construct an `OwningPtr` for each component in `to_insert_data`
164                let to_insert_ptr = to_owning_ptrs(&mut to_insert_data);
165
166                // SAFETY:
167                // - Component ids have been taken from the same world
168                // - Each array is created to the layout specified in the world
169                unsafe {
170                    entity.insert_by_ids(&to_insert_ids, to_insert_ptr.into_iter());
171                }
172
173                println!("Entity spawned with id: {}", entity.id());
174            }
175            "q" => {
176                let mut builder = QueryBuilder::<FilteredEntityMut>::new(&mut world);
177                parse_query(rest, &mut builder, &component_names);
178                let mut query = builder.build();
179                query.iter_mut(&mut world).for_each(|filtered_entity| {
180                    let terms = filtered_entity
181                        .access()
182                        .try_iter_access()
183                        .unwrap()
184                        .map(|component_access| {
185                            let id = *component_access.index();
186                            let ptr = filtered_entity.get_by_id(id).unwrap();
187                            let info = component_info.get(&id).unwrap();
188                            let len = info.layout().size() / size_of::<u64>();
189
190                            // SAFETY:
191                            // - All components are created with layout [u64]
192                            // - len is calculated from the component descriptor
193                            let data = unsafe {
194                                std::slice::from_raw_parts_mut(
195                                    ptr.assert_unique().as_ptr().cast::<u64>(),
196                                    len,
197                                )
198                            };
199
200                            // If we have write access, increment each value once
201                            if matches!(component_access, ComponentAccessKind::Exclusive(_)) {
202                                data.iter_mut().for_each(|data| {
203                                    *data += 1;
204                                });
205                            }
206
207                            format!("{}: {:?}", info.name(), data[0..len].to_vec())
208                        })
209                        .collect::<Vec<_>>()
210                        .join(", ");
211
212                    println!("{}: {}", filtered_entity.id(), terms);
213                });
214            }
215            "e" => {
216                rest.split(',').for_each(|event| {
217                    let name = event.trim();
218                    if name.is_empty() {
219                        return;
220                    }
221
222                    // Register a ComponentId for this event, no Rust type needed.
223                    // SAFETY: ZST with no drop
224                    let event_component_id = world.register_component_with_descriptor(unsafe {
225                        ComponentDescriptor::new_with_layout(
226                            format!("event:{name}"),
227                            StorageType::Table,
228                            Layout::new::<()>(),
229                            None,
230                            false,
231                            ComponentCloneBehavior::Ignore,
232                            None,
233                        )
234                    });
235                    // SAFETY: event_component_id was just registered for this event
236                    let event_key = unsafe { EventKey::new(event_component_id) };
237                    event_names.insert(name.to_string(), event_key);
238
239                    // Build a dynamic observer that prints when the event fires.
240                    let runner: ObserverRunner = |mut world, _observer, ctx, _event, _trigger| {
241                        println!("  Observer fired!");
242                        if let Some(mut counts) = world.get_resource_mut::<EventFireCount>() {
243                            *counts.0.entry(ctx.event_key).or_insert(0) += 1;
244                        }
245                    };
246
247                    // SAFETY: event_key was just registered, runner ignores pointers
248                    let observer =
249                        unsafe { Observer::with_dynamic_runner(runner).with_event_key(event_key) };
250                    world.spawn(observer);
251
252                    println!(
253                        "Event '{name}' registered (key: {}) with a dynamic observer",
254                        event_component_id.index()
255                    );
256                });
257
258                // Ensure the counter resource exists.
259                world.init_resource::<EventFireCount>();
260            }
261            "t" => {
262                let name = rest.trim();
263                let Some(&event_key) = event_names.get(name) else {
264                    println!(
265                        "Event '{name}' does not exist. Register it first with 'event {name}'"
266                    );
267                    continue;
268                };
269
270                let mut event_data = ();
271                let mut trigger_data = ();
272                // SAFETY: event_key was registered in this world, both pointers are valid ZSTs
273                unsafe {
274                    world.trigger_dynamic(
275                        event_key,
276                        PtrMut::from(&mut event_data),
277                        PtrMut::from(&mut trigger_data),
278                    );
279                }
280
281                let count = world
282                    .get_resource::<EventFireCount>()
283                    .map_or(0, |c| c.0.get(&event_key).copied().unwrap_or(0));
284                println!("Event '{name}' triggered ({count} fires)");
285            }
286            _ => continue,
287        }
288    }
289}
Source

pub fn spawn_empty(&mut self) -> EntityWorldMut<'_>

Spawns a new Entity and returns a corresponding EntityWorldMut, which can be used to add components to the entity or retrieve its id.

use bevy_ecs::{component::Component, world::World};

#[derive(Component)]
struct Position {
  x: f32,
  y: f32,
}
#[derive(Component)]
struct Label(&'static str);
#[derive(Component)]
struct Num(u32);

let mut world = World::new();
let entity = world.spawn_empty()
    .insert(Position { x: 0.0, y: 0.0 }) // add a single component
    .insert((Num(1), Label("hello"))) // add a bundle of components
    .id();

let position = world.entity(entity).get::<Position>().unwrap();
assert_eq!(position.x, 0.0);
Examples found in repository?
examples/ecs/immutable_components.rs (line 171)
135fn demo_3(world: &mut World) {
136    // This is a list of dynamic components we will create.
137    // The first item is the name of the component, and the second is the size
138    // in bytes.
139    let my_dynamic_components = [("Foo", 1), ("Bar", 2), ("Baz", 4)];
140
141    // This pipeline takes our component descriptions, registers them, and gets
142    // their ComponentId's.
143    let my_registered_components = my_dynamic_components
144        .into_iter()
145        .map(|(name, size)| {
146            // SAFETY:
147            // - No drop command is required
148            // - The component will store [u8; size], which is Send + Sync
149            let descriptor = unsafe {
150                ComponentDescriptor::new_with_layout(
151                    name.to_string(),
152                    StorageType::Table,
153                    Layout::array::<u8>(size).unwrap(),
154                    None,
155                    false,
156                    ComponentCloneBehavior::Default,
157                    None,
158                )
159            };
160
161            (name, size, descriptor)
162        })
163        .map(|(name, size, descriptor)| {
164            let component_id = world.register_component_with_descriptor(descriptor);
165
166            (name, size, component_id)
167        })
168        .collect::<Vec<(&str, usize, ComponentId)>>();
169
170    // Now that our components are registered, let's add them to an entity
171    let mut entity = world.spawn_empty();
172
173    for (_name, size, component_id) in &my_registered_components {
174        // We're just storing some zeroes for the sake of demonstration.
175        let data = core::iter::repeat_n(0, *size).collect::<Vec<u8>>();
176
177        OwningPtr::make(data, |ptr| {
178            // SAFETY:
179            // - ComponentId has been taken from the same world
180            // - Array is created to the layout specified in the world
181            unsafe {
182                entity.insert_by_id(*component_id, ptr);
183            }
184        });
185    }
186
187    for (_name, _size, component_id) in &my_registered_components {
188        // With immutable components, we can read the values...
189        assert!(entity.get_by_id(*component_id).is_ok());
190
191        // ...but we cannot gain a mutable reference.
192        assert!(entity.get_mut_by_id(*component_id).is_err());
193
194        // Instead, you must either remove or replace the value.
195    }
196}
More examples
Hide additional examples
examples/stress_tests/many_components.rs (line 135)
78fn stress_test(num_entities: u32, num_components: u32, num_systems: u32) {
79    let mut rng = ChaCha8Rng::seed_from_u64(42);
80    let mut app = App::default();
81    let world = app.world_mut();
82
83    // register a bunch of components
84    let component_ids: Vec<ComponentId> = (1..=num_components)
85        .map(|i| {
86            world.register_component_with_descriptor(
87                // SAFETY:
88                // * We don't implement a drop function
89                // * u8 is Sync and Send
90                unsafe {
91                    ComponentDescriptor::new_with_layout(
92                        format!("Component{i}").to_string(),
93                        StorageType::Table,
94                        Layout::new::<u8>(),
95                        None,
96                        true, // is mutable
97                        ComponentCloneBehavior::Default,
98                        None,
99                    )
100                },
101            )
102        })
103        .collect();
104
105    // fill the schedule with systems
106    let mut schedule = Schedule::new(Update);
107    for _ in 1..=num_systems {
108        let num_access_components = rng.random_range(1..10);
109        let access_components: Vec<ComponentId> = component_ids
110            .sample(&mut rng, num_access_components)
111            .copied()
112            .collect();
113        let system = (QueryParamBuilder::new(|builder| {
114            for &access_component in &access_components {
115                if rand::random::<bool>() {
116                    builder.mut_id(access_component);
117                } else {
118                    builder.ref_id(access_component);
119                }
120            }
121        }),)
122            .build_state(world)
123            .build_any_system(base_system);
124        schedule.add_systems((move || access_components.clone()).pipe(system));
125    }
126
127    // spawn a bunch of entities
128    for _ in 1..=num_entities {
129        let num_components = rng.random_range(1..10);
130        let components: Vec<ComponentId> = component_ids
131            .sample(&mut rng, num_components)
132            .copied()
133            .collect();
134
135        let mut entity = world.spawn_empty();
136        // We use `ManuallyDrop` here as we need to avoid dropping the u8's when `values` is dropped
137        // since ownership of the values is passed to the world in `insert_by_ids`.
138        // But we do want to deallocate the memory when values is dropped.
139        let mut values: Vec<ManuallyDrop<u8>> = components
140            .iter()
141            .map(|_id| ManuallyDrop::new(rng.random_range(0..255)))
142            .collect();
143        let ptrs: Vec<OwningPtr> = values
144            .iter_mut()
145            .map(|value| {
146                // SAFETY:
147                // * We don't read/write `values` binding after this and values are `ManuallyDrop`,
148                // so we have the right to drop/move the values
149                unsafe { PtrMut::from(value).promote() }
150            })
151            .collect();
152        // SAFETY:
153        // * component_id's are from the same world
154        // * `values` was initialized above, so references are valid
155        unsafe {
156            entity.insert_by_ids(&components, ptrs.into_iter());
157        }
158    }
159
160    // overwrite Update schedule in the app
161    app.add_schedule(schedule);
162    app.add_plugins(MinimalPlugins)
163        .add_plugins(DiagnosticsPlugin)
164        .add_plugins(LogPlugin::default())
165        .add_plugins(FrameTimeDiagnosticsPlugin::default())
166        .add_plugins(LogDiagnosticsPlugin::filtered(HashSet::from_iter([
167            DiagnosticPath::new("fps"),
168        ])));
169    app.run();
170}
examples/ecs/dynamic.rs (line 161)
69fn main() {
70    let mut world = World::new();
71    let mut lines = std::io::stdin().lines();
72    let mut component_names = HashMap::<String, ComponentId>::new();
73    let mut component_info = HashMap::<ComponentId, ComponentInfo>::new();
74    let mut event_names = HashMap::<String, EventKey>::new();
75
76    println!("{PROMPT}");
77    loop {
78        print!("\n> ");
79        let _ = std::io::stdout().flush();
80        let Some(Ok(line)) = lines.next() else {
81            return;
82        };
83
84        if line.is_empty() {
85            return;
86        };
87
88        let Some((first, rest)) = line.trim().split_once(|c: char| c.is_whitespace()) else {
89            match &line.chars().next() {
90                Some('c') => println!("{COMPONENT_PROMPT}"),
91                Some('s') => println!("{ENTITY_PROMPT}"),
92                Some('q') => println!("{QUERY_PROMPT}"),
93                Some('e') => println!("{EVENT_PROMPT}"),
94                Some('t') => println!("{EMIT_PROMPT}"),
95                _ => println!("{PROMPT}"),
96            }
97            continue;
98        };
99
100        match &first[0..1] {
101            "c" => {
102                rest.split(',').for_each(|component| {
103                    let mut component = component.split_whitespace();
104                    let Some(name) = component.next() else {
105                        return;
106                    };
107                    let size = match component.next().map(str::parse) {
108                        Some(Ok(size)) => size,
109                        _ => 0,
110                    };
111                    // Register our new component to the world with a layout specified by it's size
112                    // SAFETY: [u64] is Send + Sync
113                    let id = world.register_component_with_descriptor(unsafe {
114                        ComponentDescriptor::new_with_layout(
115                            name.to_string(),
116                            StorageType::Table,
117                            Layout::array::<u64>(size).unwrap(),
118                            None,
119                            true,
120                            ComponentCloneBehavior::Default,
121                            None,
122                        )
123                    });
124                    let Some(info) = world.components().get_info(id) else {
125                        return;
126                    };
127                    component_names.insert(name.to_string(), id);
128                    component_info.insert(id, info.clone());
129                    println!("Component {} created with id: {}", name, id.index());
130                });
131            }
132            "s" => {
133                let mut to_insert_ids = Vec::new();
134                let mut to_insert_data = Vec::new();
135                rest.split(',').for_each(|component| {
136                    let mut component = component.split_whitespace();
137                    let Some(name) = component.next() else {
138                        return;
139                    };
140
141                    // Get the id for the component with the given name
142                    let Some(&id) = component_names.get(name) else {
143                        println!("Component {name} does not exist");
144                        return;
145                    };
146
147                    // Calculate the length for the array based on the layout created for this component id
148                    let info = world.components().get_info(id).unwrap();
149                    let len = info.layout().size() / size_of::<u64>();
150                    let mut values: Vec<u64> = component
151                        .take(len)
152                        .filter_map(|value| value.parse::<u64>().ok())
153                        .collect();
154                    values.resize(len, 0);
155
156                    // Collect the id and array to be inserted onto our entity
157                    to_insert_ids.push(id);
158                    to_insert_data.push(values);
159                });
160
161                let mut entity = world.spawn_empty();
162
163                // Construct an `OwningPtr` for each component in `to_insert_data`
164                let to_insert_ptr = to_owning_ptrs(&mut to_insert_data);
165
166                // SAFETY:
167                // - Component ids have been taken from the same world
168                // - Each array is created to the layout specified in the world
169                unsafe {
170                    entity.insert_by_ids(&to_insert_ids, to_insert_ptr.into_iter());
171                }
172
173                println!("Entity spawned with id: {}", entity.id());
174            }
175            "q" => {
176                let mut builder = QueryBuilder::<FilteredEntityMut>::new(&mut world);
177                parse_query(rest, &mut builder, &component_names);
178                let mut query = builder.build();
179                query.iter_mut(&mut world).for_each(|filtered_entity| {
180                    let terms = filtered_entity
181                        .access()
182                        .try_iter_access()
183                        .unwrap()
184                        .map(|component_access| {
185                            let id = *component_access.index();
186                            let ptr = filtered_entity.get_by_id(id).unwrap();
187                            let info = component_info.get(&id).unwrap();
188                            let len = info.layout().size() / size_of::<u64>();
189
190                            // SAFETY:
191                            // - All components are created with layout [u64]
192                            // - len is calculated from the component descriptor
193                            let data = unsafe {
194                                std::slice::from_raw_parts_mut(
195                                    ptr.assert_unique().as_ptr().cast::<u64>(),
196                                    len,
197                                )
198                            };
199
200                            // If we have write access, increment each value once
201                            if matches!(component_access, ComponentAccessKind::Exclusive(_)) {
202                                data.iter_mut().for_each(|data| {
203                                    *data += 1;
204                                });
205                            }
206
207                            format!("{}: {:?}", info.name(), data[0..len].to_vec())
208                        })
209                        .collect::<Vec<_>>()
210                        .join(", ");
211
212                    println!("{}: {}", filtered_entity.id(), terms);
213                });
214            }
215            "e" => {
216                rest.split(',').for_each(|event| {
217                    let name = event.trim();
218                    if name.is_empty() {
219                        return;
220                    }
221
222                    // Register a ComponentId for this event, no Rust type needed.
223                    // SAFETY: ZST with no drop
224                    let event_component_id = world.register_component_with_descriptor(unsafe {
225                        ComponentDescriptor::new_with_layout(
226                            format!("event:{name}"),
227                            StorageType::Table,
228                            Layout::new::<()>(),
229                            None,
230                            false,
231                            ComponentCloneBehavior::Ignore,
232                            None,
233                        )
234                    });
235                    // SAFETY: event_component_id was just registered for this event
236                    let event_key = unsafe { EventKey::new(event_component_id) };
237                    event_names.insert(name.to_string(), event_key);
238
239                    // Build a dynamic observer that prints when the event fires.
240                    let runner: ObserverRunner = |mut world, _observer, ctx, _event, _trigger| {
241                        println!("  Observer fired!");
242                        if let Some(mut counts) = world.get_resource_mut::<EventFireCount>() {
243                            *counts.0.entry(ctx.event_key).or_insert(0) += 1;
244                        }
245                    };
246
247                    // SAFETY: event_key was just registered, runner ignores pointers
248                    let observer =
249                        unsafe { Observer::with_dynamic_runner(runner).with_event_key(event_key) };
250                    world.spawn(observer);
251
252                    println!(
253                        "Event '{name}' registered (key: {}) with a dynamic observer",
254                        event_component_id.index()
255                    );
256                });
257
258                // Ensure the counter resource exists.
259                world.init_resource::<EventFireCount>();
260            }
261            "t" => {
262                let name = rest.trim();
263                let Some(&event_key) = event_names.get(name) else {
264                    println!(
265                        "Event '{name}' does not exist. Register it first with 'event {name}'"
266                    );
267                    continue;
268                };
269
270                let mut event_data = ();
271                let mut trigger_data = ();
272                // SAFETY: event_key was registered in this world, both pointers are valid ZSTs
273                unsafe {
274                    world.trigger_dynamic(
275                        event_key,
276                        PtrMut::from(&mut event_data),
277                        PtrMut::from(&mut trigger_data),
278                    );
279                }
280
281                let count = world
282                    .get_resource::<EventFireCount>()
283                    .map_or(0, |c| c.0.get(&event_key).copied().unwrap_or(0));
284                println!("Event '{name}' triggered ({count} fires)");
285            }
286            _ => continue,
287        }
288    }
289}
Source

pub fn spawn_batch<I>( &mut self, iter: I, ) -> SpawnBatchIter<'_, <I as IntoIterator>::IntoIter>

Spawns a batch of entities with the same component Bundle type. Takes a given Bundle iterator and returns a corresponding Entity iterator. This is more efficient than spawning entities and adding components to them individually using World::spawn, but it is limited to spawning entities with the same Bundle type, whereas spawning individually is more flexible.

use bevy_ecs::{component::Component, entity::Entity, world::World};

#[derive(Component)]
struct Str(&'static str);
#[derive(Component)]
struct Num(u32);

let mut world = World::new();
let entities = world.spawn_batch(vec![
  (Str("a"), Num(0)), // the first entity
  (Str("b"), Num(1)), // the second entity
]).collect::<Vec<Entity>>();

assert_eq!(entities.len(), 2);
Source

pub fn get<T>(&self, entity: Entity) -> Option<&T>
where T: Component,

Retrieves a reference to the given entity’s Component of the given type. Returns None if the entity does not have a Component of the given type.

use bevy_ecs::{component::Component, world::World};

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

let mut world = World::new();
let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
let position = world.get::<Position>(entity).unwrap();
assert_eq!(position.x, 0.0);
Examples found in repository?
examples/ecs/component_hooks.rs (line 86)
61fn setup(world: &mut World) {
62    // In order to register component hooks the component must:
63    // - not be currently in use by any entities in the world
64    // - not already have a hook of that kind registered
65    // This is to prevent overriding hooks defined in plugins and other crates as well as keeping things fast
66    world
67        .register_component_hooks::<MyComponent>()
68        // There are 4 component lifecycle hooks: `on_add`, `on_insert`, `on_discard` and `on_remove`
69        // A hook has 2 arguments:
70        // - a `DeferredWorld`, this allows access to resource and component data as well as `Commands`
71        // - a `HookContext`, this provides access to the following contextual information:
72        //   - the entity that triggered the hook
73        //   - the component id of the triggering component, this is mostly used for dynamic components
74        //   - the location of the code that caused the hook to trigger
75        //
76        // `on_add` will trigger when a component is inserted onto an entity without it
77        .on_add(
78            |mut world,
79             HookContext {
80                 entity,
81                 component_id,
82                 caller,
83                 ..
84             }| {
85                // You can access component data from within the hook
86                let value = world.get::<MyComponent>(entity).unwrap().0;
87                println!(
88                    "{component_id:?} added to {entity} with value {value:?}{}",
89                    caller
90                        .map(|location| format!("due to {location}"))
91                        .unwrap_or_default()
92                );
93                // Or access resources
94                world
95                    .resource_mut::<MyComponentIndex>()
96                    .insert(value, entity);
97                // Or send messages
98                world.write_message(MyMessage);
99            },
100        )
101        // `on_insert` will trigger when a component is inserted onto an entity,
102        // regardless of whether or not it already had it and after `on_add` if it ran
103        .on_insert(|world, _| {
104            println!("Current Index: {:?}", world.resource::<MyComponentIndex>());
105        })
106        // `on_discard` will trigger when a component is inserted onto an entity that already had it,
107        // and runs before the value is replaced.
108        // Also triggers when a component is removed from an entity, and runs before `on_remove`
109        .on_discard(|mut world, context| {
110            let value = world.get::<MyComponent>(context.entity).unwrap().0;
111            world.resource_mut::<MyComponentIndex>().remove(&value);
112        })
113        // `on_remove` will trigger when a component is removed from an entity,
114        // since it runs before the component is removed you can still access the component data
115        .on_remove(
116            |mut world,
117             HookContext {
118                 entity,
119                 component_id,
120                 caller,
121                 ..
122             }| {
123                let value = world.get::<MyComponent>(entity).unwrap().0;
124                println!(
125                    "{component_id:?} removed from {entity} with value {value:?}{}",
126                    caller
127                        .map(|location| format!("due to {location}"))
128                        .unwrap_or_default()
129                );
130                // You can also issue commands through `.commands()`
131                world.commands().entity(entity).despawn();
132            },
133        );
134}
Source

pub fn get_mut<T>(&mut self, entity: Entity) -> Option<Mut<'_, T>>
where T: Component<Mutability = Mutable>,

Retrieves a mutable reference to the given entity’s Component of the given type. Returns None if the entity does not have a Component of the given type.

use bevy_ecs::{component::Component, world::World};

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

let mut world = World::new();
let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
let mut position = world.get_mut::<Position>(entity).unwrap();
position.x = 1.0;
Source

pub fn modify_component<T, R>( &mut self, entity: Entity, f: impl FnOnce(&mut T) -> R, ) -> Result<Option<R>, EntityMutableFetchError>
where T: Component,

Temporarily removes a Component T from the provided Entity and runs the provided closure on it, returning the result if T was available. This will trigger the Remove and Discard component hooks without causing an archetype move.

This is most useful with immutable components, where removal and reinsertion is the only way to modify a value.

If you do not need to ensure the above hooks are triggered, and your component is mutable, prefer using get_mut.

§Examples
#[derive(Component, PartialEq, Eq, Debug)]
#[component(immutable)]
struct Foo(bool);

world.modify_component(entity, |foo: &mut Foo| {
    foo.0 = true;
});
Source

pub fn modify_component_by_id<R>( &mut self, entity: Entity, component_id: ComponentId, f: impl for<'a> FnOnce(MutUntyped<'a>) -> R, ) -> Result<Option<R>, EntityMutableFetchError>

Temporarily removes a Component identified by the provided ComponentId from the provided Entity and runs the provided closure on it, returning the result if the component was available. This will trigger the Remove and Discard component hooks without causing an archetype move.

This is most useful with immutable components, where removal and reinsertion is the only way to modify a value.

If you do not need to ensure the above hooks are triggered, and your component is mutable, prefer using get_mut_by_id.

You should prefer the typed modify_component whenever possible.

Source

pub fn despawn(&mut self, entity: Entity) -> bool

Despawns the given Entity, if it exists. This will also remove all of the entity’s Components.

Returns true if the entity is successfully despawned and false if the entity does not exist. This counts despawning a not constructed entity as a success, and frees it to the allocator. See entity module docs for more about construction.

§Note

This will also despawn the entities in any RelationshipTarget that is configured to despawn descendants. For example, this will recursively despawn Children.

use bevy_ecs::{component::Component, world::World};

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

let mut world = World::new();
let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
assert!(world.despawn(entity));
assert!(world.get_entity(entity).is_err());
assert!(world.get::<Position>(entity).is_none());
Examples found in repository?
examples/no_std/library/src/lib.rs (line 135)
128fn unwrap<B: Bundle>(event: On<Unwrap>, world: &mut World) {
129    if let Ok(mut target) = world.get_entity_mut(event.event_target())
130        && let Some(DelayedComponent(bundle)) = target.take::<DelayedComponent<B>>()
131    {
132        target.insert(bundle);
133    }
134
135    world.despawn(event.observer());
136}
Source

pub fn try_despawn(&mut self, entity: Entity) -> Result<(), EntityDespawnError>

Despawns the given entity, if it exists. This will also remove all of the entity’s Components.

Returns an EntityDespawnError if the entity is not spawned to be despawned.

§Note

This will also despawn the entities in any RelationshipTarget that is configured to despawn descendants. For example, this will recursively despawn Children.

Source

pub fn despawn_no_free(&mut self, entity: Entity) -> Option<Entity>

Performs try_despawn_no_free, warning on errors. See that method for more information.

Source

pub fn try_despawn_no_free( &mut self, entity: Entity, ) -> Result<Entity, EntityDespawnError>

Despawns the given entity, if it exists. This will also remove all of the entity’s Components.

The only difference between this and despawning an entity is that this does not release the entity to be reused. It is up to the caller to either re-spawn or free the entity; otherwise, the EntityIndex will not be able to be reused. In general, despawn should be used instead, which automatically allows the row to be reused.

Returns the new Entity if of the despawned EntityIndex, which should eventually either be re-spawned or freed to the allocator. Returns an EntityDespawnError if the entity is not spawned.

§Note

This will also despawn the entities in any RelationshipTarget that is configured to despawn descendants. For example, this will recursively despawn Children.

§Example

There is no simple example in which this would be practical, but one use for this is a custom entity allocator. Despawning internally calls this and frees the entity id to Bevy’s default entity allocator. The same principal can be used to create custom allocators with additional properties. For example, this could be used to make an allocator that yields groups of consecutive EntityIndexs, etc. See EntityAllocator::alloc for more on this.

Source

pub fn clear_trackers(&mut self)

Clears the internal component tracker state.

The world maintains some internal state about changed and removed components. This state is used by RemovedComponents to provide access to the entities that had a specific type of component removed since last tick.

The state is also used for change detection when accessing components and resources outside of a system, for example via World::get_mut() or World::get_resource_mut().

By clearing this internal state, the world “forgets” about those changes, allowing a new round of detection to be recorded.

When using bevy_ecs as part of the full Bevy engine, this method is called automatically by bevy_app::App::update and bevy_app::SubApp::update, so you don’t need to call it manually. When using bevy_ecs as a separate standalone crate however, you do need to call this manually.

// a whole new world
let mut world = World::new();

// you changed it
let entity = world.spawn(Transform::default()).id();

// change is detected
let transform = world.get_mut::<Transform>(entity).unwrap();
assert!(transform.is_changed());

// update the last change tick
world.clear_trackers();

// change is no longer detected
let transform = world.get_mut::<Transform>(entity).unwrap();
assert!(!transform.is_changed());
Source

pub fn query<D>(&mut self) -> QueryState<D>
where D: QueryData,

Returns QueryState for the given QueryData, which is used to efficiently run queries on the World by storing and reusing the QueryState.

use bevy_ecs::{component::Component, entity::Entity, world::World};

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

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

let mut world = World::new();
let entities = world.spawn_batch(vec![
    (Position { x: 0.0, y: 0.0}, Velocity { x: 1.0, y: 0.0 }),
    (Position { x: 0.0, y: 0.0}, Velocity { x: 0.0, y: 1.0 }),
]).collect::<Vec<Entity>>();

let mut query = world.query::<(&mut Position, &Velocity)>();
for (mut position, velocity) in query.iter_mut(&mut world) {
   position.x += velocity.x;
   position.y += velocity.y;
}

assert_eq!(world.get::<Position>(entities[0]).unwrap(), &Position { x: 1.0, y: 0.0 });
assert_eq!(world.get::<Position>(entities[1]).unwrap(), &Position { x: 0.0, y: 1.0 });

To iterate over entities in a deterministic order, sort the results of the query using the desired component as a key. Note that this requires fetching the whole result set from the query and allocation of a Vec to store it.

use bevy_ecs::{component::Component, entity::Entity, world::World};

#[derive(Component, PartialEq, Eq, PartialOrd, Ord, Debug)]
struct Order(i32);
#[derive(Component, PartialEq, Debug)]
struct Label(&'static str);

let mut world = World::new();
let a = world.spawn((Order(2), Label("second"))).id();
let b = world.spawn((Order(3), Label("third"))).id();
let c = world.spawn((Order(1), Label("first"))).id();
let mut entities = world.query::<(Entity, &Order, &Label)>()
    .iter(&world)
    .collect::<Vec<_>>();
// Sort the query results by their `Order` component before comparing
// to expected results. Query iteration order should not be relied on.
entities.sort_by_key(|e| e.1);
assert_eq!(entities, vec![
    (c, &Order(1), &Label("first")),
    (a, &Order(2), &Label("second")),
    (b, &Order(3), &Label("third")),
]);
Examples found in repository?
examples/window/persisting_window_settings.rs (line 57)
50fn init_window_pos(app: &mut App) {
51    let world = app.world_mut();
52    let Some(window_settings) = world.get_resource::<WindowSettings>() else {
53        return;
54    };
55    let window_settings = window_settings.clone();
56
57    let Ok(mut window) = world.query::<&mut Window>().single_mut(world) else {
58        warn!("window not found");
59        return;
60    };
61
62    if let Some(position) = window_settings.position {
63        window.position = WindowPosition::new(position);
64    }
65
66    if let Some(size) = window_settings.size {
67        window.resolution = WindowResolution::new(size.x, size.y);
68    }
69
70    window.mode = if window_settings.fullscreen {
71        WindowMode::BorderlessFullscreen(MonitorSelection::Current)
72    } else {
73        WindowMode::Windowed
74    };
75}
More examples
Hide additional examples
examples/tools/scene_viewer/scene_viewer_plugin.rs (line 139)
103fn scene_load_check(
104    asset_server: Res<AssetServer>,
105    mut scenes: ResMut<Assets<WorldAsset>>,
106    gltf_assets: Res<Assets<Gltf>>,
107    mut scene_handle: ResMut<SceneHandle>,
108    mut scene_spawner: ResMut<WorldInstanceSpawner>,
109) {
110    match scene_handle.instance_id {
111        None => {
112            if asset_server
113                .load_state(&scene_handle.gltf_handle)
114                .is_loaded()
115            {
116                let gltf = gltf_assets.get(&scene_handle.gltf_handle).unwrap();
117                if gltf.scenes.len() > 1 {
118                    info!(
119                        "Displaying scene {} out of {}",
120                        scene_handle.scene_index,
121                        gltf.scenes.len()
122                    );
123                    info!("You can select the scene by adding '#Scene' followed by a number to the end of the file path (e.g '#Scene1' to load the second scene).");
124                }
125
126                let gltf_scene_handle =
127                    gltf.scenes
128                        .get(scene_handle.scene_index)
129                        .unwrap_or_else(|| {
130                            panic!(
131                                "glTF file doesn't contain scene {}!",
132                                scene_handle.scene_index
133                            )
134                        });
135                let mut scene = scenes.get_mut(gltf_scene_handle).unwrap();
136
137                let mut query = scene
138                    .world
139                    .query::<(Option<&DirectionalLight>, Option<&PointLight>)>();
140                scene_handle.has_light =
141                    query
142                        .iter(&scene.world)
143                        .any(|(maybe_directional_light, maybe_point_light)| {
144                            maybe_directional_light.is_some() || maybe_point_light.is_some()
145                        });
146
147                scene_handle.instance_id = Some(scene_spawner.spawn(gltf_scene_handle.clone()));
148
149                info!("Spawning scene...");
150            }
151        }
152        Some(instance_id) if !scene_handle.is_loaded => {
153            if scene_spawner.instance_is_ready(instance_id) {
154                info!("...done!");
155                scene_handle.is_loaded = true;
156            }
157        }
158        Some(_) => {}
159    }
160}
Source

pub fn query_filtered<D, F>(&mut self) -> QueryState<D, F>
where D: QueryData, F: QueryFilter,

Returns QueryState for the given filtered QueryData, which is used to efficiently run queries on the World by storing and reusing the QueryState.

use bevy_ecs::{component::Component, entity::Entity, world::World, query::With};

#[derive(Component)]
struct A;
#[derive(Component)]
struct B;

let mut world = World::new();
let e1 = world.spawn(A).id();
let e2 = world.spawn((A, B)).id();

let mut query = world.query_filtered::<Entity, With<B>>();
let matching_entities = query.iter(&world).collect::<Vec<Entity>>();

assert_eq!(matching_entities, vec![e2]);
Source

pub fn try_query<D>(&self) -> Option<QueryState<D>>
where D: QueryData,

Returns QueryState for the given QueryData, which is used to efficiently run queries on the World by storing and reusing the QueryState.

use bevy_ecs::{component::Component, entity::Entity, world::World};

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

let mut world = World::new();
world.spawn_batch(vec![
    Position { x: 0.0, y: 0.0 },
    Position { x: 1.0, y: 1.0 },
]);

fn get_positions(world: &World) -> Vec<(Entity, &Position)> {
    let mut query = world.try_query::<(Entity, &Position)>().unwrap();
    query.iter(world).collect()
}

let positions = get_positions(&world);

assert_eq!(world.get::<Position>(positions[0].0).unwrap(), positions[0].1);
assert_eq!(world.get::<Position>(positions[1].0).unwrap(), positions[1].1);

Requires only an immutable world reference, but may fail if, for example, the components that make up this query have not been registered into the world.

use bevy_ecs::{component::Component, entity::Entity, world::World};

#[derive(Component)]
struct A;

let mut world = World::new();

let none_query = world.try_query::<&A>();
assert!(none_query.is_none());

world.register_component::<A>();

let some_query = world.try_query::<&A>();
assert!(some_query.is_some());
Source

pub fn try_query_filtered<D, F>(&self) -> Option<QueryState<D, F>>
where D: QueryData, F: QueryFilter,

Returns QueryState for the given filtered QueryData, which is used to efficiently run queries on the World by storing and reusing the QueryState.

use bevy_ecs::{component::Component, entity::Entity, world::World, query::With};

#[derive(Component)]
struct A;
#[derive(Component)]
struct B;

let mut world = World::new();
let e1 = world.spawn(A).id();
let e2 = world.spawn((A, B)).id();

let mut query = world.try_query_filtered::<Entity, With<B>>().unwrap();
let matching_entities = query.iter(&world).collect::<Vec<Entity>>();

assert_eq!(matching_entities, vec![e2]);

Requires only an immutable world reference, but may fail if, for example, the components that make up this query have not been registered into the world.

Source

pub fn removed<T>(&self) -> impl Iterator<Item = Entity>
where T: Component,

Returns an iterator of entities that had components of type T removed since the last call to World::clear_trackers.

Source

pub fn removed_with_id( &self, component_id: ComponentId, ) -> impl Iterator<Item = Entity>

Returns an iterator of entities that had components with the given component_id removed since the last call to World::clear_trackers.

Source

pub fn register_non_send_with_descriptor( &mut self, descriptor: ComponentDescriptor, ) -> ComponentId

Registers a new non-send resource type and returns the ComponentId created for it.

This enables the dynamic registration of new non-send resources definitions at runtime for advanced use cases.

§Note

Registering a non-send resource does not insert it into World. For insertion, you could use World::insert_non_send_by_id.

Source

pub fn init_resource<R>(&mut self) -> ComponentId
where R: Resource + FromWorld,

Initializes a new resource and returns the ComponentId created for it.

If the resource already exists, nothing happens.

The value given by the FromWorld::from_world method will be used. Note that any resource with the Default trait automatically implements FromWorld, and those default values will be here instead.

Examples found in repository?
examples/ecs/custom_executor.rs (line 47)
45fn main() {
46    let mut world = World::new();
47    world.init_resource::<Counter>();
48
49    let mut schedule = Schedule::default();
50    schedule.set_executor(CustomExecutor);
51    schedule.add_systems((increment, print_counter).chain());
52
53    for _ in 0..5 {
54        schedule.run(&mut world);
55    }
56}
More examples
Hide additional examples
examples/ecs/immutable_components.rs (line 105)
103fn demo_2(world: &mut World) {
104    // Setup our name index
105    world.init_resource::<NameIndex>();
106
107    // Spawn some entities!
108    let alyssa = world.spawn(Name("Alyssa")).id();
109    let javier = world.spawn(Name("Javier")).id();
110
111    // Check our index
112    let index = world.resource::<NameIndex>();
113
114    assert_eq!(index.get_entity("Alyssa"), Some(alyssa));
115    assert_eq!(index.get_entity("Javier"), Some(javier));
116
117    // Changing the name of an entity is also fully capture by our index
118    world.entity_mut(javier).insert(Name("Steven"));
119
120    // Javier changed their name to Steven
121    let steven = javier;
122
123    // Check our index
124    let index = world.resource::<NameIndex>();
125
126    assert_eq!(index.get_entity("Javier"), None);
127    assert_eq!(index.get_entity("Steven"), Some(steven));
128}
examples/ecs/dynamic.rs (line 259)
69fn main() {
70    let mut world = World::new();
71    let mut lines = std::io::stdin().lines();
72    let mut component_names = HashMap::<String, ComponentId>::new();
73    let mut component_info = HashMap::<ComponentId, ComponentInfo>::new();
74    let mut event_names = HashMap::<String, EventKey>::new();
75
76    println!("{PROMPT}");
77    loop {
78        print!("\n> ");
79        let _ = std::io::stdout().flush();
80        let Some(Ok(line)) = lines.next() else {
81            return;
82        };
83
84        if line.is_empty() {
85            return;
86        };
87
88        let Some((first, rest)) = line.trim().split_once(|c: char| c.is_whitespace()) else {
89            match &line.chars().next() {
90                Some('c') => println!("{COMPONENT_PROMPT}"),
91                Some('s') => println!("{ENTITY_PROMPT}"),
92                Some('q') => println!("{QUERY_PROMPT}"),
93                Some('e') => println!("{EVENT_PROMPT}"),
94                Some('t') => println!("{EMIT_PROMPT}"),
95                _ => println!("{PROMPT}"),
96            }
97            continue;
98        };
99
100        match &first[0..1] {
101            "c" => {
102                rest.split(',').for_each(|component| {
103                    let mut component = component.split_whitespace();
104                    let Some(name) = component.next() else {
105                        return;
106                    };
107                    let size = match component.next().map(str::parse) {
108                        Some(Ok(size)) => size,
109                        _ => 0,
110                    };
111                    // Register our new component to the world with a layout specified by it's size
112                    // SAFETY: [u64] is Send + Sync
113                    let id = world.register_component_with_descriptor(unsafe {
114                        ComponentDescriptor::new_with_layout(
115                            name.to_string(),
116                            StorageType::Table,
117                            Layout::array::<u64>(size).unwrap(),
118                            None,
119                            true,
120                            ComponentCloneBehavior::Default,
121                            None,
122                        )
123                    });
124                    let Some(info) = world.components().get_info(id) else {
125                        return;
126                    };
127                    component_names.insert(name.to_string(), id);
128                    component_info.insert(id, info.clone());
129                    println!("Component {} created with id: {}", name, id.index());
130                });
131            }
132            "s" => {
133                let mut to_insert_ids = Vec::new();
134                let mut to_insert_data = Vec::new();
135                rest.split(',').for_each(|component| {
136                    let mut component = component.split_whitespace();
137                    let Some(name) = component.next() else {
138                        return;
139                    };
140
141                    // Get the id for the component with the given name
142                    let Some(&id) = component_names.get(name) else {
143                        println!("Component {name} does not exist");
144                        return;
145                    };
146
147                    // Calculate the length for the array based on the layout created for this component id
148                    let info = world.components().get_info(id).unwrap();
149                    let len = info.layout().size() / size_of::<u64>();
150                    let mut values: Vec<u64> = component
151                        .take(len)
152                        .filter_map(|value| value.parse::<u64>().ok())
153                        .collect();
154                    values.resize(len, 0);
155
156                    // Collect the id and array to be inserted onto our entity
157                    to_insert_ids.push(id);
158                    to_insert_data.push(values);
159                });
160
161                let mut entity = world.spawn_empty();
162
163                // Construct an `OwningPtr` for each component in `to_insert_data`
164                let to_insert_ptr = to_owning_ptrs(&mut to_insert_data);
165
166                // SAFETY:
167                // - Component ids have been taken from the same world
168                // - Each array is created to the layout specified in the world
169                unsafe {
170                    entity.insert_by_ids(&to_insert_ids, to_insert_ptr.into_iter());
171                }
172
173                println!("Entity spawned with id: {}", entity.id());
174            }
175            "q" => {
176                let mut builder = QueryBuilder::<FilteredEntityMut>::new(&mut world);
177                parse_query(rest, &mut builder, &component_names);
178                let mut query = builder.build();
179                query.iter_mut(&mut world).for_each(|filtered_entity| {
180                    let terms = filtered_entity
181                        .access()
182                        .try_iter_access()
183                        .unwrap()
184                        .map(|component_access| {
185                            let id = *component_access.index();
186                            let ptr = filtered_entity.get_by_id(id).unwrap();
187                            let info = component_info.get(&id).unwrap();
188                            let len = info.layout().size() / size_of::<u64>();
189
190                            // SAFETY:
191                            // - All components are created with layout [u64]
192                            // - len is calculated from the component descriptor
193                            let data = unsafe {
194                                std::slice::from_raw_parts_mut(
195                                    ptr.assert_unique().as_ptr().cast::<u64>(),
196                                    len,
197                                )
198                            };
199
200                            // If we have write access, increment each value once
201                            if matches!(component_access, ComponentAccessKind::Exclusive(_)) {
202                                data.iter_mut().for_each(|data| {
203                                    *data += 1;
204                                });
205                            }
206
207                            format!("{}: {:?}", info.name(), data[0..len].to_vec())
208                        })
209                        .collect::<Vec<_>>()
210                        .join(", ");
211
212                    println!("{}: {}", filtered_entity.id(), terms);
213                });
214            }
215            "e" => {
216                rest.split(',').for_each(|event| {
217                    let name = event.trim();
218                    if name.is_empty() {
219                        return;
220                    }
221
222                    // Register a ComponentId for this event, no Rust type needed.
223                    // SAFETY: ZST with no drop
224                    let event_component_id = world.register_component_with_descriptor(unsafe {
225                        ComponentDescriptor::new_with_layout(
226                            format!("event:{name}"),
227                            StorageType::Table,
228                            Layout::new::<()>(),
229                            None,
230                            false,
231                            ComponentCloneBehavior::Ignore,
232                            None,
233                        )
234                    });
235                    // SAFETY: event_component_id was just registered for this event
236                    let event_key = unsafe { EventKey::new(event_component_id) };
237                    event_names.insert(name.to_string(), event_key);
238
239                    // Build a dynamic observer that prints when the event fires.
240                    let runner: ObserverRunner = |mut world, _observer, ctx, _event, _trigger| {
241                        println!("  Observer fired!");
242                        if let Some(mut counts) = world.get_resource_mut::<EventFireCount>() {
243                            *counts.0.entry(ctx.event_key).or_insert(0) += 1;
244                        }
245                    };
246
247                    // SAFETY: event_key was just registered, runner ignores pointers
248                    let observer =
249                        unsafe { Observer::with_dynamic_runner(runner).with_event_key(event_key) };
250                    world.spawn(observer);
251
252                    println!(
253                        "Event '{name}' registered (key: {}) with a dynamic observer",
254                        event_component_id.index()
255                    );
256                });
257
258                // Ensure the counter resource exists.
259                world.init_resource::<EventFireCount>();
260            }
261            "t" => {
262                let name = rest.trim();
263                let Some(&event_key) = event_names.get(name) else {
264                    println!(
265                        "Event '{name}' does not exist. Register it first with 'event {name}'"
266                    );
267                    continue;
268                };
269
270                let mut event_data = ();
271                let mut trigger_data = ();
272                // SAFETY: event_key was registered in this world, both pointers are valid ZSTs
273                unsafe {
274                    world.trigger_dynamic(
275                        event_key,
276                        PtrMut::from(&mut event_data),
277                        PtrMut::from(&mut trigger_data),
278                    );
279                }
280
281                let count = world
282                    .get_resource::<EventFireCount>()
283                    .map_or(0, |c| c.0.get(&event_key).copied().unwrap_or(0));
284                println!("Event '{name}' triggered ({count} fires)");
285            }
286            _ => continue,
287        }
288    }
289}
Source

pub fn insert_resource<R>(&mut self, value: R)
where R: Resource,

Inserts a new resource with the given value.

Resources are “unique” data of a given type. If you insert a resource of a type that already exists, you will overwrite any existing data.

Examples found in repository?
crates/bevy_ecs/examples/resources.rs (line 19)
14fn main() {
15    // Create a world
16    let mut world = World::new();
17
18    // Add the counter resource
19    world.insert_resource(Counter { value: 0 });
20
21    // Create a schedule
22    let mut schedule = Schedule::default();
23
24    // Add systems to increase the counter and to print out the current value
25    schedule.add_systems((increase_counter, print_counter).chain());
26
27    for iteration in 1..=10 {
28        println!("Simulating frame {iteration}/10");
29        schedule.run(&mut world);
30    }
31}
More examples
Hide additional examples
crates/bevy_ecs/examples/change_detection.rs (line 24)
19fn main() {
20    // Create a new empty World to hold our Entities, Components and Resources
21    let mut world = World::new();
22
23    // Add the counter resource to remember how many entities where spawned
24    world.insert_resource(EntityCounter { value: 0 });
25
26    // Create a new Schedule, which stores systems and controls their relative ordering
27    let mut schedule = Schedule::default();
28
29    // Add systems to the Schedule to execute our app logic
30    // We can label our systems to force a specific run-order between some of them
31    schedule.add_systems((
32        spawn_entities.in_set(SimulationSystems::Spawn),
33        print_counter_when_changed.after(SimulationSystems::Spawn),
34        age_all_entities.in_set(SimulationSystems::Age),
35        remove_old_entities.after(SimulationSystems::Age),
36        print_changed_entities.after(SimulationSystems::Age),
37    ));
38
39    // Simulate 10 frames in our world
40    for iteration in 1..=10 {
41        println!("Simulating frame {iteration}/10");
42        schedule.run(&mut world);
43    }
44}
examples/scene/world_serialization.rs (line 187)
166fn save_world_system(world: &mut World) {
167    let asset_server = world.resource::<AssetServer>().clone();
168    // The `TypeRegistry` resource contains information about all registered types (including components).
169    // This is used to construct worlds, so we'll want to ensure that we use the registry from the
170    // main world. To do this, we can simply clone the `AppTypeRegistry` resource.
171    let type_registry = world.resource::<AppTypeRegistry>().clone();
172
173    // Any ECS World can be serialized.
174    // For demonstration purposes, we'll create a new one.
175    let mut scene_world = World::new();
176
177    let mut component_b = ComponentB::from_world(world);
178    component_b.value = "hello".to_string();
179    scene_world.spawn((
180        component_b,
181        ComponentA { x: 1.0, y: 2.0 },
182        Transform::IDENTITY,
183        Name::new("joe"),
184        WorldAssetRoot(asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0")),
185    ));
186    scene_world.spawn(ComponentA { x: 3.0, y: 4.0 });
187    scene_world.insert_resource(ResourceA { score: 1 });
188
189    // With our sample world ready to go, we can now create a DynamicWorld from it.
190    // For simplicity, we will create our scene using DynamicWorld directly, but if
191    // you need more control, you can use DynamicWorldBuilder.
192    let dynamic_world = DynamicWorld::from_world_with(&scene_world, &type_registry.read());
193
194    // Dynamic Worlds can be serialized like this:
195    let type_registry = world.resource::<AppTypeRegistry>();
196    let type_registry = type_registry.read();
197    let serialized_world = dynamic_world.serialize(&type_registry).unwrap();
198
199    // Shows the serialized world in the console
200    info!("{}", serialized_world);
201
202    // Writing the world to a new file. Using a task to avoid calling the filesystem APIs in a system
203    // as they are blocking.
204    //
205    // This can't work in Wasm as there is no filesystem access.
206    #[cfg(not(target_arch = "wasm32"))]
207    IoTaskPool::get()
208        .spawn(async move {
209            // Write the world RON data to file
210            File::create(format!("assets/{NEW_WORLD_FILE_PATH}"))
211                .and_then(|mut file| file.write(serialized_world.as_bytes()))
212                .expect("Error while writing world to file");
213        })
214        .detach();
215}
Source

pub fn init_non_send_resource<R>(&mut self) -> ComponentId
where R: 'static + FromWorld,

👎Deprecated since 0.19.0:

use World::init_non_send

Initializes a new non-send resource and returns the ComponentId created for it.

Source

pub fn init_non_send<R>(&mut self) -> ComponentId
where R: 'static + FromWorld,

Initializes new non-send data and returns the ComponentId created for it.

If the data already exists, nothing happens.

The value given by the FromWorld::from_world method will be used. Note that any non-send data with the Default trait automatically implements FromWorld, and those default values will be here instead.

§Panics

Panics if called from a thread other than the main thread.

Source

pub fn insert_non_send_resource<R>(&mut self, value: R)
where R: 'static,

👎Deprecated since 0.19.0:

use World::insert_non_send

Inserts a new non-send resource with the given value.

Source

pub fn insert_non_send<R>(&mut self, value: R)
where R: 'static,

Inserts new non-send data with the given value.

NonSend data cannot be sent across threads, and do not need the Send + Sync bounds. Systems with NonSend resources are always scheduled on the main thread.

§Panics

If a value is already present, this function will panic if called from a different thread than where the original value was inserted from.

Source

pub fn remove_resource<R>(&mut self) -> Option<R>
where R: Resource,

Removes the resource of a given type and returns it, if it exists. Otherwise returns None.

Source

pub fn remove_non_send_resource<R>(&mut self) -> Option<R>
where R: 'static,

👎Deprecated since 0.19.0:

use World::remove_non_send

Removes a !Send resource from the world and returns it, if present.

Source

pub fn remove_non_send<R>(&mut self) -> Option<R>
where R: 'static,

Removes !Send data from the world and returns it, if present.

NonSend resources cannot be sent across threads, and do not need the Send + Sync bounds. Systems with NonSend data are always scheduled on the main thread.

Returns None if a value was not previously present.

§Panics

If a value is present, this function will panic if called from a different thread than where the value was inserted from.

Source

pub fn contains_resource<R>(&self) -> bool
where R: Resource,

Returns true if a resource of type R exists. Otherwise returns false.

Source

pub fn contains_resource_by_id(&self, component_id: ComponentId) -> bool

Returns true if a resource with provided component_id exists. Otherwise returns false.

Source

pub fn contains_non_send<R>(&self) -> bool
where R: 'static,

Returns true if !Send data of type R exists. Otherwise returns false.

Source

pub fn contains_non_send_by_id(&self, component_id: ComponentId) -> bool

Returns true if !Send data with component_id exists. Otherwise returns false.

Source

pub fn is_resource_added<R>(&self) -> bool
where R: Resource,

Returns true if a resource of type R exists and was added since the world’s last_change_tick. Otherwise, this returns false.

This means that:

  • When called from an exclusive system, this will check for additions since the system last ran.
  • When called elsewhere, this will check for additions since the last time that World::clear_trackers was called.
Source

pub fn is_resource_added_by_id(&self, component_id: ComponentId) -> bool

Returns true if a resource with id component_id exists and was added since the world’s last_change_tick. Otherwise, this returns false.

This means that:

  • When called from an exclusive system, this will check for additions since the system last ran.
  • When called elsewhere, this will check for additions since the last time that World::clear_trackers was called.
Source

pub fn is_resource_changed<R>(&self) -> bool
where R: Resource,

Returns true if a resource of type R exists and was modified since the world’s last_change_tick. Otherwise, this returns false.

This means that:

  • When called from an exclusive system, this will check for changes since the system last ran.
  • When called elsewhere, this will check for changes since the last time that World::clear_trackers was called.
Source

pub fn is_resource_changed_by_id(&self, component_id: ComponentId) -> bool

Returns true if a resource with id component_id exists and was modified since the world’s last_change_tick. Otherwise, this returns false.

This means that:

  • When called from an exclusive system, this will check for changes since the system last ran.
  • When called elsewhere, this will check for changes since the last time that World::clear_trackers was called.
Source

pub fn get_resource_change_ticks<R>(&self) -> Option<ComponentTicks>
where R: Resource,

Retrieves the change ticks for the given resource.

Source

pub fn get_resource_change_ticks_by_id( &self, component_id: ComponentId, ) -> Option<ComponentTicks>

Retrieves the change ticks for the given ComponentId.

You should prefer to use the typed API World::get_resource_change_ticks where possible.

Source

pub fn resource<R>(&self) -> &R
where R: Resource,

Gets a reference to the resource of the given type

§Panics

Panics if the resource does not exist. Use get_resource instead if you want to handle this case.

If you want to instead insert a value if the resource does not exist, use get_resource_or_insert_with.

Examples found in repository?
examples/3d/specular_tint.rs (line 33)
32    fn from_world(world: &mut World) -> Self {
33        let asset_server = world.resource::<AssetServer>();
34        Self {
35            noise_texture: asset_server.load("textures/AlphaNoise.png"),
36        }
37    }
More examples
Hide additional examples
examples/audio/play_sound_effect.rs (line 14)
13    fn from_world(world: &mut World) -> Self {
14        let asset_server = world.resource::<AssetServer>();
15        SoundEffect {
16            handle: asset_server.load("sounds/breakout_collision.ogg"),
17        }
18    }
examples/scene/world_serialization.rs (line 89)
88    fn from_world(world: &mut World) -> Self {
89        let time = world.resource::<Time>();
90        ComponentB {
91            _time_since_startup: time.elapsed(),
92            value: "Default Value".to_string(),
93        }
94    }
95}
96
97/// A simple resource that also derives `Reflect`, allowing it to be stored in world files.
98///
99/// Just like a component, you can skip serializing fields or implement `FromWorld` if needed.
100#[derive(Resource, Reflect, Default)]
101#[reflect(Resource)]
102struct ResourceA {
103    /// This resource tracks a `score` value.
104    pub score: u32,
105}
106
107/// # World File Paths
108///
109/// `WORLD_FILE_PATH` points to the original world file that we'll be loading.
110/// `NEW_WORLD_FILE_PATH` points to the new world file that we'll be creating
111/// (and demonstrating how to serialize to disk).
112///
113/// The initial world file will be loaded below and not change when the world is saved.
114const WORLD_FILE_PATH: &str = "serialized_worlds/load_scene_example.scn.ron";
115
116/// The new, updated world data will be saved here so that you can see the changes.
117const NEW_WORLD_FILE_PATH: &str = "serialized_worlds/load_scene_example-new.scn.ron";
118
119/// Loads a world from an asset file and spawns it in the current world.
120///
121/// Spawning a `DynamicWorldRoot` creates a new parent entity, which then spawns new
122/// instances of the world's entities as its children. If you modify the
123/// `WORLD_FILE_PATH` file, or if you enable file watching, you can see
124/// changes reflected immediately.
125fn load_world_system(mut commands: Commands, asset_server: Res<AssetServer>) {
126    commands.spawn(DynamicWorldRoot(asset_server.load(WORLD_FILE_PATH)));
127    commands.spawn((
128        Camera3d::default(),
129        Transform::from_xyz(1.0, 1.0, 1.0).looking_at(Vec3::new(0.0, 0.25, 0.0), Vec3::Y),
130    ));
131    commands.spawn((
132        DirectionalLight::default(),
133        Transform::default().looking_to(Vec3::new(0.0, -1.0, -1.0), Vec3::Y),
134    ));
135}
136
137/// Logs changes made to `ComponentA` entities, and also checks whether `ResourceA`
138/// has been recently added.
139///
140/// Any time a `ComponentA` is modified, that change will appear here. This system
141/// demonstrates how you might detect and handle world updates at runtime.
142fn log_system(
143    query: Query<(Entity, &ComponentA), Changed<ComponentA>>,
144    res: Option<Res<ResourceA>>,
145) {
146    for (entity, component_a) in &query {
147        info!("  Entity({})", entity.index());
148        info!(
149            "    ComponentA: {{ x: {} y: {} }}\n",
150            component_a.x, component_a.y
151        );
152    }
153    if let Some(res) = res
154        && res.is_added()
155    {
156        info!("  New ResourceA: {{ score: {} }}\n", res.score);
157    }
158}
159
160/// Demonstrates how to create a new world from scratch, populate it with data,
161/// and then serialize it to a file. The new file is written to `NEW_WORLD_FILE_PATH`.
162///
163/// This system creates a fresh world, duplicates the type registry so that our
164/// custom component types are recognized, spawns some sample entities and resources,
165/// and then serializes the resulting dynamic world.
166fn save_world_system(world: &mut World) {
167    let asset_server = world.resource::<AssetServer>().clone();
168    // The `TypeRegistry` resource contains information about all registered types (including components).
169    // This is used to construct worlds, so we'll want to ensure that we use the registry from the
170    // main world. To do this, we can simply clone the `AppTypeRegistry` resource.
171    let type_registry = world.resource::<AppTypeRegistry>().clone();
172
173    // Any ECS World can be serialized.
174    // For demonstration purposes, we'll create a new one.
175    let mut scene_world = World::new();
176
177    let mut component_b = ComponentB::from_world(world);
178    component_b.value = "hello".to_string();
179    scene_world.spawn((
180        component_b,
181        ComponentA { x: 1.0, y: 2.0 },
182        Transform::IDENTITY,
183        Name::new("joe"),
184        WorldAssetRoot(asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0")),
185    ));
186    scene_world.spawn(ComponentA { x: 3.0, y: 4.0 });
187    scene_world.insert_resource(ResourceA { score: 1 });
188
189    // With our sample world ready to go, we can now create a DynamicWorld from it.
190    // For simplicity, we will create our scene using DynamicWorld directly, but if
191    // you need more control, you can use DynamicWorldBuilder.
192    let dynamic_world = DynamicWorld::from_world_with(&scene_world, &type_registry.read());
193
194    // Dynamic Worlds can be serialized like this:
195    let type_registry = world.resource::<AppTypeRegistry>();
196    let type_registry = type_registry.read();
197    let serialized_world = dynamic_world.serialize(&type_registry).unwrap();
198
199    // Shows the serialized world in the console
200    info!("{}", serialized_world);
201
202    // Writing the world to a new file. Using a task to avoid calling the filesystem APIs in a system
203    // as they are blocking.
204    //
205    // This can't work in Wasm as there is no filesystem access.
206    #[cfg(not(target_arch = "wasm32"))]
207    IoTaskPool::get()
208        .spawn(async move {
209            // Write the world RON data to file
210            File::create(format!("assets/{NEW_WORLD_FILE_PATH}"))
211                .and_then(|mut file| file.write(serialized_world.as_bytes()))
212                .expect("Error while writing world to file");
213        })
214        .detach();
215}
examples/app/externally_driven_headless_renderer.rs (line 111)
105    fn update(&mut self) {
106        self.0.update();
107        // Wait for frame to finish rendering by wait polling the device
108        self.0
109            .main
110            .world()
111            .resource::<RenderDevice>()
112            .wgpu_device()
113            .poll(PollType::Wait {
114                submission_index: None,
115                timeout: None,
116            })
117            .unwrap();
118    }
tests/ecs/ambiguity_detection.rs (line 80)
79fn count_ambiguities(sub_app: &SubApp) -> AmbiguitiesCount {
80    let schedules = sub_app.world().resource::<Schedules>();
81    let mut ambiguities = <HashMap<_, _>>::default();
82    for (_, schedule) in schedules.iter() {
83        let ambiguities_in_schedule = schedule.graph().conflicting_systems().len();
84        ambiguities.insert(schedule.label(), ambiguities_in_schedule);
85    }
86    AmbiguitiesCount(ambiguities)
87}
examples/2d/dynamic_mip_generation.rs (line 295)
291    fn from_world(world: &mut World) -> Self {
292        let mut meshes = world.resource_mut::<Assets<Mesh>>();
293        let rectangle = meshes.add(Rectangle::default());
294
295        let asset_server = world.resource::<AssetServer>();
296        let font = asset_server.load("fonts/FiraSans-Bold.ttf");
297        let text_font = TextFont {
298            font: font.into(),
299            font_size: FONT_SIZE,
300            ..default()
301        };
302
303        AppAssets {
304            rectangle,
305            text_font,
306        }
307    }
Source

pub fn resource_ref<R>(&self) -> Ref<'_, R>
where R: Resource,

Gets a reference to the resource of the given type

§Panics

Panics if the resource does not exist. Use get_resource_ref instead if you want to handle this case.

If you want to instead insert a value if the resource does not exist, use get_resource_or_insert_with.

Source

pub fn resource_mut<R>(&mut self) -> Mut<'_, R>
where R: Resource,

Gets a mutable reference to the resource of the given type

§Panics

Panics if the resource does not exist. Use get_resource_mut instead if you want to handle this case.

If you want to instead insert a value if the resource does not exist, use get_resource_or_insert_with.

Examples found in repository?
examples/shader/shader_material_wesl.rs (line 44)
41    fn build(&self, app: &mut App) {
42        let handle = app
43            .world_mut()
44            .resource_mut::<AssetServer>()
45            .load::<Shader>("shaders/util.wesl");
46        app.insert_resource(UtilityShader(handle));
47    }
More examples
Hide additional examples
tests/ecs/ambiguity_detection.rs (line 67)
66fn configure_ambiguity_detection(sub_app: &mut SubApp) {
67    let mut schedules = sub_app.world_mut().resource_mut::<Schedules>();
68    for (_, schedule) in schedules.iter_mut() {
69        schedule.set_build_settings(ScheduleBuildSettings {
70            // NOTE: you can change this to `LogLevel::Ignore` to easily see the current number of ambiguities.
71            ambiguity_detection: LogLevel::Warn,
72            use_shortnames: false,
73            ..default()
74        });
75    }
76}
examples/2d/dynamic_mip_generation.rs (line 292)
291    fn from_world(world: &mut World) -> Self {
292        let mut meshes = world.resource_mut::<Assets<Mesh>>();
293        let rectangle = meshes.add(Rectangle::default());
294
295        let asset_server = world.resource::<AssetServer>();
296        let font = asset_server.load("fonts/FiraSans-Bold.ttf");
297        let text_font = TextFont {
298            font: font.into(),
299            font_size: FONT_SIZE,
300            ..default()
301        };
302
303        AppAssets {
304            rectangle,
305            text_font,
306        }
307    }
examples/shader_advanced/compute_mesh.rs (line 68)
62    fn finish(&self, app: &mut App) {
63        let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
64            return;
65        };
66        render_app
67            .world_mut()
68            .resource_mut::<MeshAllocatorSettings>()
69            // This allows using the mesh allocator slabs as
70            // storage buffers directly in the compute shader.
71            // Which means that we can write from our compute
72            // shader directly to the allocated mesh slabs.
73            .extra_buffer_usages = BufferUsages::STORAGE;
74    }
examples/app/custom_loop.rs (line 19)
10fn my_runner(mut app: App) -> AppExit {
11    // Finalize plugin building, including running any necessary clean-up.
12    // This is normally completed by the default runner.
13    app.finish();
14    app.cleanup();
15
16    println!("Type stuff into the console");
17    for line in io::stdin().lines() {
18        {
19            let mut input = app.world_mut().resource_mut::<Input>();
20            input.0 = line.unwrap();
21        }
22        app.update();
23
24        if let Some(exit) = app.should_exit() {
25            return exit;
26        }
27    }
28
29    AppExit::Success
30}
examples/gltf/gltf_extension_animation_graph.rs (line 142)
130    fn build(&self, app: &mut App) {
131        #[cfg(target_family = "wasm")]
132        bevy::tasks::block_on(async {
133            app.world_mut()
134                .resource_mut::<GltfExtensionHandlers>()
135                .0
136                .write()
137                .await
138                .push(Box::new(GltfExtensionHandlerAnimation::default()))
139        });
140        #[cfg(not(target_family = "wasm"))]
141        app.world_mut()
142            .resource_mut::<GltfExtensionHandlers>()
143            .0
144            .write_blocking()
145            .push(Box::new(GltfExtensionHandlerAnimation::default()));
146    }
Source

pub fn get_resource<R>(&self) -> Option<&R>
where R: Resource,

Gets a reference to the resource of the given type if it exists

Examples found in repository?
examples/window/persisting_window_settings.rs (line 52)
50fn init_window_pos(app: &mut App) {
51    let world = app.world_mut();
52    let Some(window_settings) = world.get_resource::<WindowSettings>() else {
53        return;
54    };
55    let window_settings = window_settings.clone();
56
57    let Ok(mut window) = world.query::<&mut Window>().single_mut(world) else {
58        warn!("window not found");
59        return;
60    };
61
62    if let Some(position) = window_settings.position {
63        window.position = WindowPosition::new(position);
64    }
65
66    if let Some(size) = window_settings.size {
67        window.resolution = WindowResolution::new(size.x, size.y);
68    }
69
70    window.mode = if window_settings.fullscreen {
71        WindowMode::BorderlessFullscreen(MonitorSelection::Current)
72    } else {
73        WindowMode::Windowed
74    };
75}
More examples
Hide additional examples
examples/ecs/error_handling.rs (line 155)
151fn failing_system(world: &mut World) -> Result {
152    world
153        // `get_resource` returns an `Option<T>`, so we use `ok_or` to convert it to a `Result` on
154        // which we can call `?` to propagate the error.
155        .get_resource::<UninitializedResource>()
156        // We can provide a `str` here because `BevyError` implements `From<&str>`.
157        .ok_or("Resource not initialized")
158        // The default error severity is Severity::Panic.
159        // We can add a Severity level to any Result locally to downgrade it appropriately.
160        .with_severity(Severity::Warning)?;
161
162    world
163        // This entity doesn't exist!
164        .spawn_empty_at(Entity::from_raw_u32(12345678).unwrap())
165        .map_severity(|e| match e {
166            // Not that concerning, we just need to make sure to find a different entity
167            SpawnError::AlreadySpawned => Severity::Debug,
168            // Oh no
169            SpawnError::Invalid(_) => Severity::Error,
170        })?;
171
172    Ok(())
173}
174
175fn failing_commands(mut commands: Commands) {
176    commands
177        // This entity doesn't exist!
178        .entity(Entity::from_raw_u32(12345678).unwrap())
179        // Normally, this failed command would panic,
180        // but since we've set the global error handler to `warn`
181        // it will log a warning instead.
182        .insert(Transform::default());
183
184    // The error handlers for commands can be set individually as well,
185    // by using the queue_handled method.
186    commands.queue_handled(
187        |world: &mut World| -> Result {
188            world
189                .get_resource::<UninitializedResource>()
190                .ok_or("Resource not initialized when accessed in a command")?;
191
192            Ok(())
193        },
194        |error, context| {
195            error!("{error}, {context}");
196        },
197    );
198}
examples/ecs/dynamic.rs (line 282)
69fn main() {
70    let mut world = World::new();
71    let mut lines = std::io::stdin().lines();
72    let mut component_names = HashMap::<String, ComponentId>::new();
73    let mut component_info = HashMap::<ComponentId, ComponentInfo>::new();
74    let mut event_names = HashMap::<String, EventKey>::new();
75
76    println!("{PROMPT}");
77    loop {
78        print!("\n> ");
79        let _ = std::io::stdout().flush();
80        let Some(Ok(line)) = lines.next() else {
81            return;
82        };
83
84        if line.is_empty() {
85            return;
86        };
87
88        let Some((first, rest)) = line.trim().split_once(|c: char| c.is_whitespace()) else {
89            match &line.chars().next() {
90                Some('c') => println!("{COMPONENT_PROMPT}"),
91                Some('s') => println!("{ENTITY_PROMPT}"),
92                Some('q') => println!("{QUERY_PROMPT}"),
93                Some('e') => println!("{EVENT_PROMPT}"),
94                Some('t') => println!("{EMIT_PROMPT}"),
95                _ => println!("{PROMPT}"),
96            }
97            continue;
98        };
99
100        match &first[0..1] {
101            "c" => {
102                rest.split(',').for_each(|component| {
103                    let mut component = component.split_whitespace();
104                    let Some(name) = component.next() else {
105                        return;
106                    };
107                    let size = match component.next().map(str::parse) {
108                        Some(Ok(size)) => size,
109                        _ => 0,
110                    };
111                    // Register our new component to the world with a layout specified by it's size
112                    // SAFETY: [u64] is Send + Sync
113                    let id = world.register_component_with_descriptor(unsafe {
114                        ComponentDescriptor::new_with_layout(
115                            name.to_string(),
116                            StorageType::Table,
117                            Layout::array::<u64>(size).unwrap(),
118                            None,
119                            true,
120                            ComponentCloneBehavior::Default,
121                            None,
122                        )
123                    });
124                    let Some(info) = world.components().get_info(id) else {
125                        return;
126                    };
127                    component_names.insert(name.to_string(), id);
128                    component_info.insert(id, info.clone());
129                    println!("Component {} created with id: {}", name, id.index());
130                });
131            }
132            "s" => {
133                let mut to_insert_ids = Vec::new();
134                let mut to_insert_data = Vec::new();
135                rest.split(',').for_each(|component| {
136                    let mut component = component.split_whitespace();
137                    let Some(name) = component.next() else {
138                        return;
139                    };
140
141                    // Get the id for the component with the given name
142                    let Some(&id) = component_names.get(name) else {
143                        println!("Component {name} does not exist");
144                        return;
145                    };
146
147                    // Calculate the length for the array based on the layout created for this component id
148                    let info = world.components().get_info(id).unwrap();
149                    let len = info.layout().size() / size_of::<u64>();
150                    let mut values: Vec<u64> = component
151                        .take(len)
152                        .filter_map(|value| value.parse::<u64>().ok())
153                        .collect();
154                    values.resize(len, 0);
155
156                    // Collect the id and array to be inserted onto our entity
157                    to_insert_ids.push(id);
158                    to_insert_data.push(values);
159                });
160
161                let mut entity = world.spawn_empty();
162
163                // Construct an `OwningPtr` for each component in `to_insert_data`
164                let to_insert_ptr = to_owning_ptrs(&mut to_insert_data);
165
166                // SAFETY:
167                // - Component ids have been taken from the same world
168                // - Each array is created to the layout specified in the world
169                unsafe {
170                    entity.insert_by_ids(&to_insert_ids, to_insert_ptr.into_iter());
171                }
172
173                println!("Entity spawned with id: {}", entity.id());
174            }
175            "q" => {
176                let mut builder = QueryBuilder::<FilteredEntityMut>::new(&mut world);
177                parse_query(rest, &mut builder, &component_names);
178                let mut query = builder.build();
179                query.iter_mut(&mut world).for_each(|filtered_entity| {
180                    let terms = filtered_entity
181                        .access()
182                        .try_iter_access()
183                        .unwrap()
184                        .map(|component_access| {
185                            let id = *component_access.index();
186                            let ptr = filtered_entity.get_by_id(id).unwrap();
187                            let info = component_info.get(&id).unwrap();
188                            let len = info.layout().size() / size_of::<u64>();
189
190                            // SAFETY:
191                            // - All components are created with layout [u64]
192                            // - len is calculated from the component descriptor
193                            let data = unsafe {
194                                std::slice::from_raw_parts_mut(
195                                    ptr.assert_unique().as_ptr().cast::<u64>(),
196                                    len,
197                                )
198                            };
199
200                            // If we have write access, increment each value once
201                            if matches!(component_access, ComponentAccessKind::Exclusive(_)) {
202                                data.iter_mut().for_each(|data| {
203                                    *data += 1;
204                                });
205                            }
206
207                            format!("{}: {:?}", info.name(), data[0..len].to_vec())
208                        })
209                        .collect::<Vec<_>>()
210                        .join(", ");
211
212                    println!("{}: {}", filtered_entity.id(), terms);
213                });
214            }
215            "e" => {
216                rest.split(',').for_each(|event| {
217                    let name = event.trim();
218                    if name.is_empty() {
219                        return;
220                    }
221
222                    // Register a ComponentId for this event, no Rust type needed.
223                    // SAFETY: ZST with no drop
224                    let event_component_id = world.register_component_with_descriptor(unsafe {
225                        ComponentDescriptor::new_with_layout(
226                            format!("event:{name}"),
227                            StorageType::Table,
228                            Layout::new::<()>(),
229                            None,
230                            false,
231                            ComponentCloneBehavior::Ignore,
232                            None,
233                        )
234                    });
235                    // SAFETY: event_component_id was just registered for this event
236                    let event_key = unsafe { EventKey::new(event_component_id) };
237                    event_names.insert(name.to_string(), event_key);
238
239                    // Build a dynamic observer that prints when the event fires.
240                    let runner: ObserverRunner = |mut world, _observer, ctx, _event, _trigger| {
241                        println!("  Observer fired!");
242                        if let Some(mut counts) = world.get_resource_mut::<EventFireCount>() {
243                            *counts.0.entry(ctx.event_key).or_insert(0) += 1;
244                        }
245                    };
246
247                    // SAFETY: event_key was just registered, runner ignores pointers
248                    let observer =
249                        unsafe { Observer::with_dynamic_runner(runner).with_event_key(event_key) };
250                    world.spawn(observer);
251
252                    println!(
253                        "Event '{name}' registered (key: {}) with a dynamic observer",
254                        event_component_id.index()
255                    );
256                });
257
258                // Ensure the counter resource exists.
259                world.init_resource::<EventFireCount>();
260            }
261            "t" => {
262                let name = rest.trim();
263                let Some(&event_key) = event_names.get(name) else {
264                    println!(
265                        "Event '{name}' does not exist. Register it first with 'event {name}'"
266                    );
267                    continue;
268                };
269
270                let mut event_data = ();
271                let mut trigger_data = ();
272                // SAFETY: event_key was registered in this world, both pointers are valid ZSTs
273                unsafe {
274                    world.trigger_dynamic(
275                        event_key,
276                        PtrMut::from(&mut event_data),
277                        PtrMut::from(&mut trigger_data),
278                    );
279                }
280
281                let count = world
282                    .get_resource::<EventFireCount>()
283                    .map_or(0, |c| c.0.get(&event_key).copied().unwrap_or(0));
284                println!("Event '{name}' triggered ({count} fires)");
285            }
286            _ => continue,
287        }
288    }
289}
Source

pub fn get_resource_ref<R>(&self) -> Option<Ref<'_, R>>
where R: Resource,

Gets a reference including change detection to the resource of the given type if it exists.

Source

pub fn get_resource_mut<R>(&mut self) -> Option<Mut<'_, R>>
where R: Resource,

Gets a mutable reference to the resource of the given type if it exists

Examples found in repository?
examples/showcase/loading_screen.rs (line 301)
300    fn update_pipelines_ready(mut main_world: ResMut<MainWorld>, pipelines: Res<PipelineCache>) {
301        if let Some(mut pipelines_ready) = main_world.get_resource_mut::<PipelinesReady>() {
302            pipelines_ready.0 = pipelines.waiting_pipelines().count() == 0;
303        }
304    }
Source

pub fn get_resource_or_insert_with<R>( &mut self, func: impl FnOnce() -> R, ) -> Mut<'_, R>
where R: Resource,

Gets a mutable reference to the resource of type T if it exists, otherwise inserts the resource using the result of calling func.

§Example
#[derive(Resource)]
struct MyResource(i32);

let my_res = world.get_resource_or_insert_with(|| MyResource(10));
assert_eq!(my_res.0, 10);
Source

pub fn get_resource_or_init<R>(&mut self) -> Mut<'_, R>
where R: Resource + FromWorld,

Gets a mutable reference to the resource of type T if it exists, otherwise initializes the resource by calling its FromWorld implementation.

§Example
#[derive(Resource)]
struct Foo(i32);

impl Default for Foo {
    fn default() -> Self {
        Self(15)
    }
}

#[derive(Resource)]
struct MyResource(i32);

impl FromWorld for MyResource {
    fn from_world(world: &mut World) -> Self {
        let foo = world.get_resource_or_init::<Foo>();
        Self(foo.0 * 2)
    }
}

let my_res = world.get_resource_or_init::<MyResource>();
assert_eq!(my_res.0, 30);
Source

pub fn non_send_resource<R>(&self) -> &R
where R: 'static,

👎Deprecated since 0.19.0:

use World::non_send

Gets an immutable reference to a non-send resource of the given type, if it exists.

Source

pub fn non_send<R>(&self) -> &R
where R: 'static,

Gets an immutable reference to the non-send data of the given type, if it exists.

§Panics

Panics if the data does not exist. Use get_non_send instead if you want to handle this case.

This function will panic if it isn’t called from the same thread that the resource was inserted from.

Source

pub fn non_send_resource_mut<R>(&mut self) -> Mut<'_, R>
where R: 'static,

👎Deprecated since 0.19.0:

use World::non_send_mut

Gets a mutable reference to a non-send resource of the given type, if it exists.

Source

pub fn non_send_mut<R>(&mut self) -> Mut<'_, R>
where R: 'static,

Gets a mutable reference to the non-send data of the given type, if it exists.

§Panics

Panics if the data does not exist. Use get_non_send_mut instead if you want to handle this case.

This function will panic if it isn’t called from the same thread that the resource was inserted from.

Source

pub fn get_non_send_resource<R>(&self) -> Option<&R>
where R: 'static,

👎Deprecated since 0.19.0:

use World::get_non_send

Gets a reference to a non-send resource of the given type, if it exists. Otherwise returns None.

Source

pub fn get_non_send<R>(&self) -> Option<&R>
where R: 'static,

Gets a reference to the non-send data of the given type, if it exists. Otherwise returns None.

§Panics

This function will panic if it isn’t called from the same thread that the resource was inserted from.

Source

pub fn get_non_send_resource_mut<R>(&mut self) -> Option<Mut<'_, R>>
where R: 'static,

👎Deprecated since 0.19.0:

use World::get_non_send_mut

Gets a mutable reference to a non-send resource of the given type, if it exists. Otherwise returns None.

Source

pub fn get_non_send_mut<R>(&mut self) -> Option<Mut<'_, R>>
where R: 'static,

Gets a mutable reference to the non-send data of the given type, if it exists. Otherwise returns None.

§Panics

This function will panic if it isn’t called from the same thread that the resource was inserted from.

Source

pub fn insert_batch<I, B>(&mut self, batch: I)

For a given batch of (Entity, Bundle) pairs, adds the Bundle of components to each Entity. This is faster than doing equivalent operations one-by-one.

A batch can be any type that implements IntoIterator containing (Entity, Bundle) tuples, such as a Vec<(Entity, Bundle)> or an array [(Entity, Bundle); N].

This will overwrite any previous values of components shared by the Bundle. See World::insert_batch_if_new to keep the old values instead.

§Panics

This function will panic if any of the associated entities do not exist.

For the fallible version, see World::try_insert_batch.

Source

pub fn insert_batch_if_new<I, B>(&mut self, batch: I)

For a given batch of (Entity, Bundle) pairs, adds the Bundle of components to each Entity without overwriting. This is faster than doing equivalent operations one-by-one.

A batch can be any type that implements IntoIterator containing (Entity, Bundle) tuples, such as a Vec<(Entity, Bundle)> or an array [(Entity, Bundle); N].

This is the same as World::insert_batch, but in case of duplicate components it will leave the old values instead of replacing them with new ones.

§Panics

This function will panic if any of the associated entities do not exist.

For the fallible version, see World::try_insert_batch_if_new.

Source

pub fn try_insert_batch<I, B>( &mut self, batch: I, ) -> Result<(), TryInsertBatchError>

For a given batch of (Entity, Bundle) pairs, adds the Bundle of components to each Entity. This is faster than doing equivalent operations one-by-one.

A batch can be any type that implements IntoIterator containing (Entity, Bundle) tuples, such as a Vec<(Entity, Bundle)> or an array [(Entity, Bundle); N].

This will overwrite any previous values of components shared by the Bundle. See World::try_insert_batch_if_new to keep the old values instead.

Returns a TryInsertBatchError if any of the provided entities do not exist.

For the panicking version, see World::insert_batch.

Source

pub fn try_insert_batch_if_new<I, B>( &mut self, batch: I, ) -> Result<(), TryInsertBatchError>

For a given batch of (Entity, Bundle) pairs, adds the Bundle of components to each Entity without overwriting. This is faster than doing equivalent operations one-by-one.

A batch can be any type that implements IntoIterator containing (Entity, Bundle) tuples, such as a Vec<(Entity, Bundle)> or an array [(Entity, Bundle); N].

This is the same as World::try_insert_batch, but in case of duplicate components it will leave the old values instead of replacing them with new ones.

Returns a TryInsertBatchError if any of the provided entities do not exist.

For the panicking version, see World::insert_batch_if_new.

Source

pub fn resource_scope<R, U>( &mut self, f: impl FnOnce(&mut World, Mut<'_, R>) -> U, ) -> U
where R: Resource,

Temporarily removes the requested resource from this World, runs custom user code, then re-adds the resource before returning.

This enables safe simultaneous mutable access to both a resource and the rest of the World. For more complex access patterns, consider using SystemState.

§Panics

Panics if the resource does not exist. Use try_resource_scope instead if you want to handle this case.

§Example
use bevy_ecs::prelude::*;
#[derive(Resource)]
struct A(u32);
#[derive(Component)]
struct B(u32);
let mut world = World::new();
world.insert_resource(A(1));
let entity = world.spawn(B(1)).id();

world.resource_scope(|world, mut a: Mut<A>| {
    let b = world.get_mut::<B>(entity).unwrap();
    a.0 += b.0;
});
assert_eq!(world.get_resource::<A>().unwrap().0, 2);
§Note

If the world’s resource metadata is cleared within the scope, such as by calling World::clear_resources or World::clear_all, the resource will not be re-inserted at the end of the scope.

Source

pub fn try_resource_scope<R, U>( &mut self, f: impl FnOnce(&mut World, Mut<'_, R>) -> U, ) -> Option<U>
where R: Resource,

Temporarily removes the requested resource from this World if it exists, runs custom user code, then re-adds the resource before returning. Returns None if the resource does not exist in this World.

This enables safe simultaneous mutable access to both a resource and the rest of the World. For more complex access patterns, consider using SystemState.

See also resource_scope.

§Note

If the world’s resource metadata is cleared within the scope, such as by calling World::clear_resources or World::clear_all, the resource will not be re-inserted at the end of the scope.

Source

pub fn write_message<M>(&mut self, message: M) -> Option<MessageId<M>>
where M: Message,

Writes a Message. This method returns the MessageId of the written message, or None if the message could not be written.

Examples found in repository?
examples/app/persisting_preferences.rs (line 136)
135    fn apply(self, world: &mut World) {
136        world.write_message(AppExit::Success);
137    }
More examples
Hide additional examples
examples/window/persisting_window_settings.rs (line 144)
143    fn apply(self, world: &mut World) {
144        world.write_message(AppExit::Success);
145    }
examples/app/render_recovery.rs (line 133)
106fn input(
107    input: Res<ButtonInput<Key>>,
108    mut error: ResMut<RenderError>,
109    mut handler: ResMut<RenderErrorHandler>,
110) {
111    *error = RenderError::None;
112    if input.just_pressed(Key::Character("o".into())) {
113        *error = RenderError::OutOfMemory;
114    }
115    if input.just_pressed(Key::Character("v".into())) {
116        *error = RenderError::Validation;
117    }
118    if input.just_pressed(Key::Character("d".into())) {
119        *error = RenderError::DeviceLost;
120    }
121    if input.just_pressed(Key::Character("l".into())) {
122        *error = RenderError::Loop;
123    }
124
125    if input.just_pressed(Key::Character("1".into())) {
126        *handler = RenderErrorHandler(|_, _, _| RenderErrorPolicy::Ignore);
127    }
128    if input.just_pressed(Key::Character("2".into())) {
129        *handler = RenderErrorHandler(|error, _, _| panic!("Rendering error {error:?}"));
130    }
131    if input.just_pressed(Key::Character("3".into())) {
132        *handler = RenderErrorHandler(|_, main_world, _| {
133            main_world.write_message(AppExit::error());
134            RenderErrorPolicy::StopRendering
135        });
136    }
137    if input.just_pressed(Key::Character("4".into())) {
138        *handler = RenderErrorHandler(|_, _, _| RenderErrorPolicy::StopRendering);
139    }
140    if input.just_pressed(Key::Character("5".into())) {
141        *handler = RenderErrorHandler(|_, _, _| RenderErrorPolicy::Recover(default()));
142    }
143}
Source

pub fn write_message_default<M>(&mut self) -> Option<MessageId<M>>
where M: Message + Default,

Writes the default value of the Message of type M. This method returns the MessageId of the written message, or None if the event could not be written.

Source

pub fn write_message_batch<M>( &mut self, messages: impl IntoIterator<Item = M>, ) -> Option<WriteBatchIds<M>>
where M: Message,

Writes a batch of Messages from an iterator. This method returns the IDs of the written messages, or None if the events could not be written.

Source

pub unsafe fn insert_resource_by_id( &mut self, component_id: ComponentId, value: OwningPtr<'_>, caller: MaybeLocation, )

Inserts a new resource with the given value. Will replace the value if it already existed.

You should prefer to use the typed API World::insert_resource where possible and only use this in cases where the actual types are not known at compile time.

§Safety

The value referenced by value must be valid for the given ComponentId of this world.

Source

pub unsafe fn insert_non_send_by_id( &mut self, component_id: ComponentId, value: OwningPtr<'_>, caller: MaybeLocation, )

Inserts new !Send data with the given value. Will replace the value if it already existed.

You should prefer to use the typed API World::insert_non_send where possible and only use this in cases where the actual types are not known at compile time.

§Panics

If a value is already present, this function will panic if not called from the same thread that the original value was inserted from.

§Safety

The value referenced by value must be valid for the given ComponentId of this world.

Source

pub fn flush(&mut self)

Flushes queued entities and commands.

Queued entities will be spawned, and then commands will be applied.

Source

pub fn increment_change_tick(&mut self) -> Tick

Increments the world’s current change tick and returns the old value.

If you need to call this method, but do not have &mut access to the world, consider using as_unsafe_world_cell_readonly to obtain an UnsafeWorldCell and calling increment_change_tick on that. Note that this can be done in safe code, despite the name of the type.

Source

pub fn read_change_tick(&self) -> Tick

Reads the current change tick of this world.

If you have exclusive (&mut) access to the world, consider using change_tick(), which is more efficient since it does not require atomic synchronization.

Source

pub fn change_tick(&mut self) -> Tick

Reads the current change tick of this world.

This does the same thing as read_change_tick(), only this method is more efficient since it does not require atomic synchronization.

Source

pub fn last_change_tick(&self) -> Tick

When called from within an exclusive system (a System that takes &mut World as its first parameter), this method returns the Tick indicating the last time the exclusive system was run.

Otherwise, this returns the Tick indicating the last time that World::clear_trackers was called.

Source

pub fn last_change_tick_scope<T>( &mut self, last_change_tick: Tick, f: impl FnOnce(&mut World) -> T, ) -> T

Sets World::last_change_tick() to the specified value during a scope. When the scope terminates, it will return to its old value.

This is useful if you need a region of code to be able to react to earlier changes made in the same system.

§Examples
// This function runs an update loop repeatedly, allowing each iteration of the loop
// to react to changes made in the previous loop iteration.
fn update_loop(
    world: &mut World,
    mut update_fn: impl FnMut(&mut World) -> std::ops::ControlFlow<()>,
) {
    let mut last_change_tick = world.last_change_tick();

    // Repeatedly run the update function until it requests a break.
    loop {
        let control_flow = world.last_change_tick_scope(last_change_tick, |world| {
            // Increment the change tick so we can detect changes from the previous update.
            last_change_tick = world.change_tick();
            world.increment_change_tick();

            // Update once.
            update_fn(world)
        });

        // End the loop when the closure returns `ControlFlow::Break`.
        if control_flow.is_break() {
            break;
        }
    }
}
Source

pub fn check_change_ticks(&mut self) -> Option<CheckChangeTicks>

Iterates all component change ticks and clamps any older than MAX_CHANGE_AGE. This also triggers CheckChangeTicks observers and returns the same event here.

Calling this method prevents Ticks overflowing and thus prevents false positives when comparing them.

Note: Does nothing and returns None if the World counter has not been incremented at least CHECK_TICK_THRESHOLD times since the previous pass.

Source

pub fn clear_all(&mut self)

Clears all entities, resources, and non-send data. This invalidates all Entity and resource fetches such as Res, ResMut

Source

pub fn clear_entities(&mut self)

Despawns all entities in this World.

Note: This includes all resources, as they are stored as components. Any resource fetch to this World will fail unless they are re-initialized, including engine-internal resources that are only initialized on app/world construction.

This can easily cause systems expecting certain resources to immediately start panicking. Use with caution.

Source

pub fn clear_resources(&mut self)

Clears all resources in this World.

Note: Any resource fetch to this World will fail unless they are re-initialized, including engine-internal resources that are only initialized on app/world construction.

This can easily cause systems expecting certain resources to immediately start panicking. Use with caution.

Source

pub fn clear_non_send(&mut self)

Clears all non-send data in this World.

Source

pub fn register_bundle<B>(&mut self) -> &BundleInfo
where B: Bundle,

Registers all of the components in the given Bundle and returns both the component ids and the bundle id.

This is largely equivalent to calling register_component on each component in the bundle.

Source

pub fn register_dynamic_bundle( &mut self, component_ids: &[ComponentId], ) -> &BundleInfo

Registers the given ComponentIds as a dynamic bundle and returns both the required component ids and the bundle id.

Note that the components need to be registered first, this function only creates a bundle combining them. Components can be registered with World::register_component/_with_descriptor.

You should prefer to use the typed API World::register_bundle where possible and only use this in cases where not all of the actual types are known at compile time.

§Panics

This function will panic if any of the provided component ids do not belong to a component known to this World.

Source

pub fn fallback_error_handler(&self) -> fn(BevyError, ErrorContext)

Convenience method for accessing the world’s fallback error handler, which can be overwritten with FallbackErrorHandler.

Source§

impl World

Source

pub fn get_resource_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>>

Gets a pointer to the resource with the id ComponentId if it exists. The returned pointer must not be used to modify the resource, and must not be dereferenced after the immutable borrow of the World ends.

You should prefer to use the typed API World::get_resource where possible and only use this in cases where the actual types are not known at compile time.

Source

pub fn get_resource_mut_by_id( &mut self, component_id: ComponentId, ) -> Option<MutUntyped<'_>>

Gets a pointer to the resource with the id ComponentId if it exists. The returned pointer may be used to modify the resource, as long as the mutable borrow of the World is still valid.

You should prefer to use the typed API World::get_resource_mut where possible and only use this in cases where the actual types are not known at compile time.

Source

pub fn iter_resources(&self) -> impl Iterator<Item = (&ComponentInfo, Ptr<'_>)>

Iterates over all resources in the world.

The returned iterator provides lifetimed, but type-unsafe pointers. Actually reading the contents of each resource will require the use of unsafe code.

§Examples
§Printing the size of all resources
let mut total = 0;
for (info, _) in world.iter_resources() {
   println!("Resource: {}", info.name());
   println!("Size: {} bytes", info.layout().size());
   total += info.layout().size();
}
println!("Total size: {} bytes", total);
§Dynamically running closures for resources matching specific TypeIds
// In this example, `A` and `B` are resources. We deliberately do not use the
// `bevy_reflect` crate here to showcase the low-level [`Ptr`] usage. You should
// probably use something like `ReflectFromPtr` in a real-world scenario.

// Create the hash map that will store the closures for each resource type
let mut closures: HashMap<TypeId, Box<dyn Fn(&Ptr<'_>)>> = HashMap::default();

// Add closure for `A`
closures.insert(TypeId::of::<A>(), Box::new(|ptr| {
    // SAFETY: We assert ptr is the same type of A with TypeId of A
    let a = unsafe { &ptr.deref::<A>() };
    // ... do something with `a` here
}));

// Add closure for `B`
closures.insert(TypeId::of::<B>(), Box::new(|ptr| {
    // SAFETY: We assert ptr is the same type of B with TypeId of B
    let b = unsafe { &ptr.deref::<B>() };
    // ... do something with `b` here
}));

// Iterate all resources, in order to run the closures for each matching resource type
for (info, ptr) in world.iter_resources() {
    let Some(type_id) = info.type_id() else {
       // It's possible for resources to not have a `TypeId` (e.g. non-Rust resources
       // dynamically inserted via a scripting language) in which case we can't match them.
       continue;
    };

    let Some(closure) = closures.get(&type_id) else {
       // No closure for this resource type, skip it.
       continue;
    };

    // Run the closure for the resource
    closure(&ptr);
}
Source

pub fn iter_resources_mut( &mut self, ) -> impl Iterator<Item = (&ComponentInfo, MutUntyped<'_>)>

Mutably iterates over all resources in the world.

The returned iterator provides lifetimed, but type-unsafe pointers. Actually reading from or writing to the contents of each resource will require the use of unsafe code.

§Example
// In this example, `A` and `B` are resources. We deliberately do not use the
// `bevy_reflect` crate here to showcase the low-level `MutUntyped` usage. You should
// probably use something like `ReflectFromPtr` in a real-world scenario.

// Create the hash map that will store the mutator closures for each resource type
let mut mutators: HashMap<TypeId, Box<dyn Fn(&mut MutUntyped<'_>)>> = HashMap::default();

// Add mutator closure for `A`
mutators.insert(TypeId::of::<A>(), Box::new(|mut_untyped| {
    // Note: `MutUntyped::as_mut()` automatically marks the resource as changed
    // for ECS change detection, and gives us a `PtrMut` we can use to mutate the resource.
    // SAFETY: We assert ptr is the same type of A with TypeId of A
    let a = unsafe { &mut mut_untyped.as_mut().deref_mut::<A>() };
    // ... mutate `a` here
}));

// Add mutator closure for `B`
mutators.insert(TypeId::of::<B>(), Box::new(|mut_untyped| {
    // SAFETY: We assert ptr is the same type of B with TypeId of B
    let b = unsafe { &mut mut_untyped.as_mut().deref_mut::<B>() };
    // ... mutate `b` here
}));

// Iterate all resources, in order to run the mutator closures for each matching resource type
for (info, mut mut_untyped) in world.iter_resources_mut() {
    let Some(type_id) = info.type_id() else {
       // It's possible for resources to not have a `TypeId` (e.g. non-Rust resources
       // dynamically inserted via a scripting language) in which case we can't match them.
       continue;
    };

    let Some(mutator) = mutators.get(&type_id) else {
       // No mutator closure for this resource type, skip it.
       continue;
    };

    // Run the mutator closure for the resource
    mutator(&mut mut_untyped);
}
Source

pub fn get_non_send_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>>

Gets a pointer to !Send data with the id ComponentId if it exists. The returned pointer must not be used to modify the resource, and must not be dereferenced after the immutable borrow of the World ends.

You should prefer to use the typed API World::get_non_send where possible and only use this in cases where the actual types are not known at compile time.

§Panics

This function will panic if it isn’t called from the same thread that the data was inserted from.

Source

pub fn get_non_send_mut_by_id( &mut self, component_id: ComponentId, ) -> Option<MutUntyped<'_>>

Gets mutable access to !Send data with the id ComponentId if it exists. The returned pointer may be used to modify the data, as long as the mutable borrow of the World is still valid.

You should prefer to use the typed API World::get_non_send_mut where possible and only use this in cases where the actual types are not known at compile time.

§Panics

This function will panic if it isn’t called from the same thread that the data was inserted from.

Source

pub fn remove_resource_by_id(&mut self, component_id: ComponentId) -> bool

Removes the resource of a given type, if it exists. Returns true if the resource is successfully removed and false if the entity does not exist.

You should prefer to use the typed API World::remove_resource where possible and only use this in cases where the actual types are not known at compile time.

Source

pub fn remove_non_send_by_id(&mut self, component_id: ComponentId) -> Option<()>

Removes the non-send data of a given type, if it exists. Otherwise returns None.

You should prefer to use the typed API World::remove_non_send where possible and only use this in cases where the actual types are not known at compile time.

§Panics

This function will panic if it isn’t called from the same thread that the data was inserted from.

Source

pub fn get_by_id( &self, entity: Entity, component_id: ComponentId, ) -> Option<Ptr<'_>>

Retrieves an immutable untyped reference to the given entity’s Component of the given ComponentId. Returns None if the entity does not have a Component of the given type.

You should prefer to use the typed API World::get_mut where possible and only use this in cases where the actual types are not known at compile time.

§Panics

This function will panic if it isn’t called from the same thread that the resource was inserted from.

Source

pub fn get_mut_by_id( &mut self, entity: Entity, component_id: ComponentId, ) -> Option<MutUntyped<'_>>

Retrieves a mutable untyped reference to the given entity’s Component of the given ComponentId. Returns None if the entity does not have a Component of the given type.

You should prefer to use the typed API World::get_mut where possible and only use this in cases where the actual types are not known at compile time.

Source§

impl World

Source

pub fn add_schedule(&mut self, schedule: Schedule)

Adds the specified Schedule to the world. If a schedule already exists with the same label, it will be replaced.

The schedule can later be run by calling .run_schedule(label) or by directly accessing the Schedules resource.

The Schedules resource will be initialized if it does not already exist.

An alternative to this is to call Schedules::add_systems() with some ScheduleLabel and let the schedule for that label be created if it does not already exist.

Source

pub fn try_schedule_scope<R>( &mut self, label: impl ScheduleLabel, f: impl FnOnce(&mut World, &mut Schedule) -> R, ) -> Result<R, TryRunScheduleError>

Temporarily removes the schedule associated with label from the world, runs user code, and finally re-adds the schedule. This returns a TryRunScheduleError if there is no schedule associated with label.

The Schedule is fetched from the Schedules resource of the world by its label, and system state is cached.

For simple cases where you just need to call the schedule once, consider using World::try_run_schedule instead. For other use cases, see the example on World::schedule_scope.

Source

pub fn schedule_scope<R>( &mut self, label: impl ScheduleLabel, f: impl FnOnce(&mut World, &mut Schedule) -> R, ) -> R

Temporarily removes the schedule associated with label from the world, runs user code, and finally re-adds the schedule.

The Schedule is fetched from the Schedules resource of the world by its label, and system state is cached.

§Examples
// Run the schedule five times.
world.schedule_scope(MySchedule, |world, schedule| {
    for _ in 0..5 {
        schedule.run(world);
    }
});

For simple cases where you just need to call the schedule once, consider using World::run_schedule instead.

§Panics

If the requested schedule does not exist.

Source

pub fn try_run_schedule( &mut self, label: impl ScheduleLabel, ) -> Result<(), TryRunScheduleError>

Attempts to run the Schedule associated with the label a single time, and returns a TryRunScheduleError if the schedule does not exist.

The Schedule is fetched from the Schedules resource of the world by its label, and system state is cached.

For simple testing use cases, call Schedule::run(&mut world) instead.

Examples found in repository?
examples/state/custom_transitions.rs (line 113)
95    fn run_reenter<S: States>(transition: In<Option<StateTransitionEvent<S>>>, world: &mut World) {
96        // We return early if no transition event happened.
97        let Some(transition) = transition.0 else {
98            return;
99        };
100
101        // If we wanted to ignore identity transitions,
102        // we'd compare `exited` and `entered` here,
103        // and return if they were the same.
104
105        // We check if we actually entered a state.
106        // A [`None`] would indicate that the state was removed from the world.
107        // This only happens in the case of [`SubStates`] and [`ComputedStates`].
108        let Some(entered) = transition.entered else {
109            return;
110        };
111
112        // If all conditions are valid, we run our custom schedule.
113        let _ = world.try_run_schedule(OnReenter(entered));
114
115        // If you want to overwrite the default `OnEnter` behavior to act like re-enter,
116        // you can do so by running the `OnEnter` schedule here. Note that you don't want
117        // to run `OnEnter` when the default behavior does so.
118        // ```
119        // if transition.entered != transition.exited {
120        //     return;
121        // }
122        // let _ = world.try_run_schedule(OnReenter(entered));
123        // ```
124    }
125
126    /// Custom schedule that will behave like [`OnExit`], but run on identity transitions.
127    #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)]
128    pub struct OnReexit<S: States>(pub S);
129
130    fn run_reexit<S: States>(transition: In<Option<StateTransitionEvent<S>>>, world: &mut World) {
131        let Some(transition) = transition.0 else {
132            return;
133        };
134        let Some(exited) = transition.exited else {
135            return;
136        };
137
138        let _ = world.try_run_schedule(OnReexit(exited));
139    }
Source

pub fn run_schedule(&mut self, label: impl ScheduleLabel)

Runs the Schedule associated with the label a single time.

The Schedule is fetched from the Schedules resource of the world by its label, and system state is cached.

For simple testing use cases, call Schedule::run(&mut world) instead. This avoids the need to create a unique ScheduleLabel.

§Panics

If the requested schedule does not exist.

Source

pub fn allow_ambiguous_component<T>(&mut self)
where T: Component,

Ignore system order ambiguities caused by conflicts on Components of type T.

Source

pub fn allow_ambiguous_resource<T>(&mut self)
where T: Resource,

Ignore system order ambiguities caused by conflicts on Resources of type T.

Trait Implementations§

Source§

impl Debug for World

Source§

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

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

impl Default for World

Source§

fn default() -> World

Returns the “default value” for a type. Read more
Source§

impl DirectAssetAccessExt for World

Source§

fn add_asset<'a, A>(&mut self, asset: impl Into<A>) -> Handle<A>
where A: Asset,

Insert an asset similarly to Assets::add.

§Panics

If self doesn’t have an AssetServer resource initialized yet.

Source§

fn load_asset<'a, A>(&self, path: impl Into<AssetPath<'a>>) -> Handle<A>
where A: Asset,

Load an asset similarly to AssetServer::load.

§Panics

If self doesn’t have an AssetServer resource initialized yet.

Source§

fn load_builder(&self) -> LoadBuilder<'_>

Creates a new LoadBuilder similar to AssetServer::load_builder.

§Panics

If self doesn’t have an AssetServer resource initialized yet.

Source§

fn load_asset_with_settings<'a, A, S>( &self, path: impl Into<AssetPath<'a>>, settings: impl Fn(&mut S) + Send + Sync + 'static, ) -> Handle<A>
where A: Asset, S: Settings,

👎Deprecated:

Use world.load_builder().with_settings(settings).load(path)

Load an asset with settings, similarly to AssetServer::load_with_settings.

§Panics

If self doesn’t have an AssetServer resource initialized yet.

Source§

impl Drop for World

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<'w> From<&'w World> for FilteredResources<'w, 'static>

Source§

fn from(value: &'w World) -> FilteredResources<'w, 'static>

Converts to this type from the input type.
Source§

impl<'w> From<&'w World> for UnsafeWorldCell<'w>

Source§

fn from(value: &'w World) -> UnsafeWorldCell<'w>

Converts to this type from the input type.
Source§

impl<'w> From<&'w mut World> for DeferredWorld<'w>

Source§

fn from(world: &'w mut World) -> DeferredWorld<'w>

Converts to this type from the input type.
Source§

impl<'w> From<&'w mut World> for FilteredResources<'w, 'static>

Source§

fn from(value: &'w mut World) -> FilteredResources<'w, 'static>

Converts to this type from the input type.
Source§

impl<'w> From<&'w mut World> for FilteredResourcesMut<'w, 'static>

Source§

fn from(value: &'w mut World) -> FilteredResourcesMut<'w, 'static>

Converts to this type from the input type.
Source§

impl<'w> From<&'w mut World> for UnsafeWorldCell<'w>

Source§

fn from(value: &'w mut World) -> UnsafeWorldCell<'w>

Converts to this type from the input type.
Source§

impl GetAssetServer for World

Source§

impl IsFocused for World

Source§

fn is_focused(&self, entity: Entity) -> bool

Returns true if the given entity has input focus.
Source§

fn is_focus_within(&self, entity: Entity) -> bool

Returns true if the given entity or any of its descendants has input focus. Read more
Source§

fn is_focus_visible(&self, entity: Entity) -> bool

Returns true if the given entity has input focus and the focus indicator should be visible.
Source§

fn is_focus_within_visible(&self, entity: Entity) -> bool

Returns true if the given entity, or any descendant, has input focus and the focus indicator should be visible.
Source§

impl RunSystemOnce for &mut World

Source§

fn run_system_once_with<T, In, Out, Marker>( self, system: T, input: <<<T as IntoSystem<In, Out, Marker>>::System as System>::In as SystemInput>::Inner<'_>, ) -> Result<Out, RunSystemError>
where T: IntoSystem<In, Out, Marker>, In: SystemInput,

Tries to run a system with given input and apply deferred parameters.
Source§

fn run_system_once<T, Out, Marker>( self, system: T, ) -> Result<Out, RunSystemError>
where T: IntoSystem<(), Out, Marker>,

Tries to run a system and apply its deferred parameters.
Source§

impl SystemParam for &World

Source§

type State = ()

Used to store data which persists across invocations of a system.
Source§

type Item<'w, 's> = &'w World

The item type returned when constructing this system param. The value of this associated type should be Self, instantiated with new lifetimes. Read more
Source§

fn init_state(_world: &mut World) -> <&World as SystemParam>::State

Creates a new instance of this param’s State.
Source§

fn init_access( _state: &<&World as SystemParam>::State, _system_meta: &mut SystemMeta, component_access_set: &mut FilteredAccessSet, _world: &mut World, )

Registers any World access used by this SystemParam. Read more
Source§

unsafe fn get_param<'w, 's>( _state: &'s mut <&World as SystemParam>::State, _system_meta: &SystemMeta, world: UnsafeWorldCell<'w>, _change_tick: Tick, ) -> Result<<&World as SystemParam>::Item<'w, 's>, SystemParamValidationError>

Creates a parameter to be passed into a SystemParamFunction. Read more
Source§

fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World)

Applies any deferred mutations stored in this SystemParam’s state. This is used to apply Commands during ApplyDeferred.
Source§

fn queue( state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld<'_>, )

Queues any deferred mutations to be applied at the next ApplyDeferred.
Source§

impl WorldSceneExt for World

Source§

fn spawn_scene<S>( &mut self, scene: S, ) -> Result<EntityWorldMut<'_>, SpawnSceneError>
where S: Scene,

Spawns the given Scene immediately. This will resolve the Scene (using Scene::resolve). If that fails (for example, if there are dependencies that have not been loaded yet), it will return a SpawnSceneError. If resolving the Scene is successful, the scene will be spawned. Read more
Source§

fn queue_spawn_scene<S>(&mut self, scene: S) -> EntityWorldMut<'_>
where S: Scene,

Queues the scene to be spawned. This will evaluate the scene’s dependencies (via Scene::register_dependencies) and queue it to be resolved and spawned after all of the dependencies have been loaded. If a SpawnSceneError occurs, it will be logged as an error. Read more
Source§

fn spawn_scene_list<L>( &mut self, scenes: L, ) -> Result<Vec<Entity>, SpawnSceneError>
where L: SceneList,

Spawns the given SceneList immediately. This will resolve the scene list (using SceneList::resolve_list). If that fails (for example, if there are dependencies that have not been loaded yet), it will return a SpawnSceneError. If resolving the SceneList is successful, the scene list will be spawned. Read more
Source§

fn queue_spawn_scene_list<L>(&mut self, scenes: L)
where L: SceneList,

Queues the scene_list to be spawned. This will evaluate the scene_list’s dependencies (via Scene::register_dependencies) and queue it to be resolved and spawned after all of the dependencies have been loaded. If a SpawnSceneError occurs, it will be logged as an error. Read more
Source§

impl<'w> ReadOnlySystemParam for &'w World

Source§

impl Send for World

Source§

impl Sync for World

Auto Trait Implementations§

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, U> AsBindGroupShaderType<U> for T
where U: ShaderType, &'a T: for<'a> Into<U>,

Source§

fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U

Return the T ShaderType for self. When used in AsBindGroup derives, it is safe to assume that all images in self exist.
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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> Downcast<T> for T

§

fn downcast(&self) -> &T

§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> DowncastSend for T
where T: Any + Send,

§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<S> FromSample<S> for S

§

fn from_sample_(s: S) -> S

Source§

impl<T> FromWorld for T
where T: Default,

Source§

fn from_world(_world: &mut World) -> T

Creates Self using default().

§

impl<T, W> HasTypeWitness<W> for T
where W: MakeTypeWitness<Arg = T>, T: ?Sized,

§

const WITNESS: W = W::MAKE

A constant of the type witness
§

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

§

const TYPE_EQ: TypeEq<T, <T as Identity>::Type> = TypeEq::NEW

Proof that Self is the same type as Self::Type, provides methods for casting between Self and Self::Type.
§

type Type = T

The same type as Self, used to emulate type equality bounds (T == U) with associated type equality constraints (T: Identity<Type = U>).
§

impl<T> InitializeFromFunction<T> for T

§

fn initialize_from_function(f: fn() -> T) -> T

Create an instance of this type from an initialization function
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoResult<T> for T

Source§

fn into_result(self) -> Result<T, RunSystemError>

Converts this type into the system output type.
§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

§

fn into_sample(self) -> T

Source§

impl<A> Is for A
where A: Any,

Source§

fn is<T>() -> bool
where T: Any,

Checks if the current type “is” another type, using a TypeId equality comparison. This is most useful in the context of generic logic. Read more
§

impl<T> NoneValue for T
where T: Default,

§

type NoneType = T

§

fn null_value() -> T

The none-equivalent value.
§

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

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<R, P> ReadPrimitive<R> for P
where R: Read + ReadEndian<P>, P: Default,

Source§

fn read_from_little_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_little_endian().
Source§

fn read_from_big_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_big_endian().
Source§

fn read_from_native_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_native_endian().
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<Ret> SpawnIfAsync<(), Ret> for Ret

§

fn spawn(self) -> Ret

Spawn the value into the dioxus runtime if it is an async block
§

impl<T, O> SuperFrom<T> for O
where O: From<T>,

§

fn super_from(input: T) -> O

Convert from a type to another type.
§

impl<T, O, M> SuperInto<O, M> for T
where O: SuperFrom<T, M>,

§

fn super_into(self) -> O

Convert from a type to another type.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

§

fn to_sample_(self) -> U

§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. 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.
§

impl<T> Upcast<T> for T

§

fn upcast(&self) -> Option<&T>

§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ConditionalSend for T
where T: Send,

§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> Settings for T
where T: 'static + Send + Sync,

§

impl<T> WasmNotSend for T
where T: Send,

§

impl<T> WasmNotSendSync for T
where T: WasmNotSend + WasmNotSync,

§

impl<T> WasmNotSync for T
where T: Sync,