1#[cfg(feature = "bevy_reflect")]
10use crate::reflect::{ReflectComponent, ReflectFromWorld};
11use crate::{
12 bundle::Bundle,
13 component::Component,
14 entity::Entity,
15 lifecycle::HookContext,
16 name::Name,
17 relationship::{RelatedSpawner, RelatedSpawnerCommands},
18 system::EntityCommands,
19 world::{DeferredWorld, EntityWorldMut, FromWorld, World},
20};
21use alloc::{format, vec::Vec};
22#[cfg(feature = "bevy_reflect")]
23use bevy_reflect::std_traits::ReflectDefault;
24#[cfg(all(feature = "serialize", feature = "bevy_reflect"))]
25use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
26use bevy_utils::prelude::DebugName;
27use core::ops::Deref;
28use core::slice;
29use log::warn;
30
31#[derive(Component, Clone, PartialEq, Eq, Debug)]
98#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
99#[cfg_attr(
100 feature = "bevy_reflect",
101 reflect(Component, PartialEq, Debug, FromWorld, Clone)
102)]
103#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
104#[cfg_attr(
105 all(feature = "serialize", feature = "bevy_reflect"),
106 reflect(Serialize, Deserialize)
107)]
108#[relationship(relationship_target = Children)]
109#[doc(alias = "IsChild", alias = "Parent")]
110pub struct ChildOf(#[entities] pub Entity);
111
112impl ChildOf {
113 #[inline]
115 pub fn parent(&self) -> Entity {
116 self.0
117 }
118}
119
120impl FromWorld for ChildOf {
125 #[inline(always)]
126 fn from_world(_world: &mut World) -> Self {
127 ChildOf(Entity::PLACEHOLDER)
128 }
129}
130
131#[derive(Component, Default, Debug, PartialEq, Eq)]
151#[relationship_target(relationship = ChildOf, linked_spawn)]
152#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
153#[cfg_attr(feature = "bevy_reflect", reflect(Component, FromWorld, Default))]
154#[doc(alias = "IsParent")]
155pub struct Children(Vec<Entity>);
156
157impl Children {
158 #[inline]
160 pub fn swap(&mut self, a_index: usize, b_index: usize) {
161 self.0.swap(a_index, b_index);
162 }
163
164 #[inline]
173 pub fn sort_by<F>(&mut self, compare: F)
174 where
175 F: FnMut(&Entity, &Entity) -> core::cmp::Ordering,
176 {
177 self.0.sort_by(compare);
178 }
179
180 #[inline]
189 pub fn sort_by_key<K, F>(&mut self, compare: F)
190 where
191 F: FnMut(&Entity) -> K,
192 K: Ord,
193 {
194 self.0.sort_by_key(compare);
195 }
196
197 #[inline]
205 pub fn sort_by_cached_key<K, F>(&mut self, compare: F)
206 where
207 F: FnMut(&Entity) -> K,
208 K: Ord,
209 {
210 self.0.sort_by_cached_key(compare);
211 }
212
213 #[inline]
222 pub fn sort_unstable_by<F>(&mut self, compare: F)
223 where
224 F: FnMut(&Entity, &Entity) -> core::cmp::Ordering,
225 {
226 self.0.sort_unstable_by(compare);
227 }
228
229 #[inline]
238 pub fn sort_unstable_by_key<K, F>(&mut self, compare: F)
239 where
240 F: FnMut(&Entity) -> K,
241 K: Ord,
242 {
243 self.0.sort_unstable_by_key(compare);
244 }
245}
246
247impl<'a> IntoIterator for &'a Children {
248 type Item = <Self::IntoIter as Iterator>::Item;
249
250 type IntoIter = slice::Iter<'a, Entity>;
251
252 #[inline(always)]
253 fn into_iter(self) -> Self::IntoIter {
254 self.0.iter()
255 }
256}
257
258impl Deref for Children {
259 type Target = [Entity];
260
261 fn deref(&self) -> &Self::Target {
262 &self.0
263 }
264}
265
266pub type ChildSpawner<'w> = RelatedSpawner<'w, ChildOf>;
268
269pub type ChildSpawnerCommands<'w> = RelatedSpawnerCommands<'w, ChildOf>;
271
272impl<'w> EntityWorldMut<'w> {
273 pub fn with_children(&mut self, func: impl FnOnce(&mut ChildSpawner)) -> &mut Self {
276 self.with_related_entities(func);
277 self
278 }
279
280 pub fn add_children(&mut self, children: &[Entity]) -> &mut Self {
283 self.add_related::<ChildOf>(children)
284 }
285
286 #[deprecated = "Use detach_all_children() instead"]
289 pub fn clear_children(&mut self) -> &mut Self {
290 self.detach_all_children()
291 }
292
293 pub fn detach_all_children(&mut self) -> &mut Self {
297 self.detach_all_related::<ChildOf>()
298 }
299
300 pub fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self {
303 self.insert_related::<ChildOf>(index, children)
304 }
305
306 pub fn insert_child(&mut self, index: usize, child: Entity) -> &mut Self {
309 self.insert_related::<ChildOf>(index, &[child])
310 }
311
312 pub fn add_child(&mut self, child: Entity) -> &mut Self {
315 self.add_related::<ChildOf>(&[child])
316 }
317
318 #[deprecated = "Use detach_children() instead"]
320 pub fn remove_children(&mut self, children: &[Entity]) -> &mut Self {
321 self.detach_children(children)
322 }
323
324 pub fn detach_children(&mut self, children: &[Entity]) -> &mut Self {
327 self.remove_related::<ChildOf>(children)
328 }
329
330 #[deprecated = "Use detach_child() instead"]
332 pub fn remove_child(&mut self, child: Entity) -> &mut Self {
333 self.detach_child(child)
334 }
335
336 pub fn detach_child(&mut self, child: Entity) -> &mut Self {
339 self.remove_related::<ChildOf>(&[child])
340 }
341
342 pub fn replace_children(&mut self, children: &[Entity]) -> &mut Self {
344 self.replace_related::<ChildOf>(children)
345 }
346
347 pub fn replace_children_with_difference(
358 &mut self,
359 entities_to_unrelate: &[Entity],
360 entities_to_relate: &[Entity],
361 newly_related_entities: &[Entity],
362 ) -> &mut Self {
363 self.replace_related_with_difference::<ChildOf>(
364 entities_to_unrelate,
365 entities_to_relate,
366 newly_related_entities,
367 )
368 }
369
370 pub fn with_child(&mut self, bundle: impl Bundle) -> &mut Self {
376 let parent = self.id();
377 self.world_scope(|world| {
378 world.spawn((bundle, ChildOf(parent)));
379 });
380 self
381 }
382}
383
384impl<'a> EntityCommands<'a> {
385 pub fn with_children(
387 &mut self,
388 func: impl FnOnce(&mut RelatedSpawnerCommands<ChildOf>),
389 ) -> &mut Self {
390 self.with_related_entities(func);
391 self
392 }
393
394 pub fn add_children(&mut self, children: &[Entity]) -> &mut Self {
396 self.add_related::<ChildOf>(children)
397 }
398
399 #[deprecated = "Use detach_all_children() instead"]
402 pub fn clear_children(&mut self) -> &mut Self {
403 self.detach_all_children()
404 }
405
406 pub fn detach_all_children(&mut self) -> &mut Self {
410 self.detach_all_related::<ChildOf>()
411 }
412
413 pub fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self {
416 self.insert_related::<ChildOf>(index, children)
417 }
418
419 pub fn insert_child(&mut self, index: usize, child: Entity) -> &mut Self {
422 self.insert_related::<ChildOf>(index, &[child])
423 }
424
425 pub fn add_child(&mut self, child: Entity) -> &mut Self {
427 self.add_related::<ChildOf>(&[child])
428 }
429
430 #[deprecated = "Use detach_children() instead"]
432 pub fn remove_children(&mut self, children: &[Entity]) -> &mut Self {
433 self.detach_children(children)
434 }
435
436 pub fn detach_children(&mut self, children: &[Entity]) -> &mut Self {
439 self.remove_related::<ChildOf>(children)
440 }
441
442 #[deprecated = "Use detach_child() instead"]
444 pub fn remove_child(&mut self, child: Entity) -> &mut Self {
445 self.detach_child(child)
446 }
447
448 pub fn detach_child(&mut self, child: Entity) -> &mut Self {
451 self.remove_related::<ChildOf>(&[child])
452 }
453
454 pub fn replace_children(&mut self, children: &[Entity]) -> &mut Self {
456 self.replace_related::<ChildOf>(children)
457 }
458
459 pub fn replace_children_with_difference(
470 &mut self,
471 entities_to_unrelate: &[Entity],
472 entities_to_relate: &[Entity],
473 newly_related_entities: &[Entity],
474 ) -> &mut Self {
475 self.replace_related_with_difference::<ChildOf>(
476 entities_to_unrelate,
477 entities_to_relate,
478 newly_related_entities,
479 )
480 }
481
482 pub fn with_child(&mut self, bundle: impl Bundle) -> &mut Self {
488 self.with_related::<ChildOf>(bundle);
489 self
490 }
491}
492
493pub fn validate_parent_has_component<C: Component>(
496 world: DeferredWorld,
497 HookContext { entity, caller, .. }: HookContext,
498) {
499 let entity_ref = world.entity(entity);
500 let Some(child_of) = entity_ref.get::<ChildOf>() else {
501 return;
502 };
503 let parent = child_of.parent();
504 let maybe_parent_ref = world.get_entity(parent);
505 if let Ok(parent_ref) = maybe_parent_ref
506 && !parent_ref.contains::<C>()
507 {
508 let name = entity_ref.get::<Name>();
509 let debug_name = DebugName::type_name::<C>();
510 let parent_name = parent_ref.get::<Name>();
511 warn!(
512 "warning[B0004]: {}{name} with the {ty_name} component has a parent ({parent_name}) without {ty_name}.\n\
513 This will cause inconsistent behaviors! See: https://bevy.org/learn/errors/b0004",
514 caller.map(|c| format!("{c}: ")).unwrap_or_default(),
515 ty_name = debug_name.shortname(),
516 name = name.map_or_else(
517 || format!("Entity {entity}"),
518 |s| format!("The {s} entity")
519 ),
520 parent_name = parent_name.map_or_else(
521 || format!("{parent} entity"),
522 |s| format!("the {s} entity")
523 ),
524 );
525 }
526}
527
528#[macro_export]
558macro_rules! children {
559 [$($child:expr),*$(,)?] => {
560 $crate::hierarchy::Children::spawn($crate::recursive_spawn!($($child),*))
561 };
562}
563
564#[cfg(test)]
565mod tests {
566 use crate::{
567 entity::Entity,
568 hierarchy::{ChildOf, Children},
569 relationship::{RelationshipHookMode, RelationshipTarget},
570 spawn::{Spawn, SpawnRelated},
571 world::World,
572 };
573 use alloc::{vec, vec::Vec};
574
575 #[derive(PartialEq, Eq, Debug)]
576 struct Node {
577 entity: Entity,
578 children: Vec<Node>,
579 }
580
581 impl Node {
582 fn new(entity: Entity) -> Self {
583 Self {
584 entity,
585 children: Vec::new(),
586 }
587 }
588
589 fn new_with(entity: Entity, children: Vec<Node>) -> Self {
590 Self { entity, children }
591 }
592 }
593
594 fn get_hierarchy(world: &World, entity: Entity) -> Node {
595 Node {
596 entity,
597 children: world
598 .entity(entity)
599 .get::<Children>()
600 .map_or_else(Default::default, |c| {
601 c.iter().map(|e| get_hierarchy(world, e)).collect()
602 }),
603 }
604 }
605
606 #[test]
607 fn hierarchy() {
608 let mut world = World::new();
609 let root = world.spawn_empty().id();
610 let child1 = world.spawn(ChildOf(root)).id();
611 let grandchild = world.spawn(ChildOf(child1)).id();
612 let child2 = world.spawn(ChildOf(root)).id();
613
614 let hierarchy = get_hierarchy(&world, root);
616 assert_eq!(
617 hierarchy,
618 Node::new_with(
619 root,
620 vec![
621 Node::new_with(child1, vec![Node::new(grandchild)]),
622 Node::new(child2)
623 ]
624 )
625 );
626
627 world.entity_mut(child1).remove::<ChildOf>();
629 let hierarchy = get_hierarchy(&world, root);
630 assert_eq!(hierarchy, Node::new_with(root, vec![Node::new(child2)]));
631
632 world.entity_mut(child1).insert(ChildOf(root));
634 let hierarchy = get_hierarchy(&world, root);
635 assert_eq!(
636 hierarchy,
637 Node::new_with(
638 root,
639 vec![
640 Node::new(child2),
641 Node::new_with(child1, vec![Node::new(grandchild)])
642 ]
643 )
644 );
645
646 world.entity_mut(root).despawn();
648 assert!(world.get_entity(root).is_err());
649 assert!(world.get_entity(child1).is_err());
650 assert!(world.get_entity(child2).is_err());
651 assert!(world.get_entity(grandchild).is_err());
652 }
653
654 #[test]
655 fn with_children() {
656 let mut world = World::new();
657 let mut child1 = Entity::PLACEHOLDER;
658 let mut child2 = Entity::PLACEHOLDER;
659 let root = world
660 .spawn_empty()
661 .with_children(|p| {
662 child1 = p.spawn_empty().id();
663 child2 = p.spawn_empty().id();
664 })
665 .id();
666
667 let hierarchy = get_hierarchy(&world, root);
668 assert_eq!(
669 hierarchy,
670 Node::new_with(root, vec![Node::new(child1), Node::new(child2)])
671 );
672 }
673
674 #[test]
675 fn add_children() {
676 let mut world = World::new();
677 let child1 = world.spawn_empty().id();
678 let child2 = world.spawn_empty().id();
679 let root = world.spawn_empty().add_children(&[child1, child2]).id();
680
681 let hierarchy = get_hierarchy(&world, root);
682 assert_eq!(
683 hierarchy,
684 Node::new_with(root, vec![Node::new(child1), Node::new(child2)])
685 );
686 }
687
688 #[test]
689 fn insert_children() {
690 let mut world = World::new();
691 let child1 = world.spawn_empty().id();
692 let child2 = world.spawn_empty().id();
693 let child3 = world.spawn_empty().id();
694 let child4 = world.spawn_empty().id();
695
696 let mut entity_world_mut = world.spawn_empty();
697
698 let first_children = entity_world_mut.add_children(&[child1, child2]);
699
700 let root = first_children.insert_children(1, &[child3, child4]).id();
701
702 let hierarchy = get_hierarchy(&world, root);
703 assert_eq!(
704 hierarchy,
705 Node::new_with(
706 root,
707 vec![
708 Node::new(child1),
709 Node::new(child3),
710 Node::new(child4),
711 Node::new(child2)
712 ]
713 )
714 );
715 }
716
717 #[test]
718 fn insert_child() {
719 let mut world = World::new();
720 let child1 = world.spawn_empty().id();
721 let child2 = world.spawn_empty().id();
722 let child3 = world.spawn_empty().id();
723
724 let mut entity_world_mut = world.spawn_empty();
725
726 let first_children = entity_world_mut.add_children(&[child1, child2]);
727
728 let root = first_children.insert_child(1, child3).id();
729
730 let hierarchy = get_hierarchy(&world, root);
731 assert_eq!(
732 hierarchy,
733 Node::new_with(
734 root,
735 vec![Node::new(child1), Node::new(child3), Node::new(child2)]
736 )
737 );
738 }
739
740 #[test]
742 fn insert_children_index_bound() {
743 let mut world = World::new();
744 let child1 = world.spawn_empty().id();
745 let child2 = world.spawn_empty().id();
746 let child3 = world.spawn_empty().id();
747 let child4 = world.spawn_empty().id();
748
749 let mut entity_world_mut = world.spawn_empty();
750
751 let first_children = entity_world_mut.add_children(&[child1, child2]).id();
752 let hierarchy = get_hierarchy(&world, first_children);
753 assert_eq!(
754 hierarchy,
755 Node::new_with(first_children, vec![Node::new(child1), Node::new(child2)])
756 );
757
758 let root = world
759 .entity_mut(first_children)
760 .insert_children(usize::MAX, &[child3, child4])
761 .id();
762 let hierarchy = get_hierarchy(&world, root);
763 assert_eq!(
764 hierarchy,
765 Node::new_with(
766 root,
767 vec![
768 Node::new(child1),
769 Node::new(child2),
770 Node::new(child3),
771 Node::new(child4),
772 ]
773 )
774 );
775 }
776
777 #[test]
778 fn detach_children() {
779 let mut world = World::new();
780 let child1 = world.spawn_empty().id();
781 let child2 = world.spawn_empty().id();
782 let child3 = world.spawn_empty().id();
783 let child4 = world.spawn_empty().id();
784
785 let mut root = world.spawn_empty();
786 root.add_children(&[child1, child2, child3, child4]);
787 root.detach_children(&[child2, child3]);
788 let root = root.id();
789
790 let hierarchy = get_hierarchy(&world, root);
791 assert_eq!(
792 hierarchy,
793 Node::new_with(root, vec![Node::new(child1), Node::new(child4)])
794 );
795 }
796
797 #[test]
798 fn detach_child() {
799 let mut world = World::new();
800 let child1 = world.spawn_empty().id();
801 let child2 = world.spawn_empty().id();
802 let child3 = world.spawn_empty().id();
803
804 let mut root = world.spawn_empty();
805 root.add_children(&[child1, child2, child3]);
806 root.detach_child(child2);
807 let root = root.id();
808
809 let hierarchy = get_hierarchy(&world, root);
810 assert_eq!(
811 hierarchy,
812 Node::new_with(root, vec![Node::new(child1), Node::new(child3)])
813 );
814 }
815
816 #[test]
817 fn self_parenting_invalid() {
818 let mut world = World::new();
819 let id = world.spawn_empty().id();
820 world.entity_mut(id).insert(ChildOf(id));
821 assert!(
822 world.entity(id).get::<ChildOf>().is_none(),
823 "invalid ChildOf relationships should self-remove"
824 );
825 }
826
827 #[test]
828 fn missing_parent_invalid() {
829 let mut world = World::new();
830 let parent = world.spawn_empty().id();
831 world.entity_mut(parent).despawn();
832 let id = world.spawn(ChildOf(parent)).id();
833 assert!(
834 world.entity(id).get::<ChildOf>().is_none(),
835 "invalid ChildOf relationships should self-remove"
836 );
837 }
838
839 #[test]
840 fn reinsert_same_parent() {
841 let mut world = World::new();
842 let parent = world.spawn_empty().id();
843 let id = world.spawn(ChildOf(parent)).id();
844 world.entity_mut(id).insert(ChildOf(parent));
845 assert_eq!(
846 Some(&ChildOf(parent)),
847 world.entity(id).get::<ChildOf>(),
848 "ChildOf should still be there"
849 );
850 }
851
852 #[test]
853 fn spawn_children() {
854 let mut world = World::new();
855 let id = world.spawn(Children::spawn((Spawn(()), Spawn(())))).id();
856 assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 2,);
857 }
858
859 #[test]
860 fn spawn_many_children() {
861 let mut world = World::new();
862
863 world.spawn(children![]);
865
866 let id = world
868 .spawn(children![(), (), (), (), (), (), (), (), (), (), (), ()])
869 .id();
870
871 assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 12,);
872
873 let id = world
875 .spawn(children![
876 (),
877 (),
878 (),
879 (),
880 (),
881 (),
882 (),
883 (),
884 (),
885 (),
886 (),
887 (),
888 (),
889 ])
890 .id();
891
892 assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 13,);
893 }
894
895 #[test]
896 fn replace_children() {
897 let mut world = World::new();
898 let parent = world.spawn(Children::spawn((Spawn(()), Spawn(())))).id();
899 let &[child_a, child_b] = &world.entity(parent).get::<Children>().unwrap().0[..] else {
900 panic!("Tried to spawn 2 children on an entity and didn't get 2 children");
901 };
902
903 let child_c = world.spawn_empty().id();
904
905 world
906 .entity_mut(parent)
907 .replace_children(&[child_a, child_c]);
908
909 let children = world.entity(parent).get::<Children>().unwrap();
910
911 assert!(children.contains(&child_a));
912 assert!(children.contains(&child_c));
913 assert!(!children.contains(&child_b));
914
915 assert_eq!(
916 world.entity(child_a).get::<ChildOf>().unwrap(),
917 &ChildOf(parent)
918 );
919 assert_eq!(
920 world.entity(child_c).get::<ChildOf>().unwrap(),
921 &ChildOf(parent)
922 );
923 assert!(world.entity(child_b).get::<ChildOf>().is_none());
924 }
925
926 #[test]
927 fn replace_children_with_nothing() {
928 let mut world = World::new();
929 let parent = world.spawn_empty().id();
930 let child_a = world.spawn_empty().id();
931 let child_b = world.spawn_empty().id();
932
933 world.entity_mut(parent).add_children(&[child_a, child_b]);
934
935 assert_eq!(world.entity(parent).get::<Children>().unwrap().len(), 2);
936
937 world.entity_mut(parent).replace_children(&[]);
938
939 assert!(world.entity(child_a).get::<ChildOf>().is_none());
940 assert!(world.entity(child_b).get::<ChildOf>().is_none());
941 }
942
943 #[test]
944 fn insert_same_child_twice() {
945 let mut world = World::new();
946
947 let parent = world.spawn_empty().id();
948 let child = world.spawn_empty().id();
949
950 world.entity_mut(parent).add_child(child);
951 world.entity_mut(parent).add_child(child);
952
953 let children = world.get::<Children>(parent).unwrap();
954 assert_eq!(children.0, [child]);
955 assert_eq!(
956 world.entity(child).get::<ChildOf>().unwrap(),
957 &ChildOf(parent)
958 );
959 }
960
961 #[test]
962 fn replace_with_difference() {
963 let mut world = World::new();
964
965 let parent = world.spawn_empty().id();
966 let child_a = world.spawn_empty().id();
967 let child_b = world.spawn_empty().id();
968 let child_c = world.spawn_empty().id();
969 let child_d = world.spawn_empty().id();
970
971 world.entity_mut(parent).replace_children_with_difference(
973 &[],
974 &[child_a, child_b],
975 &[child_a, child_b],
976 );
977
978 assert_eq!(
979 world.entity(child_a).get::<ChildOf>().unwrap(),
980 &ChildOf(parent)
981 );
982 assert_eq!(
983 world.entity(child_b).get::<ChildOf>().unwrap(),
984 &ChildOf(parent)
985 );
986 assert_eq!(
987 world.entity(parent).get::<Children>().unwrap().0,
988 [child_a, child_b]
989 );
990
991 world.entity_mut(parent).replace_children_with_difference(
993 &[child_b],
994 &[child_d, child_c, child_a],
995 &[child_c, child_d],
996 );
997 assert_eq!(
998 world.entity(child_a).get::<ChildOf>().unwrap(),
999 &ChildOf(parent)
1000 );
1001 assert_eq!(
1002 world.entity(child_c).get::<ChildOf>().unwrap(),
1003 &ChildOf(parent)
1004 );
1005 assert_eq!(
1006 world.entity(child_d).get::<ChildOf>().unwrap(),
1007 &ChildOf(parent)
1008 );
1009 assert_eq!(
1010 world.entity(parent).get::<Children>().unwrap().0,
1011 [child_d, child_c, child_a]
1012 );
1013 assert!(!world.entity(child_b).contains::<ChildOf>());
1014
1015 world.entity_mut(parent).replace_children_with_difference(
1017 &[child_a, child_d, child_c],
1018 &[],
1019 &[],
1020 );
1021 assert!(!world.entity(parent).contains::<Children>());
1022 assert!(!world.entity(child_a).contains::<ChildOf>());
1023 assert!(!world.entity(child_b).contains::<ChildOf>());
1024 assert!(!world.entity(child_c).contains::<ChildOf>());
1025 assert!(!world.entity(child_d).contains::<ChildOf>());
1026 }
1027
1028 #[test]
1029 fn replace_with_difference_on_empty() {
1030 let mut world = World::new();
1031
1032 let parent = world.spawn_empty().id();
1033 let child_a = world.spawn_empty().id();
1034
1035 world
1036 .entity_mut(parent)
1037 .replace_children_with_difference(&[child_a], &[], &[]);
1038
1039 assert!(!world.entity(parent).contains::<Children>());
1040 assert!(!world.entity(child_a).contains::<ChildOf>());
1041 }
1042
1043 #[test]
1044 fn replace_with_difference_totally_new_children() {
1045 let mut world = World::new();
1046
1047 let parent = world.spawn_empty().id();
1048 let child_a = world.spawn_empty().id();
1049 let child_b = world.spawn_empty().id();
1050 let child_c = world.spawn_empty().id();
1051 let child_d = world.spawn_empty().id();
1052
1053 world.entity_mut(parent).replace_children_with_difference(
1055 &[],
1056 &[child_a, child_b],
1057 &[child_a, child_b],
1058 );
1059
1060 assert_eq!(
1061 world.entity(child_a).get::<ChildOf>().unwrap(),
1062 &ChildOf(parent)
1063 );
1064 assert_eq!(
1065 world.entity(child_b).get::<ChildOf>().unwrap(),
1066 &ChildOf(parent)
1067 );
1068 assert_eq!(
1069 world.entity(parent).get::<Children>().unwrap().0,
1070 [child_a, child_b]
1071 );
1072
1073 world.entity_mut(parent).replace_children_with_difference(
1075 &[child_b, child_a],
1076 &[child_d, child_c],
1077 &[child_c, child_d],
1078 );
1079 assert_eq!(
1080 world.entity(child_c).get::<ChildOf>().unwrap(),
1081 &ChildOf(parent)
1082 );
1083 assert_eq!(
1084 world.entity(child_d).get::<ChildOf>().unwrap(),
1085 &ChildOf(parent)
1086 );
1087 assert_eq!(
1088 world.entity(parent).get::<Children>().unwrap().0,
1089 [child_d, child_c]
1090 );
1091 assert!(!world.entity(child_a).contains::<ChildOf>());
1092 assert!(!world.entity(child_b).contains::<ChildOf>());
1093 }
1094
1095 #[test]
1096 fn replace_children_order() {
1097 let mut world = World::new();
1098
1099 let parent = world.spawn_empty().id();
1100 let child_a = world.spawn_empty().id();
1101 let child_b = world.spawn_empty().id();
1102 let child_c = world.spawn_empty().id();
1103 let child_d = world.spawn_empty().id();
1104
1105 let initial_order = [child_a, child_b, child_c, child_d];
1106 world.entity_mut(parent).add_children(&initial_order);
1107
1108 assert_eq!(
1109 world.entity_mut(parent).get::<Children>().unwrap().0,
1110 initial_order
1111 );
1112
1113 let new_order = [child_d, child_b, child_a, child_c];
1114 world.entity_mut(parent).replace_children(&new_order);
1115
1116 assert_eq!(world.entity(parent).get::<Children>().unwrap().0, new_order);
1117 }
1118
1119 #[test]
1120 #[should_panic]
1121 #[cfg_attr(
1122 not(debug_assertions),
1123 ignore = "we don't check invariants if debug assertions are off"
1124 )]
1125 fn replace_diff_invariant_overlapping_unrelate_with_relate() {
1126 let mut world = World::new();
1127
1128 let parent = world.spawn_empty().id();
1129 let child_a = world.spawn_empty().id();
1130
1131 world
1132 .entity_mut(parent)
1133 .replace_children_with_difference(&[], &[child_a], &[child_a]);
1134
1135 world
1137 .entity_mut(parent)
1138 .replace_children_with_difference(&[child_a], &[child_a], &[]);
1139 }
1140
1141 #[test]
1142 #[should_panic]
1143 #[cfg_attr(
1144 not(debug_assertions),
1145 ignore = "we don't check invariants if debug assertions are off"
1146 )]
1147 fn replace_diff_invariant_overlapping_unrelate_with_newly() {
1148 let mut world = World::new();
1149
1150 let parent = world.spawn_empty().id();
1151 let child_a = world.spawn_empty().id();
1152 let child_b = world.spawn_empty().id();
1153
1154 world
1155 .entity_mut(parent)
1156 .replace_children_with_difference(&[], &[child_a], &[child_a]);
1157
1158 world.entity_mut(parent).replace_children_with_difference(
1160 &[child_b],
1161 &[child_a, child_b],
1162 &[child_b],
1163 );
1164 }
1165
1166 #[test]
1167 #[should_panic]
1168 #[cfg_attr(
1169 not(debug_assertions),
1170 ignore = "we don't check invariants if debug assertions are off"
1171 )]
1172 fn replace_diff_invariant_newly_not_subset() {
1173 let mut world = World::new();
1174
1175 let parent = world.spawn_empty().id();
1176 let child_a = world.spawn_empty().id();
1177 let child_b = world.spawn_empty().id();
1178
1179 world.entity_mut(parent).replace_children_with_difference(
1181 &[],
1182 &[child_a, child_b],
1183 &[child_a],
1184 );
1185 }
1186
1187 #[test]
1188 fn child_replace_hook_skip() {
1189 let mut world = World::new();
1190 let parent = world.spawn_empty().id();
1191 let other = world.spawn_empty().id();
1192 let child = world.spawn(ChildOf(parent)).id();
1193 world
1194 .entity_mut(child)
1195 .insert_with_relationship_hook_mode(ChildOf(other), RelationshipHookMode::Skip);
1196 assert_eq!(
1197 &**world.entity(parent).get::<Children>().unwrap(),
1198 &[child],
1199 "Children should still have the old value, as on_insert/on_replace didn't run"
1200 );
1201 }
1202}