@@ -2653,34 +2653,29 @@ unsafe fn trigger_on_replace_and_on_remove_hooks_and_observers(
2653
2653
bundle_info : & BundleInfo ,
2654
2654
caller : MaybeLocation ,
2655
2655
) {
2656
+ let bundle_components_in_archetype = || {
2657
+ bundle_info
2658
+ . iter_explicit_components ( )
2659
+ . filter ( |component_id| archetype. contains ( * component_id) )
2660
+ } ;
2656
2661
if archetype. has_replace_observer ( ) {
2657
2662
deferred_world. trigger_observers (
2658
2663
ON_REPLACE ,
2659
2664
entity,
2660
- bundle_info . iter_explicit_components ( ) ,
2665
+ bundle_components_in_archetype ( ) ,
2661
2666
caller,
2662
2667
) ;
2663
2668
}
2664
- deferred_world. trigger_on_replace (
2665
- archetype,
2666
- entity,
2667
- bundle_info. iter_explicit_components ( ) ,
2668
- caller,
2669
- ) ;
2669
+ deferred_world. trigger_on_replace ( archetype, entity, bundle_components_in_archetype ( ) , caller) ;
2670
2670
if archetype. has_remove_observer ( ) {
2671
2671
deferred_world. trigger_observers (
2672
2672
ON_REMOVE ,
2673
2673
entity,
2674
- bundle_info . iter_explicit_components ( ) ,
2674
+ bundle_components_in_archetype ( ) ,
2675
2675
caller,
2676
2676
) ;
2677
2677
}
2678
- deferred_world. trigger_on_remove (
2679
- archetype,
2680
- entity,
2681
- bundle_info. iter_explicit_components ( ) ,
2682
- caller,
2683
- ) ;
2678
+ deferred_world. trigger_on_remove ( archetype, entity, bundle_components_in_archetype ( ) , caller) ;
2684
2679
}
2685
2680
2686
2681
/// A view into a single entity and component in a world, which may either be vacant or occupied.
@@ -5900,4 +5895,42 @@ mod tests {
5900
5895
5901
5896
assert_eq ! ( archetype_pointer_before, archetype_pointer_after) ;
5902
5897
}
5898
+
5899
+ #[ test]
5900
+ fn bundle_remove_only_triggers_for_present_components ( ) {
5901
+ let mut world = World :: default ( ) ;
5902
+
5903
+ #[ derive( Component ) ]
5904
+ struct A ;
5905
+
5906
+ #[ derive( Component ) ]
5907
+ struct B ;
5908
+
5909
+ #[ derive( Resource , PartialEq , Eq , Debug ) ]
5910
+ struct Tracker {
5911
+ a : bool ,
5912
+ b : bool ,
5913
+ }
5914
+
5915
+ world. insert_resource ( Tracker { a : false , b : false } ) ;
5916
+ let entity = world. spawn ( A ) . id ( ) ;
5917
+
5918
+ world. add_observer ( |_: Trigger < OnRemove , A > , mut tracker : ResMut < Tracker > | {
5919
+ tracker. a = true ;
5920
+ } ) ;
5921
+ world. add_observer ( |_: Trigger < OnRemove , B > , mut tracker : ResMut < Tracker > | {
5922
+ tracker. b = true ;
5923
+ } ) ;
5924
+
5925
+ world. entity_mut ( entity) . remove :: < ( A , B ) > ( ) ;
5926
+
5927
+ assert_eq ! (
5928
+ world. resource:: <Tracker >( ) ,
5929
+ & Tracker {
5930
+ a: true ,
5931
+ // The entity didn't have a B component, so it should not have been triggered.
5932
+ b: false ,
5933
+ }
5934
+ ) ;
5935
+ }
5903
5936
}
0 commit comments