bevy_ecs/event/
update.rs

1use crate as bevy_ecs;
2use bevy_ecs::{
3    change_detection::Mut,
4    component::Tick,
5    event::EventRegistry,
6    system::{Local, Res, ResMut},
7    world::World,
8};
9use bevy_ecs_macros::SystemSet;
10#[cfg(feature = "bevy_reflect")]
11use core::hash::Hash;
12
13use super::registry::ShouldUpdateEvents;
14
15#[doc(hidden)]
16#[derive(SystemSet, Clone, Debug, PartialEq, Eq, Hash)]
17pub struct EventUpdates;
18
19/// Signals the [`event_update_system`] to run after `FixedUpdate` systems.
20///
21/// This will change the behavior of the [`EventRegistry`] to only run after a fixed update cycle has passed.
22/// Normally, this will simply run every frame.
23pub fn signal_event_update_system(signal: Option<ResMut<EventRegistry>>) {
24    if let Some(mut registry) = signal {
25        registry.should_update = ShouldUpdateEvents::Ready;
26    }
27}
28
29/// A system that calls [`Events::update`](super::Events::update) on all registered [`Events`][super::Events] in the world.
30pub fn event_update_system(world: &mut World, mut last_change_tick: Local<Tick>) {
31    if world.contains_resource::<EventRegistry>() {
32        world.resource_scope(|world, mut registry: Mut<EventRegistry>| {
33            registry.run_updates(world, *last_change_tick);
34
35            registry.should_update = match registry.should_update {
36                // If we're always updating, keep doing so.
37                ShouldUpdateEvents::Always => ShouldUpdateEvents::Always,
38                // Disable the system until signal_event_update_system runs again.
39                ShouldUpdateEvents::Waiting | ShouldUpdateEvents::Ready => {
40                    ShouldUpdateEvents::Waiting
41                }
42            };
43        });
44    }
45    *last_change_tick = world.change_tick();
46}
47
48/// A run condition for [`event_update_system`].
49///
50/// If [`signal_event_update_system`] has been run at least once,
51/// we will wait for it to be run again before updating the events.
52///
53/// Otherwise, we will always update the events.
54pub fn event_update_condition(maybe_signal: Option<Res<EventRegistry>>) -> bool {
55    match maybe_signal {
56        Some(signal) => match signal.should_update {
57            ShouldUpdateEvents::Always | ShouldUpdateEvents::Ready => true,
58            ShouldUpdateEvents::Waiting => false,
59        },
60        None => true,
61    }
62}