bevy_ecs/event/
update.rs

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