Struct bevy_ecs::observer::Observer

source ·
pub struct Observer<T: 'static, B: Bundle> { /* private fields */ }
Expand description

An Observer system. Add this Component to an Entity to turn it into an “observer”.

Observers listen for a “trigger” of a specific Event. Events are triggered by calling World::trigger or World::trigger_targets.

Note that “buffered” events sent using EventReader and EventWriter are not automatically triggered. They must be triggered at a specific point in the schedule.

§Usage

The simplest usage of the observer pattern looks like this:

#[derive(Event)]
struct Speak {
    message: String,
}

world.observe(|trigger: Trigger<Speak>| {
    println!("{}", trigger.event().message);
});

// Observers currently require a flush() to be registered. In the context of schedules,
// this will generally be done for you.
world.flush();

world.trigger(Speak {
    message: "Hello!".into(),
});

Notice that we used World::observe. This is just a shorthand for spawning an Observer manually:

// These are functionally the same:
world.observe(|trigger: Trigger<Speak>| {});
world.spawn(Observer::new(|trigger: Trigger<Speak>| {}));

Observers are systems. They can access arbitrary World data by adding SystemParams:

world.observe(|trigger: Trigger<PrintNames>, names: Query<&Name>| {
    for name in &names {
        println!("{name:?}");
    }
});

Note that Trigger must always be the first parameter.

You can also add Commands, which means you can spawn new entities, insert new components, etc:

world.observe(|trigger: Trigger<SpawnThing>, mut commands: Commands| {
    commands.spawn(Thing);
});

Observers can also trigger new events:

world.observe(|trigger: Trigger<A>, mut commands: Commands| {
    commands.trigger(B);
});

When the commands are flushed (including these “nested triggers”) they will be recursively evaluated until there are no commands left, meaning nested triggers all evaluate at the same time!

Events can be triggered for entities, which will be passed to the Observer:

#[derive(Event)]
struct Explode;

world.observe(|trigger: Trigger<Explode>, mut commands: Commands| {
    println!("Entity {:?} goes BOOM!", trigger.entity());
    commands.entity(trigger.entity()).despawn();
});

world.flush();

world.trigger_targets(Explode, entity);

You can trigger multiple entities at once:

world.trigger_targets(Explode, [e1, e2]);

Observers can also watch specific entities, which enables you to assign entity-specific logic:

world.entity_mut(e1).observe(|trigger: Trigger<Explode>, mut commands: Commands| {
    println!("Boom!");
    commands.entity(trigger.entity()).despawn();
});

world.entity_mut(e2).observe(|trigger: Trigger<Explode>, mut commands: Commands| {
    println!("The explosion fizzles! This entity is immune!");
});

If all entities watched by a given Observer are despawned, the Observer entity will also be despawned. This protects against observer “garbage” building up over time.

The examples above calling EntityWorldMut::observe to add entity-specific observer logic are (once again) just shorthand for spawning an Observer directly:

let mut observer = Observer::new(|trigger: Trigger<Explode>| {});
observer.watch_entity(entity);
world.spawn(observer);

Note that the Observer component is not added to the entity it is observing. Observers should always be their own entities!

You can call Observer::watch_entity more than once, which allows you to watch multiple entities with the same Observer.

When first added, Observer will also create an ObserverState component, which registers the observer with the World and serves as the “source of truth” of the observer.

Implementations§

source§

impl<E: Event, B: Bundle> Observer<E, B>

source

pub fn new<M>(system: impl IntoObserverSystem<E, B, M>) -> Self

Creates a new Observer, which defaults to a “global” observer. This means it will run whenever the event E is triggered for any entity (or no entity).

source

pub fn with_entity(self, entity: Entity) -> Self

Observe the given entity. This will cause the Observer to run whenever the Event is triggered for the entity.

source

pub fn watch_entity(&mut self, entity: Entity)

Observe the given entity. This will cause the Observer to run whenever the Event is triggered for the entity. Note that if this is called after an Observer is spawned, it will produce no effects.

source

pub fn with_component(self, component: ComponentId) -> Self

Observe the given component. This will cause the Observer to run whenever the Event is triggered with the given component target.

source

pub unsafe fn with_event(self, event: ComponentId) -> Self

Observe the given event. This will cause the Observer to run whenever an event with the given ComponentId is triggered.

§Safety

The type of the event ComponentId must match the actual value of the event passed into the observer system.

Trait Implementations§

source§

impl<E: Event, B: Bundle> Component for Observer<E, B>

source§

const STORAGE_TYPE: StorageType = StorageType::SparseSet

A constant indicating the storage type used for this component.
source§

fn register_component_hooks(hooks: &mut ComponentHooks)

Called when registering this component, allowing mutable access to its ComponentHooks.

Auto Trait Implementations§

§

impl<T, B> Freeze for Observer<T, B>

§

impl<T, B> !RefUnwindSafe for Observer<T, B>

§

impl<T, B> Send for Observer<T, B>

§

impl<T, B> Sync for Observer<T, B>

§

impl<T, B> Unpin for Observer<T, B>

§

impl<T, B> !UnwindSafe for Observer<T, B>

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<C> Bundle for C
where C: Component,

source§

fn component_ids( components: &mut Components, storages: &mut Storages, ids: &mut impl FnMut(ComponentId), )

source§

unsafe fn from_components<T, F>(ctx: &mut T, func: &mut F) -> C
where F: for<'a> FnMut(&'a mut T) -> OwningPtr<'a>,

source§

fn get_component_ids( components: &Components, ids: &mut impl FnMut(Option<ComponentId>), )

Gets this Bundle’s component ids. This will be None if the component has not been registered.
source§

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

source§

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.
source§

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.
source§

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.
source§

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.
source§

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

source§

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.
source§

impl<C> DynamicBundle for C
where C: Component,

source§

fn get_components(self, func: &mut impl FnMut(StorageType, OwningPtr<'_>))

source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

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

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

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, U> TryFrom<U> for T
where U: Into<T>,

§

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>,

§

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.
source§

impl<T> WithSubscriber for T

source§

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
source§

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,