Struct bevy_render::MainWorld
source · pub struct MainWorld(/* private fields */);
Expand description
The simulation World
of the application, stored as a resource.
This resource is only available during ExtractSchedule
and not
during command application of that schedule.
See Extract
for more details.
Methods from Deref<Target = World>§
sourcepub fn observe<E, B, M>(
&mut self,
system: impl IntoObserverSystem<E, B, M>
) -> EntityWorldMut<'_>
pub fn observe<E, B, M>( &mut self, system: impl IntoObserverSystem<E, B, M> ) -> EntityWorldMut<'_>
sourcepub fn trigger(&mut self, event: impl Event)
pub fn trigger(&mut self, event: impl Event)
Triggers the given event
, which will run any observers watching for it.
sourcepub fn trigger_targets(
&mut self,
event: impl Event,
targets: impl TriggerTargets
)
pub fn trigger_targets( &mut self, event: impl Event, targets: impl TriggerTargets )
Triggers the given event
for the given targets
, which will run any observers watching for it.
sourcepub fn register_system<I, O, M, S>(&mut self, system: S) -> SystemId<I, O>where
I: 'static,
O: 'static,
S: IntoSystem<I, O, M> + 'static,
pub fn register_system<I, O, M, S>(&mut self, system: S) -> SystemId<I, O>where
I: 'static,
O: 'static,
S: IntoSystem<I, O, M> + 'static,
Registers a system and returns a SystemId
so it can later be called by World::run_system
.
It’s possible to register the same systems more than once, they’ll be stored separately.
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.
sourcepub fn register_boxed_system<I, O>(
&mut self,
system: Box<dyn System<In = I, Out = O>>
) -> SystemId<I, O>where
I: 'static,
O: 'static,
pub fn register_boxed_system<I, O>(
&mut self,
system: Box<dyn System<In = I, Out = O>>
) -> SystemId<I, O>where
I: '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
.
sourcepub fn remove_system<I, O>(
&mut self,
id: SystemId<I, O>
) -> Result<RemovedSystem<I, O>, RegisteredSystemError<I, O>>where
I: 'static,
O: 'static,
pub fn remove_system<I, O>(
&mut self,
id: SystemId<I, O>
) -> Result<RemovedSystem<I, O>, RegisteredSystemError<I, O>>where
I: '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.
sourcepub fn run_system<O>(
&mut self,
id: SystemId<(), O>
) -> Result<O, RegisteredSystemError<(), O>>where
O: 'static,
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.
In order to run a chained system with an input, use World::run_system_with_input
instead.
§Limitations
- Stored systems cannot be recursive, they cannot call themselves through
Commands::run_system
.
§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"));
}
sourcepub fn run_system_with_input<I, O>(
&mut self,
id: SystemId<I, O>,
input: I
) -> Result<O, RegisteredSystemError<I, O>>where
I: 'static,
O: 'static,
pub fn run_system_with_input<I, O>(
&mut self,
id: SystemId<I, O>,
input: I
) -> Result<O, RegisteredSystemError<I, O>>where
I: '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
.
§Limitations
- Stored systems cannot be recursive, they cannot call themselves through
Commands::run_system
.
§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_input(counter_one, 1).unwrap(), 1);
assert_eq!(world.run_system_with_input(counter_one, 20).unwrap(), 21);
assert_eq!(world.run_system_with_input(counter_two, 30).unwrap(), 30);
See World::run_system
for more examples.
sourcepub fn as_unsafe_world_cell(&mut self) -> UnsafeWorldCell<'_>
pub fn as_unsafe_world_cell(&mut self) -> UnsafeWorldCell<'_>
Creates a new UnsafeWorldCell
view with complete read+write access.
sourcepub fn as_unsafe_world_cell_readonly(&self) -> UnsafeWorldCell<'_>
pub fn as_unsafe_world_cell_readonly(&self) -> UnsafeWorldCell<'_>
Creates a new UnsafeWorldCell
view with only read access to everything.
sourcepub unsafe fn entities_mut(&mut self) -> &mut Entities
pub unsafe fn entities_mut(&mut self) -> &mut Entities
sourcepub fn archetypes(&self) -> &Archetypes
pub fn archetypes(&self) -> &Archetypes
Retrieves this world’s Archetypes
collection.
sourcepub fn components(&self) -> &Components
pub fn components(&self) -> &Components
Retrieves this world’s Components
collection.
sourcepub fn removed_components(&self) -> &RemovedComponentEvents
pub fn removed_components(&self) -> &RemovedComponentEvents
Retrieves this world’s RemovedComponentEvents
collection
sourcepub fn commands(&mut self) -> Commands<'_, '_>
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
sourcepub fn init_component<T>(&mut self) -> ComponentIdwhere
T: Component,
pub fn init_component<T>(&mut self) -> ComponentIdwhere
T: Component,
Initializes a new Component
type and returns the ComponentId
created for it.
sourcepub fn register_component_hooks<T>(&mut self) -> &mut ComponentHookswhere
T: Component,
pub fn register_component_hooks<T>(&mut self) -> &mut ComponentHookswhere
T: Component,
Returns a mutable reference to the ComponentHooks
for a Component
type.
Will panic if T
exists in any archetypes.
sourcepub fn register_component_hooks_by_id(
&mut self,
id: ComponentId
) -> Option<&mut ComponentHooks>
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.
sourcepub fn init_component_with_descriptor(
&mut self,
descriptor: ComponentDescriptor
) -> ComponentId
pub fn init_component_with_descriptor( &mut self, descriptor: ComponentDescriptor ) -> ComponentId
Initializes a new Component
type and returns the ComponentId
created for it.
This method differs from World::init_component
in that it uses a ComponentDescriptor
to initialize the new component type instead of statically available type information. This
enables the dynamic initialization of new component definitions at runtime for advanced use cases.
While the option to initialize a component from a descriptor is useful in type-erased
contexts, the standard World::init_component
function should always be used instead
when type information is available at compile time.
sourcepub fn component_id<T>(&self) -> Option<ComponentId>where
T: Component,
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::init_component
.
use bevy_ecs::prelude::*;
let mut world = World::new();
#[derive(Component)]
struct ComponentA;
let component_a_id = world.init_component::<ComponentA>();
assert_eq!(component_a_id, world.component_id::<ComponentA>().unwrap())
§See also
sourcepub fn entity(&self, entity: Entity) -> EntityRef<'_>
pub fn entity(&self, entity: Entity) -> EntityRef<'_>
Retrieves an EntityRef
that exposes read-only operations for the given entity
.
This will panic if the entity
does not exist. Use World::get_entity
if you want
to check for entity existence instead of implicitly panic-ing.
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.entity(entity).get::<Position>().unwrap();
assert_eq!(position.x, 0.0);
sourcepub fn entity_mut(&mut self, entity: Entity) -> EntityWorldMut<'_>
pub fn entity_mut(&mut self, entity: Entity) -> EntityWorldMut<'_>
Retrieves an EntityWorldMut
that exposes read and write operations for the given entity
.
This will panic if the entity
does not exist. Use World::get_entity_mut
if you want
to check for entity existence instead of implicitly panic-ing.
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 entity_mut = world.entity_mut(entity);
let mut position = entity_mut.get_mut::<Position>().unwrap();
position.x = 1.0;
sourcepub fn many_entities<const N: usize>(
&mut self,
entities: [Entity; N]
) -> [EntityRef<'_>; N]
pub fn many_entities<const N: usize>( &mut self, entities: [Entity; N] ) -> [EntityRef<'_>; N]
sourcepub fn many_entities_mut<const N: usize>(
&mut self,
entities: [Entity; N]
) -> [EntityMut<'_>; N]
pub fn many_entities_mut<const N: usize>( &mut self, entities: [Entity; N] ) -> [EntityMut<'_>; N]
Gets mutable access to multiple entities at once.
§Panics
If any entities do not exist in the world, or if the same entity is specified multiple times.
§Examples
Disjoint mutable access.
// Disjoint mutable access.
let [entity1, entity2] = world.many_entities_mut([id1, id2]);
Trying to access the same entity multiple times will fail.
world.many_entities_mut([id, id]);
sourcepub fn inspect_entity(&self, entity: Entity) -> Vec<&ComponentInfo>
pub fn inspect_entity(&self, entity: Entity) -> Vec<&ComponentInfo>
Returns the components of an Entity
through ComponentInfo
.
sourcepub fn get_or_spawn(&mut self, entity: Entity) -> Option<EntityWorldMut<'_>>
pub fn get_or_spawn(&mut self, entity: Entity) -> Option<EntityWorldMut<'_>>
Returns an EntityWorldMut
for the given entity
(if it exists) or spawns one if it doesn’t exist.
This will return None
if the entity
exists with a different generation.
§Note
Spawning a specific entity
value is rarely the right choice. Most apps should favor World::spawn
.
This method should generally only be used for sharing entities across apps, and only when they have a
scheme worked out to share an ID space (which doesn’t happen by default).
sourcepub fn get_entity(&self, entity: Entity) -> Option<EntityRef<'_>>
pub fn get_entity(&self, entity: Entity) -> Option<EntityRef<'_>>
Retrieves an EntityRef
that exposes read-only operations for the given entity
.
Returns None
if the entity
does not exist.
Instead of unwrapping the value returned from this function, prefer World::entity
.
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 entity_ref = world.get_entity(entity).unwrap();
let position = entity_ref.get::<Position>().unwrap();
assert_eq!(position.x, 0.0);
sourcepub fn get_many_entities<const N: usize>(
&self,
entities: [Entity; N]
) -> Result<[EntityRef<'_>; N], Entity>
pub fn get_many_entities<const N: usize>( &self, entities: [Entity; N] ) -> Result<[EntityRef<'_>; N], Entity>
Gets an EntityRef
for multiple entities at once.
§Errors
If any entity does not exist in the world.
§Examples
// Getting multiple entities.
let [entity1, entity2] = world.get_many_entities([id1, id2]).unwrap();
// Trying to get a despawned entity will fail.
world.despawn(id2);
assert!(world.get_many_entities([id1, id2]).is_err());
sourcepub fn get_many_entities_dynamic<'w>(
&'w self,
entities: &[Entity]
) -> Result<Vec<EntityRef<'w>>, Entity>
pub fn get_many_entities_dynamic<'w>( &'w self, entities: &[Entity] ) -> Result<Vec<EntityRef<'w>>, Entity>
Gets an EntityRef
for multiple entities at once, whose number is determined at runtime.
§Errors
If any entity does not exist in the world.
§Examples
// Getting multiple entities.
let entities = world.get_many_entities_dynamic(&[id1, id2]).unwrap();
let entity1 = entities.get(0).unwrap();
let entity2 = entities.get(1).unwrap();
// Trying to get a despawned entity will fail.
world.despawn(id2);
assert!(world.get_many_entities_dynamic(&[id1, id2]).is_err());
sourcepub fn iter_entities(&self) -> impl Iterator<Item = EntityRef<'_>>
pub fn iter_entities(&self) -> impl Iterator<Item = EntityRef<'_>>
sourcepub fn iter_entities_mut(&mut self) -> impl Iterator<Item = EntityMut<'_>>
pub fn iter_entities_mut(&mut self) -> impl Iterator<Item = EntityMut<'_>>
Returns a mutable iterator over all entities in the World
.
sourcepub fn get_entity_mut(&mut self, entity: Entity) -> Option<EntityWorldMut<'_>>
pub fn get_entity_mut(&mut self, entity: Entity) -> Option<EntityWorldMut<'_>>
Retrieves an EntityWorldMut
that exposes read and write operations for the given entity
.
Returns None
if the entity
does not exist.
Instead of unwrapping the value returned from this function, prefer World::entity_mut
.
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 entity_mut = world.get_entity_mut(entity).unwrap();
let mut position = entity_mut.get_mut::<Position>().unwrap();
position.x = 1.0;
sourcepub fn get_many_entities_mut<const N: usize>(
&mut self,
entities: [Entity; N]
) -> Result<[EntityMut<'_>; N], QueryEntityError>
pub fn get_many_entities_mut<const N: usize>( &mut self, entities: [Entity; N] ) -> Result<[EntityMut<'_>; N], QueryEntityError>
Gets mutable access to multiple entities.
§Errors
If any entities do not exist in the world, or if the same entity is specified multiple times.
§Examples
// Disjoint mutable access.
let [entity1, entity2] = world.get_many_entities_mut([id1, id2]).unwrap();
// Trying to access the same entity multiple times will fail.
assert!(world.get_many_entities_mut([id1, id1]).is_err());
sourcepub fn get_many_entities_dynamic_mut<'w>(
&'w mut self,
entities: &[Entity]
) -> Result<Vec<EntityMut<'w>>, QueryEntityError>
pub fn get_many_entities_dynamic_mut<'w>( &'w mut self, entities: &[Entity] ) -> Result<Vec<EntityMut<'w>>, QueryEntityError>
Gets mutable access to multiple entities, whose number is determined at runtime.
§Errors
If any entities do not exist in the world, or if the same entity is specified multiple times.
§Examples
// Disjoint mutable access.
let mut entities = world.get_many_entities_dynamic_mut(&[id1, id2]).unwrap();
let entity1 = entities.get_mut(0).unwrap();
// Trying to access the same entity multiple times will fail.
assert!(world.get_many_entities_dynamic_mut(&[id1, id1]).is_err());
sourcepub fn get_many_entities_from_set_mut<'w>(
&'w mut self,
entities: &HashSet<Entity, EntityHash>
) -> Result<Vec<EntityMut<'w>>, QueryEntityError>
pub fn get_many_entities_from_set_mut<'w>( &'w mut self, entities: &HashSet<Entity, EntityHash> ) -> Result<Vec<EntityMut<'w>>, QueryEntityError>
Gets mutable access to multiple entities, contained in a [HashSet
].
The uniqueness of items in a [HashSet
] allows us to avoid checking for duplicates.
§Errors
If any entities do not exist in the world.
§Examples
let s = EntityHash::default();
let mut set = EntityHashSet::with_hasher(s);
set.insert(id1);
set.insert(id2);
// Disjoint mutable access.
let mut entities = world.get_many_entities_from_set_mut(&set).unwrap();
let entity1 = entities.get_mut(0).unwrap();
sourcepub fn spawn_empty(&mut self) -> EntityWorldMut<'_>
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);
sourcepub fn spawn<B>(&mut self, bundle: B) -> EntityWorldMut<'_>where
B: Bundle,
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.
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);
sourcepub fn spawn_batch<I>(
&mut self,
iter: I
) -> SpawnBatchIter<'_, <I as IntoIterator>::IntoIter>
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,
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);
sourcepub fn get<T>(&self, entity: Entity) -> Option<&T>where
T: Component,
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);
sourcepub fn get_mut<T>(&mut self, entity: Entity) -> Option<Mut<'_, T>>where
T: Component,
pub fn get_mut<T>(&mut self, entity: Entity) -> Option<Mut<'_, T>>where
T: Component,
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;
sourcepub fn despawn(&mut self, entity: Entity) -> bool
pub fn despawn(&mut self, entity: Entity) -> bool
Despawns the given entity
, if it exists. This will also remove all of the entity’s
Component
s. Returns true
if the entity
is successfully despawned and false
if
the entity
does not exist.
§Note
This won’t clean up external references to the entity (such as parent-child relationships
if you’re using bevy_hierarchy
), which may leave the world in an invalid state.
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_none());
assert!(world.get::<Position>(entity).is_none());
sourcepub fn clear_trackers(&mut self)
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());
sourcepub fn query<D>(&mut self) -> QueryState<D>where
D: QueryData,
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")),
]);
sourcepub fn query_filtered<D, F>(&mut self) -> QueryState<D, F>where
D: QueryData,
F: QueryFilter,
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]);
sourcepub fn removed<T>(&self) -> impl Iterator<Item = Entity>where
T: Component,
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
.
sourcepub fn removed_with_id(
&self,
component_id: ComponentId
) -> impl Iterator<Item = Entity>
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
.
sourcepub fn init_resource<R>(&mut self) -> ComponentId
pub fn init_resource<R>(&mut self) -> ComponentId
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.
sourcepub fn insert_resource<R>(&mut self, value: R)where
R: Resource,
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.
sourcepub fn init_non_send_resource<R>(&mut self) -> ComponentIdwhere
R: 'static + FromWorld,
pub fn init_non_send_resource<R>(&mut self) -> ComponentIdwhere
R: 'static + FromWorld,
Initializes a new non-send 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.
§Panics
Panics if called from a thread other than the main thread.
sourcepub fn insert_non_send_resource<R>(&mut self, value: R)where
R: 'static,
pub fn insert_non_send_resource<R>(&mut self, value: R)where
R: 'static,
Inserts a new non-send resource with the given value
.
NonSend
resources 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.
sourcepub fn remove_resource<R>(&mut self) -> Option<R>where
R: Resource,
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
.
sourcepub fn remove_non_send_resource<R>(&mut self) -> Option<R>where
R: 'static,
pub fn remove_non_send_resource<R>(&mut self) -> Option<R>where
R: 'static,
Removes a !Send
resource 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
resources 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.
sourcepub fn contains_resource<R>(&self) -> boolwhere
R: Resource,
pub fn contains_resource<R>(&self) -> boolwhere
R: Resource,
Returns true
if a resource of type R
exists. Otherwise returns false
.
sourcepub fn contains_non_send<R>(&self) -> boolwhere
R: 'static,
pub fn contains_non_send<R>(&self) -> boolwhere
R: 'static,
Returns true
if a resource of type R
exists. Otherwise returns false
.
sourcepub fn is_resource_added<R>(&self) -> boolwhere
R: Resource,
pub fn is_resource_added<R>(&self) -> boolwhere
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.
sourcepub fn is_resource_added_by_id(&self, component_id: ComponentId) -> bool
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.
sourcepub fn is_resource_changed<R>(&self) -> boolwhere
R: Resource,
pub fn is_resource_changed<R>(&self) -> boolwhere
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.
sourcepub fn is_resource_changed_by_id(&self, component_id: ComponentId) -> bool
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.
sourcepub fn get_resource_change_ticks<R>(&self) -> Option<ComponentTicks>where
R: Resource,
pub fn get_resource_change_ticks<R>(&self) -> Option<ComponentTicks>where
R: Resource,
Retrieves the change ticks for the given resource.
sourcepub fn get_resource_change_ticks_by_id(
&self,
component_id: ComponentId
) -> Option<ComponentTicks>
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.
sourcepub fn resource<R>(&self) -> &Rwhere
R: Resource,
pub fn resource<R>(&self) -> &Rwhere
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
.
sourcepub fn resource_ref<R>(&self) -> Res<'_, R>where
R: Resource,
pub fn resource_ref<R>(&self) -> Res<'_, 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
.
sourcepub fn resource_mut<R>(&mut self) -> Mut<'_, R>where
R: Resource,
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
.
sourcepub fn get_resource<R>(&self) -> Option<&R>where
R: Resource,
pub fn get_resource<R>(&self) -> Option<&R>where
R: Resource,
Gets a reference to the resource of the given type if it exists
sourcepub fn get_resource_ref<R>(&self) -> Option<Res<'_, R>>where
R: Resource,
pub fn get_resource_ref<R>(&self) -> Option<Res<'_, R>>where
R: Resource,
Gets a reference including change detection to the resource of the given type if it exists.
sourcepub fn get_resource_mut<R>(&mut self) -> Option<Mut<'_, R>>where
R: Resource,
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
sourcepub fn get_resource_or_insert_with<R>(
&mut self,
func: impl FnOnce() -> R
) -> Mut<'_, R>where
R: Resource,
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
.
sourcepub fn non_send_resource<R>(&self) -> &Rwhere
R: 'static,
pub fn non_send_resource<R>(&self) -> &Rwhere
R: 'static,
Gets an immutable reference to the non-send resource of the given type, if it exists.
§Panics
Panics if the resource does not exist.
Use get_non_send_resource
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.
sourcepub fn non_send_resource_mut<R>(&mut self) -> Mut<'_, R>where
R: 'static,
pub fn non_send_resource_mut<R>(&mut self) -> Mut<'_, R>where
R: 'static,
Gets a mutable reference to the non-send resource of the given type, if it exists.
§Panics
Panics if the resource does not exist.
Use get_non_send_resource_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.
sourcepub fn get_non_send_resource<R>(&self) -> Option<&R>where
R: 'static,
pub fn get_non_send_resource<R>(&self) -> Option<&R>where
R: 'static,
Gets a reference to the non-send resource 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.
sourcepub fn get_non_send_resource_mut<R>(&mut self) -> Option<Mut<'_, R>>where
R: 'static,
pub fn get_non_send_resource_mut<R>(&mut self) -> Option<Mut<'_, R>>where
R: 'static,
Gets a mutable reference to the non-send resource 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.
sourcepub fn insert_or_spawn_batch<I, B>(
&mut self,
iter: I
) -> Result<(), Vec<Entity>>
pub fn insert_or_spawn_batch<I, B>( &mut self, iter: I ) -> Result<(), Vec<Entity>>
For a given batch of (Entity
, Bundle
) pairs, either spawns each Entity
with the given
bundle (if the entity does not exist), or inserts the Bundle
(if the entity already exists).
This is faster than doing equivalent operations one-by-one.
Returns Ok
if all entities were successfully inserted into or spawned. Otherwise it returns an Err
with a list of entities that could not be spawned or inserted into. A “spawn or insert” operation can
only fail if an Entity
is passed in with an “invalid generation” that conflicts with an existing Entity
.
§Note
Spawning a specific entity
value is rarely the right choice. Most apps should use World::spawn_batch
.
This method should generally only be used for sharing entities across apps, and only when they have a scheme
worked out to share an ID space (which doesn’t happen by default).
use bevy_ecs::{entity::Entity, world::World, component::Component};
#[derive(Component)]
struct A(&'static str);
#[derive(Component, PartialEq, Debug)]
struct B(f32);
let mut world = World::new();
let e0 = world.spawn_empty().id();
let e1 = world.spawn_empty().id();
world.insert_or_spawn_batch(vec![
(e0, (A("a"), B(0.0))), // the first entity
(e1, (A("b"), B(1.0))), // the second entity
]);
assert_eq!(world.get::<B>(e0), Some(&B(0.0)));
sourcepub fn resource_scope<R, U>(
&mut self,
f: impl FnOnce(&mut World, Mut<'_, R>) -> U
) -> Uwhere
R: Resource,
pub fn resource_scope<R, U>(
&mut self,
f: impl FnOnce(&mut World, Mut<'_, R>) -> U
) -> Uwhere
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
.
§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);
sourcepub fn send_event<E>(&mut self, event: E) -> Option<EventId<E>>where
E: Event,
pub fn send_event<E>(&mut self, event: E) -> Option<EventId<E>>where
E: Event,
sourcepub fn send_event_default<E>(&mut self) -> Option<EventId<E>>
pub fn send_event_default<E>(&mut self) -> Option<EventId<E>>
sourcepub fn send_event_batch<E>(
&mut self,
events: impl IntoIterator<Item = E>
) -> Option<SendBatchIds<E>>where
E: Event,
pub fn send_event_batch<E>(
&mut self,
events: impl IntoIterator<Item = E>
) -> Option<SendBatchIds<E>>where
E: Event,
sourcepub unsafe fn insert_resource_by_id(
&mut self,
component_id: ComponentId,
value: OwningPtr<'_>
)
pub unsafe fn insert_resource_by_id( &mut self, component_id: ComponentId, value: OwningPtr<'_> )
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.
sourcepub unsafe fn insert_non_send_by_id(
&mut self,
component_id: ComponentId,
value: OwningPtr<'_>
)
pub unsafe fn insert_non_send_by_id( &mut self, component_id: ComponentId, value: OwningPtr<'_> )
Inserts a new !Send
resource with the given value
. Will replace the value if it already
existed.
You should prefer to use the typed API World::insert_non_send_resource
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.
sourcepub fn flush(&mut self)
pub fn flush(&mut self)
Calls both World::flush_entities
and World::flush_commands
.
sourcepub fn flush_commands(&mut self)
pub fn flush_commands(&mut self)
Applies any commands in the world’s internal CommandQueue
.
This does not apply commands from any systems, only those stored in the world.
sourcepub fn increment_change_tick(&self) -> Tick
pub fn increment_change_tick(&self) -> Tick
Increments the world’s current change tick and returns the old value.
sourcepub fn read_change_tick(&self) -> Tick
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.
sourcepub fn change_tick(&mut self) -> Tick
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.
sourcepub fn last_change_tick(&self) -> Tick
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.
sourcepub fn last_change_tick_scope<T>(
&mut self,
last_change_tick: Tick,
f: impl FnOnce(&mut World) -> T
) -> T
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;
}
}
}
sourcepub fn check_change_ticks(&mut self)
pub fn check_change_ticks(&mut self)
Iterates all component change ticks and clamps any older than MAX_CHANGE_AGE
.
This prevents overflow and thus prevents false positives.
Note: Does nothing if the World
counter has not been incremented at least CHECK_TICK_THRESHOLD
times since the previous pass.
sourcepub fn clear_all(&mut self)
pub fn clear_all(&mut self)
Runs both clear_entities
and clear_resources
,
invalidating all Entity
and resource fetches such as Res
, ResMut
sourcepub fn clear_entities(&mut self)
pub fn clear_entities(&mut self)
Despawns all entities in this World
.
sourcepub fn clear_resources(&mut self)
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.
sourcepub fn init_bundle<B>(&mut self) -> &BundleInfowhere
B: Bundle,
pub fn init_bundle<B>(&mut self) -> &BundleInfowhere
B: Bundle,
Initializes all of the components in the given Bundle
and returns both the component
ids and the bundle id.
This is largely equivalent to calling init_component
on each
component in the bundle.
sourcepub fn get_resource_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>>
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.
sourcepub fn get_resource_mut_by_id(
&mut self,
component_id: ComponentId
) -> Option<MutUntyped<'_>>
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.
sourcepub fn iter_resources(&self) -> impl Iterator<Item = (&ComponentInfo, Ptr<'_>)>
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 TypeId
s
// 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::new();
// 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);
}
sourcepub fn iter_resources_mut(
&mut self
) -> impl Iterator<Item = (&ComponentInfo, MutUntyped<'_>)>
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::new();
// 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);
}
sourcepub fn get_non_send_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>>
pub fn get_non_send_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>>
Gets a !Send
resource 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.
§Panics
This function will panic if it isn’t called from the same thread that the resource was inserted from.
sourcepub fn get_non_send_mut_by_id(
&mut self,
component_id: ComponentId
) -> Option<MutUntyped<'_>>
pub fn get_non_send_mut_by_id( &mut self, component_id: ComponentId ) -> Option<MutUntyped<'_>>
Gets a !Send
resource 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.
§Panics
This function will panic if it isn’t called from the same thread that the resource was inserted from.
sourcepub fn remove_resource_by_id(&mut self, component_id: ComponentId) -> Option<()>
pub fn remove_resource_by_id(&mut self, component_id: ComponentId) -> Option<()>
Removes the resource of a given type, if it exists. Otherwise returns None
.
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.
sourcepub fn remove_non_send_by_id(&mut self, component_id: ComponentId) -> Option<()>
pub fn remove_non_send_by_id(&mut self, component_id: ComponentId) -> Option<()>
Removes the resource of a given type, if it exists. Otherwise returns None
.
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.
§Panics
This function will panic if it isn’t called from the same thread that the resource was inserted from.
sourcepub fn get_by_id(
&self,
entity: Entity,
component_id: ComponentId
) -> Option<Ptr<'_>>
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.
sourcepub fn get_mut_by_id(
&mut self,
entity: Entity,
component_id: ComponentId
) -> Option<MutUntyped<'_>>
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.
sourcepub fn add_schedule(&mut self, schedule: Schedule)
pub fn add_schedule(&mut self, schedule: Schedule)
Adds the specified Schedule
to the world. 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.
sourcepub fn try_schedule_scope<R>(
&mut self,
label: impl ScheduleLabel,
f: impl FnOnce(&mut World, &mut Schedule) -> R
) -> Result<R, TryRunScheduleError>
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
.
sourcepub fn schedule_scope<R>(
&mut self,
label: impl ScheduleLabel,
f: impl FnOnce(&mut World, &mut Schedule) -> R
) -> R
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.
sourcepub fn try_run_schedule(
&mut self,
label: impl ScheduleLabel
) -> Result<(), TryRunScheduleError>
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.
sourcepub fn run_schedule(&mut self, label: impl ScheduleLabel)
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.
§Panics
If the requested schedule does not exist.
sourcepub fn allow_ambiguous_component<T>(&mut self)where
T: Component,
pub fn allow_ambiguous_component<T>(&mut self)where
T: Component,
Ignore system order ambiguities caused by conflicts on Component
s of type T
.
sourcepub fn allow_ambiguous_resource<T>(&mut self)where
T: Resource,
pub fn allow_ambiguous_resource<T>(&mut self)where
T: Resource,
Ignore system order ambiguities caused by conflicts on Resource
s of type T
.
Trait Implementations§
impl Resource for MainWorld
Auto Trait Implementations§
impl !Freeze for MainWorld
impl !RefUnwindSafe for MainWorld
impl Send for MainWorld
impl Sync for MainWorld
impl Unpin for MainWorld
impl UnwindSafe for MainWorld
Blanket Implementations§
source§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
source§fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
T
ShaderType
for self
. When used in AsBindGroup
derives, it is safe to assume that all images in self
exist.source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
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
.source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
source§impl<T> FromWorld for Twhere
T: Default,
impl<T> FromWorld for Twhere
T: Default,
source§fn from_world(_world: &mut World) -> T
fn from_world(_world: &mut World) -> T
Self
using data from the given World
.