diff --git a/crates/bevy_ecs/src/observer/mod.rs b/crates/bevy_ecs/src/observer/mod.rs index b1876afddd..b3d689d449 100644 --- a/crates/bevy_ecs/src/observer/mod.rs +++ b/crates/bevy_ecs/src/observer/mod.rs @@ -72,9 +72,12 @@ pub struct ObserverDescriptor { } impl ObserverDescriptor { - /// Add the given `triggers` to the descriptor. - pub fn with_triggers(mut self, triggers: Vec) -> Self { - self.events = triggers; + /// Add the given `events` to the descriptor. + /// # Safety + /// The type of each [`ComponentId`] in `events` _must_ match the actual value + /// of the event passed into the observer. + pub unsafe fn with_events(mut self, events: Vec) -> Self { + self.events = events; self } @@ -518,8 +521,11 @@ mod tests { world.init_resource::(); let on_remove = world.init_component::(); world.spawn( - Observer::new(|_: Trigger, mut res: ResMut| res.0 += 1) - .with_event(on_remove), + // SAFETY: OnAdd and OnRemove are both unit types, so this is safe + unsafe { + Observer::new(|_: Trigger, mut res: ResMut| res.0 += 1) + .with_event(on_remove) + }, ); let entity = world.spawn(A).id(); @@ -641,7 +647,8 @@ mod tests { let event_a = world.init_component::(); world.spawn(ObserverState { - descriptor: ObserverDescriptor::default().with_triggers(vec![event_a]), + // SAFETY: we registered `event_a` above and it matches the type of TriggerA + descriptor: unsafe { ObserverDescriptor::default().with_events(vec![event_a]) }, runner: |mut world, _trigger, _ptr| { world.resource_mut::().0 += 1; }, @@ -649,7 +656,7 @@ mod tests { }); world.commands().add( - // SAFETY: we registered `trigger` above and it matches the type of TriggerA + // SAFETY: we registered `event_a` above and it matches the type of TriggerA unsafe { EmitDynamicTrigger::new_with_id(event_a, EventA, ()) }, ); world.flush(); diff --git a/crates/bevy_ecs/src/observer/runner.rs b/crates/bevy_ecs/src/observer/runner.rs index f4d5384348..40092be553 100644 --- a/crates/bevy_ecs/src/observer/runner.rs +++ b/crates/bevy_ecs/src/observer/runner.rs @@ -298,7 +298,10 @@ impl Observer { /// Observe the given `event`. This will cause the [`Observer`] to run whenever an event with the given [`ComponentId`] /// is triggered. - pub fn with_event(mut self, event: ComponentId) -> Self { + /// # Safety + /// The type of the `event` [`ComponentId`] _must_ match the actual value + /// of the event passed into the observer system. + pub unsafe fn with_event(mut self, event: ComponentId) -> Self { self.descriptor.events.push(event); self }