mirror of
https://github.com/bevyengine/bevy.git
synced 2026-05-06 06:06:42 -04:00
Add Commands::insert_resource_if_neq (#24082)
# Objective - Fixes #24041 ## Testing - [`insert_resource_if_not_equal`](https://github.com/micttyoid/bevy/blob/command-insert-resource-if-neq/crates/bevy_ecs/src/system/commands/mod.rs#L2932) - [`insert_resource_if_not_equal_tracks_caller`](https://github.com/micttyoid/bevy/blob/command-insert-resource-if-neq/crates/bevy_ecs/src/system/commands/mod.rs#L2973)
This commit is contained in:
@@ -896,6 +896,22 @@ impl<'w, 's> Commands<'w, 's> {
|
||||
self.queue(command::insert_resource(resource));
|
||||
}
|
||||
|
||||
/// Inserts a [`Resource`] into the [`World`] with a specific value
|
||||
/// if the resource is different or missing.
|
||||
#[track_caller]
|
||||
pub fn insert_resource_if_neq<R: Resource + PartialEq>(&mut self, resource: R) {
|
||||
let caller = MaybeLocation::caller();
|
||||
|
||||
self.queue(move |world: &mut World| {
|
||||
if world
|
||||
.get_resource::<R>()
|
||||
.is_none_or(|old_resource| *old_resource != resource)
|
||||
{
|
||||
world.insert_resource_with_caller(resource, caller);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Removes a [`Resource`] from the [`World`].
|
||||
///
|
||||
/// # Example
|
||||
@@ -2912,6 +2928,111 @@ mod tests {
|
||||
assert!(world.contains_resource::<V<f64>>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn insert_resource_if_not_equal() {
|
||||
#[derive(Resource, PartialEq)]
|
||||
struct P(u8);
|
||||
|
||||
let mut world = World::default();
|
||||
let mut queue = CommandQueue::default();
|
||||
|
||||
{
|
||||
let mut commands = Commands::new(&mut queue, &world);
|
||||
commands.insert_resource_if_neq(P(41));
|
||||
}
|
||||
|
||||
queue.apply(&mut world);
|
||||
assert!(world.is_resource_added::<P>());
|
||||
assert_eq!(world.get_resource::<P>().unwrap().0, 41);
|
||||
|
||||
world.clear_trackers();
|
||||
|
||||
{
|
||||
let mut commands = Commands::new(&mut queue, &world);
|
||||
commands.insert_resource_if_neq(P(42));
|
||||
}
|
||||
|
||||
queue.apply(&mut world);
|
||||
assert!(world.is_resource_changed::<P>());
|
||||
assert_eq!(world.get_resource::<P>().unwrap().0, 42);
|
||||
|
||||
world.clear_trackers();
|
||||
|
||||
{
|
||||
let mut commands = Commands::new(&mut queue, &world);
|
||||
commands.insert_resource_if_neq(P(42));
|
||||
}
|
||||
|
||||
queue.apply(&mut world);
|
||||
assert!(!world.is_resource_changed::<P>());
|
||||
assert_eq!(world.get_resource::<P>().unwrap().0, 42);
|
||||
}
|
||||
|
||||
#[cfg(feature = "track_location")]
|
||||
#[test]
|
||||
fn insert_resource_if_not_equal_tracks_caller() {
|
||||
use crate::change_detection::DetectChanges;
|
||||
use core::panic::Location;
|
||||
|
||||
#[derive(Resource, PartialEq)]
|
||||
struct P(u8);
|
||||
|
||||
let mut world = World::default();
|
||||
let mut queue = CommandQueue::default();
|
||||
|
||||
macro_rules! insert_resource_if_neq_with_expected_caller {
|
||||
($commands:expr, $resource:expr) => {{
|
||||
$commands.insert_resource_if_neq($resource);
|
||||
Location::caller()
|
||||
}};
|
||||
}
|
||||
let expected1 =
|
||||
insert_resource_if_neq_with_expected_caller!(Commands::new(&mut queue, &world), P(41));
|
||||
|
||||
queue.apply(&mut world);
|
||||
|
||||
assert_eq!(
|
||||
world
|
||||
.get_resource_ref::<P>()
|
||||
.unwrap()
|
||||
.changed_by()
|
||||
.into_option(),
|
||||
Some(expected1)
|
||||
);
|
||||
|
||||
world.clear_trackers();
|
||||
|
||||
let expected2 =
|
||||
insert_resource_if_neq_with_expected_caller!(Commands::new(&mut queue, &world), P(42));
|
||||
|
||||
queue.apply(&mut world);
|
||||
|
||||
assert_eq!(
|
||||
world
|
||||
.get_resource_ref::<P>()
|
||||
.unwrap()
|
||||
.changed_by()
|
||||
.into_option(),
|
||||
Some(expected2)
|
||||
);
|
||||
|
||||
world.clear_trackers();
|
||||
|
||||
let expected3 =
|
||||
insert_resource_if_neq_with_expected_caller!(Commands::new(&mut queue, &world), P(42));
|
||||
|
||||
queue.apply(&mut world);
|
||||
|
||||
assert_ne!(
|
||||
world
|
||||
.get_resource_ref::<P>()
|
||||
.unwrap()
|
||||
.changed_by()
|
||||
.into_option(),
|
||||
Some(expected3)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remove_component_with_required_components() {
|
||||
#[derive(Component)]
|
||||
|
||||
Reference in New Issue
Block a user