@@ -158,19 +158,21 @@ pub trait Relationship: Component + Sized {
158
158
{
159
159
relationship_target. collection_mut_risky ( ) . remove ( entity) ;
160
160
if relationship_target. len ( ) == 0 {
161
- if let Ok ( mut entity) = world . commands ( ) . get_entity ( target_entity ) {
161
+ let command = | mut entity : EntityWorldMut | {
162
162
// this "remove" operation must check emptiness because in the event that an identical
163
163
// relationship is inserted on top, this despawn would result in the removal of that identical
164
164
// relationship ... not what we want!
165
- entity. queue ( |mut entity : EntityWorldMut | {
166
- if entity
167
- . get :: < Self :: RelationshipTarget > ( )
168
- . is_some_and ( RelationshipTarget :: is_empty)
169
- {
170
- entity. remove :: < Self :: RelationshipTarget > ( ) ;
171
- }
172
- } ) ;
173
- }
165
+ if entity
166
+ . get :: < Self :: RelationshipTarget > ( )
167
+ . is_some_and ( RelationshipTarget :: is_empty)
168
+ {
169
+ entity. remove :: < Self :: RelationshipTarget > ( ) ;
170
+ }
171
+ } ;
172
+
173
+ world
174
+ . commands ( )
175
+ . queue ( command. with_entity ( target_entity) . handle_error_with ( ignore) ) ;
174
176
}
175
177
}
176
178
}
@@ -424,4 +426,63 @@ mod tests {
424
426
425
427
// No assert necessary, looking to make sure compilation works with the macros
426
428
}
429
+
430
+ #[ test]
431
+ fn parent_child_relationship_with_custom_relationship ( ) {
432
+ use crate :: prelude:: ChildOf ;
433
+
434
+ #[ derive( Component ) ]
435
+ #[ relationship( relationship_target = RelTarget ) ]
436
+ struct Rel ( Entity ) ;
437
+
438
+ #[ derive( Component ) ]
439
+ #[ relationship_target( relationship = Rel ) ]
440
+ struct RelTarget ( Entity ) ;
441
+
442
+ let mut world = World :: new ( ) ;
443
+
444
+ // Rel on Parent
445
+ // Despawn Parent
446
+ let mut commands = world. commands ( ) ;
447
+ let child = commands. spawn_empty ( ) . id ( ) ;
448
+ let parent = commands. spawn ( Rel ( child) ) . add_child ( child) . id ( ) ;
449
+ commands. entity ( parent) . despawn ( ) ;
450
+ world. flush ( ) ;
451
+
452
+ assert ! ( world. get_entity( child) . is_err( ) ) ;
453
+ assert ! ( world. get_entity( parent) . is_err( ) ) ;
454
+
455
+ // Rel on Parent
456
+ // Despawn Child
457
+ let mut commands = world. commands ( ) ;
458
+ let child = commands. spawn_empty ( ) . id ( ) ;
459
+ let parent = commands. spawn ( Rel ( child) ) . add_child ( child) . id ( ) ;
460
+ commands. entity ( child) . despawn ( ) ;
461
+ world. flush ( ) ;
462
+
463
+ assert ! ( world. get_entity( child) . is_err( ) ) ;
464
+ assert ! ( !world. entity( parent) . contains:: <Rel >( ) ) ;
465
+
466
+ // Rel on Child
467
+ // Despawn Parent
468
+ let mut commands = world. commands ( ) ;
469
+ let parent = commands. spawn_empty ( ) . id ( ) ;
470
+ let child = commands. spawn ( ( ChildOf ( parent) , Rel ( parent) ) ) . id ( ) ;
471
+ commands. entity ( parent) . despawn ( ) ;
472
+ world. flush ( ) ;
473
+
474
+ assert ! ( world. get_entity( child) . is_err( ) ) ;
475
+ assert ! ( world. get_entity( parent) . is_err( ) ) ;
476
+
477
+ // Rel on Child
478
+ // Despawn Child
479
+ let mut commands = world. commands ( ) ;
480
+ let parent = commands. spawn_empty ( ) . id ( ) ;
481
+ let child = commands. spawn ( ( ChildOf ( parent) , Rel ( parent) ) ) . id ( ) ;
482
+ commands. entity ( child) . despawn ( ) ;
483
+ world. flush ( ) ;
484
+
485
+ assert ! ( world. get_entity( child) . is_err( ) ) ;
486
+ assert ! ( !world. entity( parent) . contains:: <RelTarget >( ) ) ;
487
+ }
427
488
}
0 commit comments