1#[cfg(feature = "bevy_reflect")]
10use crate::reflect::{ReflectComponent, ReflectFromWorld};
11use crate::{
12 bundle::Bundle,
13 component::Component,
14 entity::Entity,
15 relationship::{RelatedSpawner, RelatedSpawnerCommands},
16 system::EntityCommands,
17 template::FromTemplate,
18 world::{EntityWorldMut, FromWorld, World},
19};
20use alloc::vec::Vec;
21#[cfg(feature = "bevy_reflect")]
22use bevy_reflect::std_traits::ReflectDefault;
23#[cfg(all(feature = "serialize", feature = "bevy_reflect"))]
24use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
25use core::ops::Deref;
26use core::slice;
27
28#[derive(Component, FromTemplate, Clone, PartialEq, Eq, Debug)]
95#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
96#[cfg_attr(
97 feature = "bevy_reflect",
98 reflect(Component, PartialEq, Debug, FromWorld, Clone)
99)]
100#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
101#[cfg_attr(
102 all(feature = "serialize", feature = "bevy_reflect"),
103 reflect(Serialize, Deserialize)
104)]
105#[relationship(relationship_target = Children)]
106#[doc(alias = "IsChild", alias = "Parent")]
107pub struct ChildOf(#[entities] pub Entity);
108
109impl ChildOf {
110 #[inline]
112 pub fn parent(&self) -> Entity {
113 self.0
114 }
115}
116
117impl FromWorld for ChildOf {
122 #[inline(always)]
123 fn from_world(_world: &mut World) -> Self {
124 ChildOf(Entity::PLACEHOLDER)
125 }
126}
127
128#[derive(Component, Default, Debug, PartialEq, Eq)]
148#[relationship_target(relationship = ChildOf, linked_spawn)]
149#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
150#[cfg_attr(feature = "bevy_reflect", reflect(Component, FromWorld, Default))]
151#[doc(alias = "IsParent")]
152pub struct Children(Vec<Entity>);
153
154impl Children {
155 #[inline]
157 pub fn swap(&mut self, a_index: usize, b_index: usize) {
158 self.0.swap(a_index, b_index);
159 }
160
161 #[inline]
170 pub fn sort_by<F>(&mut self, compare: F)
171 where
172 F: FnMut(&Entity, &Entity) -> core::cmp::Ordering,
173 {
174 self.0.sort_by(compare);
175 }
176
177 #[inline]
186 pub fn sort_by_key<K, F>(&mut self, compare: F)
187 where
188 F: FnMut(&Entity) -> K,
189 K: Ord,
190 {
191 self.0.sort_by_key(compare);
192 }
193
194 #[inline]
202 pub fn sort_by_cached_key<K, F>(&mut self, compare: F)
203 where
204 F: FnMut(&Entity) -> K,
205 K: Ord,
206 {
207 self.0.sort_by_cached_key(compare);
208 }
209
210 #[inline]
219 pub fn sort_unstable_by<F>(&mut self, compare: F)
220 where
221 F: FnMut(&Entity, &Entity) -> core::cmp::Ordering,
222 {
223 self.0.sort_unstable_by(compare);
224 }
225
226 #[inline]
235 pub fn sort_unstable_by_key<K, F>(&mut self, compare: F)
236 where
237 F: FnMut(&Entity) -> K,
238 K: Ord,
239 {
240 self.0.sort_unstable_by_key(compare);
241 }
242}
243
244impl<'a> IntoIterator for &'a Children {
245 type Item = <Self::IntoIter as Iterator>::Item;
246
247 type IntoIter = slice::Iter<'a, Entity>;
248
249 #[inline(always)]
250 fn into_iter(self) -> Self::IntoIter {
251 self.0.iter()
252 }
253}
254
255impl Deref for Children {
256 type Target = [Entity];
257
258 fn deref(&self) -> &Self::Target {
259 &self.0
260 }
261}
262
263pub type ChildSpawner<'w> = RelatedSpawner<'w, ChildOf>;
265
266pub type ChildSpawnerCommands<'w> = RelatedSpawnerCommands<'w, ChildOf>;
268
269impl<'w> EntityWorldMut<'w> {
270 pub fn with_children(&mut self, func: impl FnOnce(&mut ChildSpawner)) -> &mut Self {
273 self.with_related_entities(func);
274 self
275 }
276
277 pub fn add_children(&mut self, children: &[Entity]) -> &mut Self {
280 self.add_related::<ChildOf>(children)
281 }
282
283 pub fn detach_all_children(&mut self) -> &mut Self {
287 self.detach_all_related::<ChildOf>()
288 }
289
290 pub fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self {
293 self.insert_related::<ChildOf>(index, children)
294 }
295
296 pub fn insert_child(&mut self, index: usize, child: Entity) -> &mut Self {
299 self.insert_related::<ChildOf>(index, &[child])
300 }
301
302 pub fn add_child(&mut self, child: Entity) -> &mut Self {
305 self.add_related::<ChildOf>(&[child])
306 }
307
308 pub fn detach_children(&mut self, children: &[Entity]) -> &mut Self {
311 self.remove_related::<ChildOf>(children)
312 }
313
314 pub fn detach_child(&mut self, child: Entity) -> &mut Self {
317 self.remove_related::<ChildOf>(&[child])
318 }
319
320 pub fn replace_children(&mut self, children: &[Entity]) -> &mut Self {
324 self.replace_related::<ChildOf>(children)
325 }
326
327 pub fn replace_children_with_difference(
338 &mut self,
339 entities_to_unrelate: &[Entity],
340 entities_to_relate: &[Entity],
341 newly_related_entities: &[Entity],
342 ) -> &mut Self {
343 self.replace_related_with_difference::<ChildOf>(
344 entities_to_unrelate,
345 entities_to_relate,
346 newly_related_entities,
347 )
348 }
349
350 pub fn with_child(&mut self, bundle: impl Bundle) -> &mut Self {
356 let parent = self.id();
357 self.world_scope(|world| {
358 world.spawn((bundle, ChildOf(parent)));
359 });
360 self
361 }
362}
363
364impl<'a> EntityCommands<'a> {
365 pub fn with_children(
367 &mut self,
368 func: impl FnOnce(&mut RelatedSpawnerCommands<ChildOf>),
369 ) -> &mut Self {
370 self.with_related_entities(func);
371 self
372 }
373
374 pub fn add_children(&mut self, children: &[Entity]) -> &mut Self {
376 self.add_related::<ChildOf>(children)
377 }
378
379 pub fn detach_all_children(&mut self) -> &mut Self {
383 self.detach_all_related::<ChildOf>()
384 }
385
386 pub fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self {
389 self.insert_related::<ChildOf>(index, children)
390 }
391
392 pub fn insert_child(&mut self, index: usize, child: Entity) -> &mut Self {
395 self.insert_related::<ChildOf>(index, &[child])
396 }
397
398 pub fn add_child(&mut self, child: Entity) -> &mut Self {
400 self.add_related::<ChildOf>(&[child])
401 }
402
403 pub fn detach_children(&mut self, children: &[Entity]) -> &mut Self {
406 self.remove_related::<ChildOf>(children)
407 }
408
409 pub fn detach_child(&mut self, child: Entity) -> &mut Self {
412 self.remove_related::<ChildOf>(&[child])
413 }
414
415 pub fn replace_children(&mut self, children: &[Entity]) -> &mut Self {
419 self.replace_related::<ChildOf>(children)
420 }
421
422 pub fn replace_children_with_difference(
433 &mut self,
434 entities_to_unrelate: &[Entity],
435 entities_to_relate: &[Entity],
436 newly_related_entities: &[Entity],
437 ) -> &mut Self {
438 self.replace_related_with_difference::<ChildOf>(
439 entities_to_unrelate,
440 entities_to_relate,
441 newly_related_entities,
442 )
443 }
444
445 pub fn with_child(&mut self, bundle: impl Bundle) -> &mut Self {
451 self.with_related::<ChildOf>(bundle);
452 self
453 }
454}
455
456#[macro_export]
485macro_rules! children {
486 [$($child:expr),*$(,)?] => {
487 $crate::related!($crate::hierarchy::Children [$($child),*])
488 };
489}
490
491#[cfg(test)]
492mod tests {
493 use crate::{
494 entity::Entity,
495 hierarchy::{ChildOf, Children},
496 relationship::{RelationshipHookMode, RelationshipTarget},
497 spawn::{Spawn, SpawnRelated},
498 world::World,
499 };
500 use alloc::{vec, vec::Vec};
501
502 #[derive(PartialEq, Eq, Debug)]
503 struct Node {
504 entity: Entity,
505 children: Vec<Node>,
506 }
507
508 impl Node {
509 fn new(entity: Entity) -> Self {
510 Self {
511 entity,
512 children: Vec::new(),
513 }
514 }
515
516 fn new_with(entity: Entity, children: Vec<Node>) -> Self {
517 Self { entity, children }
518 }
519 }
520
521 fn get_hierarchy(world: &World, entity: Entity) -> Node {
522 Node {
523 entity,
524 children: world
525 .entity(entity)
526 .get::<Children>()
527 .map_or_else(Default::default, |c| {
528 c.iter().map(|e| get_hierarchy(world, e)).collect()
529 }),
530 }
531 }
532
533 #[test]
534 fn hierarchy() {
535 let mut world = World::new();
536 let root = world.spawn_empty().id();
537 let child1 = world.spawn(ChildOf(root)).id();
538 let grandchild = world.spawn(ChildOf(child1)).id();
539 let child2 = world.spawn(ChildOf(root)).id();
540
541 let hierarchy = get_hierarchy(&world, root);
543 assert_eq!(
544 hierarchy,
545 Node::new_with(
546 root,
547 vec![
548 Node::new_with(child1, vec![Node::new(grandchild)]),
549 Node::new(child2)
550 ]
551 )
552 );
553
554 world.entity_mut(child1).remove::<ChildOf>();
556 let hierarchy = get_hierarchy(&world, root);
557 assert_eq!(hierarchy, Node::new_with(root, vec![Node::new(child2)]));
558
559 world.entity_mut(child1).insert(ChildOf(root));
561 let hierarchy = get_hierarchy(&world, root);
562 assert_eq!(
563 hierarchy,
564 Node::new_with(
565 root,
566 vec![
567 Node::new(child2),
568 Node::new_with(child1, vec![Node::new(grandchild)])
569 ]
570 )
571 );
572
573 world.entity_mut(root).despawn();
575 assert!(world.get_entity(root).is_err());
576 assert!(world.get_entity(child1).is_err());
577 assert!(world.get_entity(child2).is_err());
578 assert!(world.get_entity(grandchild).is_err());
579 }
580
581 #[test]
582 fn with_children() {
583 let mut world = World::new();
584 let mut child1 = None;
585 let mut child2 = None;
586 let root = world
587 .spawn_empty()
588 .with_children(|p| {
589 child1 = Some(p.spawn_empty().id());
590 child2 = Some(p.spawn_empty().id());
591 })
592 .id();
593
594 let hierarchy = get_hierarchy(&world, root);
595 assert_eq!(
596 hierarchy,
597 Node::new_with(
598 root,
599 vec![Node::new(child1.unwrap()), Node::new(child2.unwrap())]
600 )
601 );
602 }
603
604 #[test]
605 fn add_children() {
606 let mut world = World::new();
607 let child1 = world.spawn_empty().id();
608 let child2 = world.spawn_empty().id();
609 let root = world.spawn_empty().add_children(&[child1, child2]).id();
610
611 let hierarchy = get_hierarchy(&world, root);
612 assert_eq!(
613 hierarchy,
614 Node::new_with(root, vec![Node::new(child1), Node::new(child2)])
615 );
616 }
617
618 #[test]
619 fn insert_children() {
620 let mut world = World::new();
621 let child1 = world.spawn_empty().id();
622 let child2 = world.spawn_empty().id();
623 let child3 = world.spawn_empty().id();
624 let child4 = world.spawn_empty().id();
625
626 let mut entity_world_mut = world.spawn_empty();
627
628 let first_children = entity_world_mut.add_children(&[child1, child2]);
629
630 let root = first_children.insert_children(1, &[child3, child4]).id();
631
632 let hierarchy = get_hierarchy(&world, root);
633 assert_eq!(
634 hierarchy,
635 Node::new_with(
636 root,
637 vec![
638 Node::new(child1),
639 Node::new(child3),
640 Node::new(child4),
641 Node::new(child2)
642 ]
643 )
644 );
645 }
646
647 #[test]
648 fn insert_child() {
649 let mut world = World::new();
650 let child1 = world.spawn_empty().id();
651 let child2 = world.spawn_empty().id();
652 let child3 = world.spawn_empty().id();
653
654 let mut entity_world_mut = world.spawn_empty();
655
656 let first_children = entity_world_mut.add_children(&[child1, child2]);
657
658 let root = first_children.insert_child(1, child3).id();
659
660 let hierarchy = get_hierarchy(&world, root);
661 assert_eq!(
662 hierarchy,
663 Node::new_with(
664 root,
665 vec![Node::new(child1), Node::new(child3), Node::new(child2)]
666 )
667 );
668 }
669
670 #[test]
672 fn insert_children_index_bound() {
673 let mut world = World::new();
674 let child1 = world.spawn_empty().id();
675 let child2 = world.spawn_empty().id();
676 let child3 = world.spawn_empty().id();
677 let child4 = world.spawn_empty().id();
678
679 let mut entity_world_mut = world.spawn_empty();
680
681 let first_children = entity_world_mut.add_children(&[child1, child2]).id();
682 let hierarchy = get_hierarchy(&world, first_children);
683 assert_eq!(
684 hierarchy,
685 Node::new_with(first_children, vec![Node::new(child1), Node::new(child2)])
686 );
687
688 let root = world
689 .entity_mut(first_children)
690 .insert_children(usize::MAX, &[child3, child4])
691 .id();
692 let hierarchy = get_hierarchy(&world, root);
693 assert_eq!(
694 hierarchy,
695 Node::new_with(
696 root,
697 vec![
698 Node::new(child1),
699 Node::new(child2),
700 Node::new(child3),
701 Node::new(child4),
702 ]
703 )
704 );
705 }
706
707 #[test]
708 fn detach_children() {
709 let mut world = World::new();
710 let child1 = world.spawn_empty().id();
711 let child2 = world.spawn_empty().id();
712 let child3 = world.spawn_empty().id();
713 let child4 = world.spawn_empty().id();
714
715 let mut root = world.spawn_empty();
716 root.add_children(&[child1, child2, child3, child4]);
717 root.detach_children(&[child2, child3]);
718 let root = root.id();
719
720 let hierarchy = get_hierarchy(&world, root);
721 assert_eq!(
722 hierarchy,
723 Node::new_with(root, vec![Node::new(child1), Node::new(child4)])
724 );
725 }
726
727 #[test]
728 fn detach_child() {
729 let mut world = World::new();
730 let child1 = world.spawn_empty().id();
731 let child2 = world.spawn_empty().id();
732 let child3 = world.spawn_empty().id();
733
734 let mut root = world.spawn_empty();
735 root.add_children(&[child1, child2, child3]);
736 root.detach_child(child2);
737 let root = root.id();
738
739 let hierarchy = get_hierarchy(&world, root);
740 assert_eq!(
741 hierarchy,
742 Node::new_with(root, vec![Node::new(child1), Node::new(child3)])
743 );
744 }
745
746 #[test]
747 fn self_parenting_invalid() {
748 let mut world = World::new();
749 let id = world.spawn_empty().id();
750 world.entity_mut(id).insert(ChildOf(id));
751 assert!(
752 world.entity(id).get::<ChildOf>().is_none(),
753 "invalid ChildOf relationships should self-remove"
754 );
755 }
756
757 #[test]
758 fn missing_parent_invalid() {
759 let mut world = World::new();
760 let parent = world.spawn_empty().id();
761 world.entity_mut(parent).despawn();
762 let id = world.spawn(ChildOf(parent)).id();
763 assert!(
764 world.entity(id).get::<ChildOf>().is_none(),
765 "invalid ChildOf relationships should self-remove"
766 );
767 }
768
769 #[test]
770 fn reinsert_same_parent() {
771 let mut world = World::new();
772 let parent = world.spawn_empty().id();
773 let id = world.spawn(ChildOf(parent)).id();
774 world.entity_mut(id).insert(ChildOf(parent));
775 assert_eq!(
776 Some(&ChildOf(parent)),
777 world.entity(id).get::<ChildOf>(),
778 "ChildOf should still be there"
779 );
780 }
781
782 #[test]
783 fn spawn_children() {
784 let mut world = World::new();
785 let id = world.spawn(Children::spawn((Spawn(()), Spawn(())))).id();
786 assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 2,);
787 }
788
789 #[test]
790 fn spawn_many_children() {
791 let mut world = World::new();
792
793 world.spawn(children![]);
795
796 let id = world
798 .spawn(children![(), (), (), (), (), (), (), (), (), (), (), ()])
799 .id();
800
801 assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 12,);
802
803 let id = world
805 .spawn(children![
806 (),
807 (),
808 (),
809 (),
810 (),
811 (),
812 (),
813 (),
814 (),
815 (),
816 (),
817 (),
818 (),
819 ])
820 .id();
821
822 assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 13,);
823 }
824
825 #[test]
826 fn replace_children() {
827 let mut world = World::new();
828 let parent = world.spawn(Children::spawn((Spawn(()), Spawn(())))).id();
829 let &[child_a, child_b] = &world.entity(parent).get::<Children>().unwrap().0[..] else {
830 panic!("Tried to spawn 2 children on an entity and didn't get 2 children");
831 };
832
833 let child_c = world.spawn_empty().id();
834
835 world
836 .entity_mut(parent)
837 .replace_children(&[child_a, child_c]);
838
839 let children = world.entity(parent).get::<Children>().unwrap();
840
841 assert!(children.contains(&child_a));
842 assert!(children.contains(&child_c));
843 assert!(!children.contains(&child_b));
844
845 assert_eq!(
846 world.entity(child_a).get::<ChildOf>().unwrap(),
847 &ChildOf(parent)
848 );
849 assert_eq!(
850 world.entity(child_c).get::<ChildOf>().unwrap(),
851 &ChildOf(parent)
852 );
853 assert!(world.entity(child_b).get::<ChildOf>().is_none());
854 }
855
856 #[test]
857 fn replace_children_with_nothing() {
858 let mut world = World::new();
859 let parent = world.spawn_empty().id();
860 let child_a = world.spawn_empty().id();
861 let child_b = world.spawn_empty().id();
862
863 world.entity_mut(parent).add_children(&[child_a, child_b]);
864
865 assert_eq!(world.entity(parent).get::<Children>().unwrap().len(), 2);
866
867 world.entity_mut(parent).replace_children(&[]);
868
869 assert!(world.entity(child_a).get::<ChildOf>().is_none());
870 assert!(world.entity(child_b).get::<ChildOf>().is_none());
871 }
872
873 #[test]
874 fn insert_same_child_twice() {
875 let mut world = World::new();
876
877 let parent = world.spawn_empty().id();
878 let child = world.spawn_empty().id();
879
880 world.entity_mut(parent).add_child(child);
881 world.entity_mut(parent).add_child(child);
882
883 let children = world.get::<Children>(parent).unwrap();
884 assert_eq!(children.0, [child]);
885 assert_eq!(
886 world.entity(child).get::<ChildOf>().unwrap(),
887 &ChildOf(parent)
888 );
889 }
890
891 #[test]
892 fn replace_with_difference() {
893 let mut world = World::new();
894
895 let parent = world.spawn_empty().id();
896 let child_a = world.spawn_empty().id();
897 let child_b = world.spawn_empty().id();
898 let child_c = world.spawn_empty().id();
899 let child_d = world.spawn_empty().id();
900
901 world.entity_mut(parent).replace_children_with_difference(
903 &[],
904 &[child_a, child_b],
905 &[child_a, child_b],
906 );
907
908 assert_eq!(
909 world.entity(child_a).get::<ChildOf>().unwrap(),
910 &ChildOf(parent)
911 );
912 assert_eq!(
913 world.entity(child_b).get::<ChildOf>().unwrap(),
914 &ChildOf(parent)
915 );
916 assert_eq!(
917 world.entity(parent).get::<Children>().unwrap().0,
918 [child_a, child_b]
919 );
920
921 world.entity_mut(parent).replace_children_with_difference(
923 &[child_b],
924 &[child_d, child_c, child_a],
925 &[child_c, child_d],
926 );
927 assert_eq!(
928 world.entity(child_a).get::<ChildOf>().unwrap(),
929 &ChildOf(parent)
930 );
931 assert_eq!(
932 world.entity(child_c).get::<ChildOf>().unwrap(),
933 &ChildOf(parent)
934 );
935 assert_eq!(
936 world.entity(child_d).get::<ChildOf>().unwrap(),
937 &ChildOf(parent)
938 );
939 assert_eq!(
940 world.entity(parent).get::<Children>().unwrap().0,
941 [child_d, child_c, child_a]
942 );
943 assert!(!world.entity(child_b).contains::<ChildOf>());
944
945 world.entity_mut(parent).replace_children_with_difference(
947 &[child_a, child_d, child_c],
948 &[],
949 &[],
950 );
951 assert!(!world.entity(parent).contains::<Children>());
952 assert!(!world.entity(child_a).contains::<ChildOf>());
953 assert!(!world.entity(child_b).contains::<ChildOf>());
954 assert!(!world.entity(child_c).contains::<ChildOf>());
955 assert!(!world.entity(child_d).contains::<ChildOf>());
956 }
957
958 #[test]
959 fn replace_with_difference_on_empty() {
960 let mut world = World::new();
961
962 let parent = world.spawn_empty().id();
963 let child_a = world.spawn_empty().id();
964
965 world
966 .entity_mut(parent)
967 .replace_children_with_difference(&[child_a], &[], &[]);
968
969 assert!(!world.entity(parent).contains::<Children>());
970 assert!(!world.entity(child_a).contains::<ChildOf>());
971 }
972
973 #[test]
974 fn replace_with_difference_totally_new_children() {
975 let mut world = World::new();
976
977 let parent = world.spawn_empty().id();
978 let child_a = world.spawn_empty().id();
979 let child_b = world.spawn_empty().id();
980 let child_c = world.spawn_empty().id();
981 let child_d = world.spawn_empty().id();
982
983 world.entity_mut(parent).replace_children_with_difference(
985 &[],
986 &[child_a, child_b],
987 &[child_a, child_b],
988 );
989
990 assert_eq!(
991 world.entity(child_a).get::<ChildOf>().unwrap(),
992 &ChildOf(parent)
993 );
994 assert_eq!(
995 world.entity(child_b).get::<ChildOf>().unwrap(),
996 &ChildOf(parent)
997 );
998 assert_eq!(
999 world.entity(parent).get::<Children>().unwrap().0,
1000 [child_a, child_b]
1001 );
1002
1003 world.entity_mut(parent).replace_children_with_difference(
1005 &[child_b, child_a],
1006 &[child_d, child_c],
1007 &[child_c, child_d],
1008 );
1009 assert_eq!(
1010 world.entity(child_c).get::<ChildOf>().unwrap(),
1011 &ChildOf(parent)
1012 );
1013 assert_eq!(
1014 world.entity(child_d).get::<ChildOf>().unwrap(),
1015 &ChildOf(parent)
1016 );
1017 assert_eq!(
1018 world.entity(parent).get::<Children>().unwrap().0,
1019 [child_d, child_c]
1020 );
1021 assert!(!world.entity(child_a).contains::<ChildOf>());
1022 assert!(!world.entity(child_b).contains::<ChildOf>());
1023 }
1024
1025 #[test]
1026 fn replace_children_order() {
1027 let mut world = World::new();
1028
1029 let parent = world.spawn_empty().id();
1030 let child_a = world.spawn_empty().id();
1031 let child_b = world.spawn_empty().id();
1032 let child_c = world.spawn_empty().id();
1033 let child_d = world.spawn_empty().id();
1034
1035 let initial_order = [child_a, child_b, child_c, child_d];
1036 world.entity_mut(parent).add_children(&initial_order);
1037
1038 assert_eq!(
1039 world.entity_mut(parent).get::<Children>().unwrap().0,
1040 initial_order
1041 );
1042
1043 let new_order = [child_d, child_b, child_a, child_c];
1044 world.entity_mut(parent).replace_children(&new_order);
1045
1046 assert_eq!(world.entity(parent).get::<Children>().unwrap().0, new_order);
1047 }
1048
1049 #[test]
1050 fn replace_children_duplicates() {
1051 let mut world = World::new();
1052
1053 let parent = world.spawn_empty().id();
1054 let child_a = world.spawn_empty().id();
1055 let child_b = world.spawn_empty().id();
1056
1057 world
1058 .entity_mut(parent)
1059 .add_children(&[child_a])
1060 .replace_children(&[child_a, child_a]);
1061
1062 assert_eq!(world.entity(parent).get::<Children>().unwrap().0, [child_a]);
1063
1064 world.entity_mut(parent).clear();
1065
1066 world
1069 .entity_mut(parent)
1070 .add_children(&[child_b])
1071 .replace_children(&[child_a, child_b, child_a]);
1072
1073 assert_eq!(
1074 world.entity(parent).get::<Children>().unwrap().0,
1075 [child_a, child_b]
1076 );
1077
1078 world.entity_mut(parent).clear();
1079
1080 world
1081 .entity_mut(parent)
1082 .add_children(&[child_a])
1083 .replace_children(&[child_a, child_b, child_a]);
1084
1085 assert_eq!(
1086 world.entity(parent).get::<Children>().unwrap().0,
1087 [child_a, child_b]
1088 );
1089 }
1090
1091 #[test]
1092 #[should_panic]
1093 #[cfg_attr(
1094 not(debug_assertions),
1095 ignore = "we don't check invariants if debug assertions are off"
1096 )]
1097 fn replace_diff_invariant_overlapping_unrelate_with_relate() {
1098 let mut world = World::new();
1099
1100 let parent = world.spawn_empty().id();
1101 let child_a = world.spawn_empty().id();
1102
1103 world
1104 .entity_mut(parent)
1105 .replace_children_with_difference(&[], &[child_a], &[child_a]);
1106
1107 world
1109 .entity_mut(parent)
1110 .replace_children_with_difference(&[child_a], &[child_a], &[]);
1111 }
1112
1113 #[test]
1114 #[should_panic]
1115 #[cfg_attr(
1116 not(debug_assertions),
1117 ignore = "we don't check invariants if debug assertions are off"
1118 )]
1119 fn replace_diff_invariant_overlapping_unrelate_with_newly() {
1120 let mut world = World::new();
1121
1122 let parent = world.spawn_empty().id();
1123 let child_a = world.spawn_empty().id();
1124 let child_b = world.spawn_empty().id();
1125
1126 world
1127 .entity_mut(parent)
1128 .replace_children_with_difference(&[], &[child_a], &[child_a]);
1129
1130 world.entity_mut(parent).replace_children_with_difference(
1132 &[child_b],
1133 &[child_a, child_b],
1134 &[child_b],
1135 );
1136 }
1137
1138 #[test]
1139 #[should_panic]
1140 #[cfg_attr(
1141 not(debug_assertions),
1142 ignore = "we don't check invariants if debug assertions are off"
1143 )]
1144 fn replace_diff_invariant_newly_not_subset() {
1145 let mut world = World::new();
1146
1147 let parent = world.spawn_empty().id();
1148 let child_a = world.spawn_empty().id();
1149 let child_b = world.spawn_empty().id();
1150
1151 world.entity_mut(parent).replace_children_with_difference(
1153 &[],
1154 &[child_a, child_b],
1155 &[child_a],
1156 );
1157 }
1158
1159 #[test]
1160 fn child_replace_hook_skip() {
1161 let mut world = World::new();
1162 let parent = world.spawn_empty().id();
1163 let other = world.spawn_empty().id();
1164 let child = world.spawn(ChildOf(parent)).id();
1165 world
1166 .entity_mut(child)
1167 .insert_with_relationship_hook_mode(ChildOf(other), RelationshipHookMode::Skip);
1168 assert_eq!(
1169 &**world.entity(parent).get::<Children>().unwrap(),
1170 &[child],
1171 "Children should still have the old value, as on_insert/on_discard didn't run"
1172 );
1173 }
1174}