@@ -1481,6 +1481,20 @@ impl<'a> EntityCommands<'a> {
14811481 }
14821482 }
14831483
1484+ /// Adds a [`Component`] to the entity if the component is different or
1485+ /// missing.
1486+ #[ track_caller]
1487+ pub fn insert_if_neq < T : Component + PartialEq > ( & mut self , component : T ) -> & mut Self {
1488+ self . queue ( move |mut entity : EntityWorldMut | {
1489+ if entity
1490+ . get :: < T > ( )
1491+ . is_none_or ( |old_component| * old_component != component)
1492+ {
1493+ entity. insert ( component) ;
1494+ }
1495+ } )
1496+ }
1497+
14841498 /// Adds a dynamic [`Component`] to the entity.
14851499 ///
14861500 /// This will overwrite any previous value(s) of the same component type.
@@ -2668,6 +2682,63 @@ mod tests {
26682682 command_queue1. apply ( & mut world) ;
26692683 }
26702684
2685+ #[ test]
2686+ fn insert_component_if_not_equal ( ) {
2687+ use crate :: query:: Added ;
2688+
2689+ #[ derive( Component , PartialEq ) ]
2690+ struct P ( u8 ) ;
2691+
2692+ let mut world = World :: default ( ) ;
2693+ let mut command_queue = CommandQueue :: default ( ) ;
2694+
2695+ let entity = Commands :: new ( & mut command_queue, & world)
2696+ . spawn ( P ( 41u8 ) )
2697+ . id ( ) ;
2698+
2699+ Commands :: new ( & mut command_queue, & world)
2700+ . entity ( entity)
2701+ . insert_if_neq ( P ( 42u8 ) ) ;
2702+
2703+ command_queue. apply ( & mut world) ;
2704+
2705+ let n_added = world. query_filtered :: < ( ) , Added < P > > ( ) . iter ( & world) . count ( ) ;
2706+
2707+ assert_eq ! ( n_added, 1 ) ;
2708+ assert_eq ! ( world. get:: <P >( entity) . unwrap( ) . 0 , 42 ) ;
2709+
2710+ world. clear_trackers ( ) ;
2711+
2712+ Commands :: new ( & mut command_queue, & world)
2713+ . entity ( entity)
2714+ . insert_if_neq ( P ( 42u8 ) ) ;
2715+
2716+ command_queue. apply ( & mut world) ;
2717+
2718+ let n_added = world. query_filtered :: < ( ) , Added < P > > ( ) . iter ( & world) . count ( ) ;
2719+
2720+ assert_eq ! ( n_added, 0 ) ;
2721+ assert_eq ! ( world. get:: <P >( entity) . unwrap( ) . 0 , 42 ) ;
2722+
2723+ world. clear_trackers ( ) ;
2724+
2725+ Commands :: new ( & mut command_queue, & world)
2726+ . entity ( entity)
2727+ . insert_if_neq ( P ( 42u8 ) ) ;
2728+
2729+ let entity2 = Commands :: new ( & mut command_queue, & world) . spawn_empty ( ) . id ( ) ;
2730+
2731+ Commands :: new ( & mut command_queue, & world)
2732+ . entity ( entity2)
2733+ . insert_if_neq ( P ( 42u8 ) ) ;
2734+ command_queue. apply ( & mut world) ;
2735+
2736+ let n_added = world. query_filtered :: < ( ) , Added < P > > ( ) . iter ( & world) . count ( ) ;
2737+
2738+ assert_eq ! ( n_added, 1 ) ;
2739+ assert_eq ! ( world. get:: <P >( entity2) . unwrap( ) . 0 , 42 ) ;
2740+ }
2741+
26712742 #[ test]
26722743 fn remove_components ( ) {
26732744 let mut world = World :: default ( ) ;
0 commit comments