bevy_ecs::schedule::common_conditions

Function resource_changed_or_removed

Source
pub fn resource_changed_or_removed<T>() -> impl FnMut(Option<Res<'_, T>>) -> bool + Clone
where T: Resource,
Expand description

Generates a Condition-satisfying closure that returns true if the resource of the given type has had its value changed since the condition was last checked.

The value is considered changed when it is added. The first time this condition is checked after the resource was added, it will return true. Change detection behaves like this everywhere in Bevy.

This run condition also detects removal. It will return true if the resource has been removed since the run condition was last checked.

The condition will return false if the resource does not exist.

ยงExample

app.add_systems(
    // `resource_changed_or_removed` will only return true if the
    // given resource was just changed or removed (or added)
    my_system.run_if(
        resource_changed_or_removed::<Counter>()
        // By default detecting changes will also trigger if the resource was
        // just added, this won't work with my example so I will add a second
        // condition to make sure the resource wasn't just added
        .and_then(not(resource_added::<Counter>))
    ),
);

#[derive(Resource, Default)]
struct MyResource;

// If `Counter` exists, increment it, otherwise insert `MyResource`
fn my_system(mut commands: Commands, mut counter: Option<ResMut<Counter>>) {
    if let Some(mut counter) = counter {
        counter.0 += 1;
    } else {
        commands.init_resource::<MyResource>();
    }
}

// `Counter` hasn't been changed so `my_system` won't run
app.run(&mut world);
assert_eq!(world.resource::<Counter>().0, 0);

world.resource_mut::<Counter>().0 = 50;

// `Counter` was just changed so `my_system` will run
app.run(&mut world);
assert_eq!(world.resource::<Counter>().0, 51);

world.remove_resource::<Counter>();

// `Counter` was just removed so `my_system` will run
app.run(&mut world);
assert_eq!(world.contains_resource::<MyResource>(), true);