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]
557macro_rules! children {
558 [$($child:expr),*$(,)?] => {
559 $crate::related!($crate::hierarchy::Children [$($child),*])
560 };
561}
562
563#[cfg(test)]
564mod tests {
565 use crate::{
566 entity::Entity,
567 hierarchy::{ChildOf, Children},
568 relationship::{RelationshipHookMode, RelationshipTarget},
569 spawn::{Spawn, SpawnRelated},
570 world::World,
571 };
572 use alloc::{vec, vec::Vec};
573
574 #[derive(PartialEq, Eq, Debug)]
575 struct Node {
576 entity: Entity,
577 children: Vec<Node>,
578 }
579
580 impl Node {
581 fn new(entity: Entity) -> Self {
582 Self {
583 entity,
584 children: Vec::new(),
585 }
586 }
587
588 fn new_with(entity: Entity, children: Vec<Node>) -> Self {
589 Self { entity, children }
590 }
591 }
592
593 fn get_hierarchy(world: &World, entity: Entity) -> Node {
594 Node {
595 entity,
596 children: world
597 .entity(entity)
598 .get::<Children>()
599 .map_or_else(Default::default, |c| {
600 c.iter().map(|e| get_hierarchy(world, e)).collect()
601 }),
602 }
603 }
604
605 #[test]
606 fn hierarchy() {
607 let mut world = World::new();
608 let root = world.spawn_empty().id();
609 let child1 = world.spawn(ChildOf(root)).id();
610 let grandchild = world.spawn(ChildOf(child1)).id();
611 let child2 = world.spawn(ChildOf(root)).id();
612
613 let hierarchy = get_hierarchy(&world, root);
615 assert_eq!(
616 hierarchy,
617 Node::new_with(
618 root,
619 vec![
620 Node::new_with(child1, vec![Node::new(grandchild)]),
621 Node::new(child2)
622 ]
623 )
624 );
625
626 world.entity_mut(child1).remove::<ChildOf>();
628 let hierarchy = get_hierarchy(&world, root);
629 assert_eq!(hierarchy, Node::new_with(root, vec![Node::new(child2)]));
630
631 world.entity_mut(child1).insert(ChildOf(root));
633 let hierarchy = get_hierarchy(&world, root);
634 assert_eq!(
635 hierarchy,
636 Node::new_with(
637 root,
638 vec![
639 Node::new(child2),
640 Node::new_with(child1, vec![Node::new(grandchild)])
641 ]
642 )
643 );
644
645 world.entity_mut(root).despawn();
647 assert!(world.get_entity(root).is_err());
648 assert!(world.get_entity(child1).is_err());
649 assert!(world.get_entity(child2).is_err());
650 assert!(world.get_entity(grandchild).is_err());
651 }
652
653 #[test]
654 fn with_children() {
655 let mut world = World::new();
656 let mut child1 = Entity::PLACEHOLDER;
657 let mut child2 = Entity::PLACEHOLDER;
658 let root = world
659 .spawn_empty()
660 .with_children(|p| {
661 child1 = p.spawn_empty().id();
662 child2 = p.spawn_empty().id();
663 })
664 .id();
665
666 let hierarchy = get_hierarchy(&world, root);
667 assert_eq!(
668 hierarchy,
669 Node::new_with(root, vec![Node::new(child1), Node::new(child2)])
670 );
671 }
672
673 #[test]
674 fn add_children() {
675 let mut world = World::new();
676 let child1 = world.spawn_empty().id();
677 let child2 = world.spawn_empty().id();
678 let root = world.spawn_empty().add_children(&[child1, child2]).id();
679
680 let hierarchy = get_hierarchy(&world, root);
681 assert_eq!(
682 hierarchy,
683 Node::new_with(root, vec![Node::new(child1), Node::new(child2)])
684 );
685 }
686
687 #[test]
688 fn insert_children() {
689 let mut world = World::new();
690 let child1 = world.spawn_empty().id();
691 let child2 = world.spawn_empty().id();
692 let child3 = world.spawn_empty().id();
693 let child4 = world.spawn_empty().id();
694
695 let mut entity_world_mut = world.spawn_empty();
696
697 let first_children = entity_world_mut.add_children(&[child1, child2]);
698
699 let root = first_children.insert_children(1, &[child3, child4]).id();
700
701 let hierarchy = get_hierarchy(&world, root);
702 assert_eq!(
703 hierarchy,
704 Node::new_with(
705 root,
706 vec![
707 Node::new(child1),
708 Node::new(child3),
709 Node::new(child4),
710 Node::new(child2)
711 ]
712 )
713 );
714 }
715
716 #[test]
717 fn insert_child() {
718 let mut world = World::new();
719 let child1 = world.spawn_empty().id();
720 let child2 = world.spawn_empty().id();
721 let child3 = world.spawn_empty().id();
722
723 let mut entity_world_mut = world.spawn_empty();
724
725 let first_children = entity_world_mut.add_children(&[child1, child2]);
726
727 let root = first_children.insert_child(1, child3).id();
728
729 let hierarchy = get_hierarchy(&world, root);
730 assert_eq!(
731 hierarchy,
732 Node::new_with(
733 root,
734 vec![Node::new(child1), Node::new(child3), Node::new(child2)]
735 )
736 );
737 }
738
739 #[test]
741 fn insert_children_index_bound() {
742 let mut world = World::new();
743 let child1 = world.spawn_empty().id();
744 let child2 = world.spawn_empty().id();
745 let child3 = world.spawn_empty().id();
746 let child4 = world.spawn_empty().id();
747
748 let mut entity_world_mut = world.spawn_empty();
749
750 let first_children = entity_world_mut.add_children(&[child1, child2]).id();
751 let hierarchy = get_hierarchy(&world, first_children);
752 assert_eq!(
753 hierarchy,
754 Node::new_with(first_children, vec![Node::new(child1), Node::new(child2)])
755 );
756
757 let root = world
758 .entity_mut(first_children)
759 .insert_children(usize::MAX, &[child3, child4])
760 .id();
761 let hierarchy = get_hierarchy(&world, root);
762 assert_eq!(
763 hierarchy,
764 Node::new_with(
765 root,
766 vec![
767 Node::new(child1),
768 Node::new(child2),
769 Node::new(child3),
770 Node::new(child4),
771 ]
772 )
773 );
774 }
775
776 #[test]
777 fn detach_children() {
778 let mut world = World::new();
779 let child1 = world.spawn_empty().id();
780 let child2 = world.spawn_empty().id();
781 let child3 = world.spawn_empty().id();
782 let child4 = world.spawn_empty().id();
783
784 let mut root = world.spawn_empty();
785 root.add_children(&[child1, child2, child3, child4]);
786 root.detach_children(&[child2, child3]);
787 let root = root.id();
788
789 let hierarchy = get_hierarchy(&world, root);
790 assert_eq!(
791 hierarchy,
792 Node::new_with(root, vec![Node::new(child1), Node::new(child4)])
793 );
794 }
795
796 #[test]
797 fn detach_child() {
798 let mut world = World::new();
799 let child1 = world.spawn_empty().id();
800 let child2 = world.spawn_empty().id();
801 let child3 = world.spawn_empty().id();
802
803 let mut root = world.spawn_empty();
804 root.add_children(&[child1, child2, child3]);
805 root.detach_child(child2);
806 let root = root.id();
807
808 let hierarchy = get_hierarchy(&world, root);
809 assert_eq!(
810 hierarchy,
811 Node::new_with(root, vec![Node::new(child1), Node::new(child3)])
812 );
813 }
814
815 #[test]
816 fn self_parenting_invalid() {
817 let mut world = World::new();
818 let id = world.spawn_empty().id();
819 world.entity_mut(id).insert(ChildOf(id));
820 assert!(
821 world.entity(id).get::<ChildOf>().is_none(),
822 "invalid ChildOf relationships should self-remove"
823 );
824 }
825
826 #[test]
827 fn missing_parent_invalid() {
828 let mut world = World::new();
829 let parent = world.spawn_empty().id();
830 world.entity_mut(parent).despawn();
831 let id = world.spawn(ChildOf(parent)).id();
832 assert!(
833 world.entity(id).get::<ChildOf>().is_none(),
834 "invalid ChildOf relationships should self-remove"
835 );
836 }
837
838 #[test]
839 fn reinsert_same_parent() {
840 let mut world = World::new();
841 let parent = world.spawn_empty().id();
842 let id = world.spawn(ChildOf(parent)).id();
843 world.entity_mut(id).insert(ChildOf(parent));
844 assert_eq!(
845 Some(&ChildOf(parent)),
846 world.entity(id).get::<ChildOf>(),
847 "ChildOf should still be there"
848 );
849 }
850
851 #[test]
852 fn spawn_children() {
853 let mut world = World::new();
854 let id = world.spawn(Children::spawn((Spawn(()), Spawn(())))).id();
855 assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 2,);
856 }
857
858 #[test]
859 fn spawn_many_children() {
860 let mut world = World::new();
861
862 world.spawn(children![]);
864
865 let id = world
867 .spawn(children![(), (), (), (), (), (), (), (), (), (), (), ()])
868 .id();
869
870 assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 12,);
871
872 let id = world
874 .spawn(children![
875 (),
876 (),
877 (),
878 (),
879 (),
880 (),
881 (),
882 (),
883 (),
884 (),
885 (),
886 (),
887 (),
888 ])
889 .id();
890
891 assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 13,);
892 }
893
894 #[test]
895 fn replace_children() {
896 let mut world = World::new();
897 let parent = world.spawn(Children::spawn((Spawn(()), Spawn(())))).id();
898 let &[child_a, child_b] = &world.entity(parent).get::<Children>().unwrap().0[..] else {
899 panic!("Tried to spawn 2 children on an entity and didn't get 2 children");
900 };
901
902 let child_c = world.spawn_empty().id();
903
904 world
905 .entity_mut(parent)
906 .replace_children(&[child_a, child_c]);
907
908 let children = world.entity(parent).get::<Children>().unwrap();
909
910 assert!(children.contains(&child_a));
911 assert!(children.contains(&child_c));
912 assert!(!children.contains(&child_b));
913
914 assert_eq!(
915 world.entity(child_a).get::<ChildOf>().unwrap(),
916 &ChildOf(parent)
917 );
918 assert_eq!(
919 world.entity(child_c).get::<ChildOf>().unwrap(),
920 &ChildOf(parent)
921 );
922 assert!(world.entity(child_b).get::<ChildOf>().is_none());
923 }
924
925 #[test]
926 fn replace_children_with_nothing() {
927 let mut world = World::new();
928 let parent = world.spawn_empty().id();
929 let child_a = world.spawn_empty().id();
930 let child_b = world.spawn_empty().id();
931
932 world.entity_mut(parent).add_children(&[child_a, child_b]);
933
934 assert_eq!(world.entity(parent).get::<Children>().unwrap().len(), 2);
935
936 world.entity_mut(parent).replace_children(&[]);
937
938 assert!(world.entity(child_a).get::<ChildOf>().is_none());
939 assert!(world.entity(child_b).get::<ChildOf>().is_none());
940 }
941
942 #[test]
943 fn insert_same_child_twice() {
944 let mut world = World::new();
945
946 let parent = world.spawn_empty().id();
947 let child = world.spawn_empty().id();
948
949 world.entity_mut(parent).add_child(child);
950 world.entity_mut(parent).add_child(child);
951
952 let children = world.get::<Children>(parent).unwrap();
953 assert_eq!(children.0, [child]);
954 assert_eq!(
955 world.entity(child).get::<ChildOf>().unwrap(),
956 &ChildOf(parent)
957 );
958 }
959
960 #[test]
961 fn replace_with_difference() {
962 let mut world = World::new();
963
964 let parent = world.spawn_empty().id();
965 let child_a = world.spawn_empty().id();
966 let child_b = world.spawn_empty().id();
967 let child_c = world.spawn_empty().id();
968 let child_d = world.spawn_empty().id();
969
970 world.entity_mut(parent).replace_children_with_difference(
972 &[],
973 &[child_a, child_b],
974 &[child_a, child_b],
975 );
976
977 assert_eq!(
978 world.entity(child_a).get::<ChildOf>().unwrap(),
979 &ChildOf(parent)
980 );
981 assert_eq!(
982 world.entity(child_b).get::<ChildOf>().unwrap(),
983 &ChildOf(parent)
984 );
985 assert_eq!(
986 world.entity(parent).get::<Children>().unwrap().0,
987 [child_a, child_b]
988 );
989
990 world.entity_mut(parent).replace_children_with_difference(
992 &[child_b],
993 &[child_d, child_c, child_a],
994 &[child_c, child_d],
995 );
996 assert_eq!(
997 world.entity(child_a).get::<ChildOf>().unwrap(),
998 &ChildOf(parent)
999 );
1000 assert_eq!(
1001 world.entity(child_c).get::<ChildOf>().unwrap(),
1002 &ChildOf(parent)
1003 );
1004 assert_eq!(
1005 world.entity(child_d).get::<ChildOf>().unwrap(),
1006 &ChildOf(parent)
1007 );
1008 assert_eq!(
1009 world.entity(parent).get::<Children>().unwrap().0,
1010 [child_d, child_c, child_a]
1011 );
1012 assert!(!world.entity(child_b).contains::<ChildOf>());
1013
1014 world.entity_mut(parent).replace_children_with_difference(
1016 &[child_a, child_d, child_c],
1017 &[],
1018 &[],
1019 );
1020 assert!(!world.entity(parent).contains::<Children>());
1021 assert!(!world.entity(child_a).contains::<ChildOf>());
1022 assert!(!world.entity(child_b).contains::<ChildOf>());
1023 assert!(!world.entity(child_c).contains::<ChildOf>());
1024 assert!(!world.entity(child_d).contains::<ChildOf>());
1025 }
1026
1027 #[test]
1028 fn replace_with_difference_on_empty() {
1029 let mut world = World::new();
1030
1031 let parent = world.spawn_empty().id();
1032 let child_a = world.spawn_empty().id();
1033
1034 world
1035 .entity_mut(parent)
1036 .replace_children_with_difference(&[child_a], &[], &[]);
1037
1038 assert!(!world.entity(parent).contains::<Children>());
1039 assert!(!world.entity(child_a).contains::<ChildOf>());
1040 }
1041
1042 #[test]
1043 fn replace_with_difference_totally_new_children() {
1044 let mut world = World::new();
1045
1046 let parent = world.spawn_empty().id();
1047 let child_a = world.spawn_empty().id();
1048 let child_b = world.spawn_empty().id();
1049 let child_c = world.spawn_empty().id();
1050 let child_d = world.spawn_empty().id();
1051
1052 world.entity_mut(parent).replace_children_with_difference(
1054 &[],
1055 &[child_a, child_b],
1056 &[child_a, child_b],
1057 );
1058
1059 assert_eq!(
1060 world.entity(child_a).get::<ChildOf>().unwrap(),
1061 &ChildOf(parent)
1062 );
1063 assert_eq!(
1064 world.entity(child_b).get::<ChildOf>().unwrap(),
1065 &ChildOf(parent)
1066 );
1067 assert_eq!(
1068 world.entity(parent).get::<Children>().unwrap().0,
1069 [child_a, child_b]
1070 );
1071
1072 world.entity_mut(parent).replace_children_with_difference(
1074 &[child_b, child_a],
1075 &[child_d, child_c],
1076 &[child_c, child_d],
1077 );
1078 assert_eq!(
1079 world.entity(child_c).get::<ChildOf>().unwrap(),
1080 &ChildOf(parent)
1081 );
1082 assert_eq!(
1083 world.entity(child_d).get::<ChildOf>().unwrap(),
1084 &ChildOf(parent)
1085 );
1086 assert_eq!(
1087 world.entity(parent).get::<Children>().unwrap().0,
1088 [child_d, child_c]
1089 );
1090 assert!(!world.entity(child_a).contains::<ChildOf>());
1091 assert!(!world.entity(child_b).contains::<ChildOf>());
1092 }
1093
1094 #[test]
1095 fn replace_children_order() {
1096 let mut world = World::new();
1097
1098 let parent = world.spawn_empty().id();
1099 let child_a = world.spawn_empty().id();
1100 let child_b = world.spawn_empty().id();
1101 let child_c = world.spawn_empty().id();
1102 let child_d = world.spawn_empty().id();
1103
1104 let initial_order = [child_a, child_b, child_c, child_d];
1105 world.entity_mut(parent).add_children(&initial_order);
1106
1107 assert_eq!(
1108 world.entity_mut(parent).get::<Children>().unwrap().0,
1109 initial_order
1110 );
1111
1112 let new_order = [child_d, child_b, child_a, child_c];
1113 world.entity_mut(parent).replace_children(&new_order);
1114
1115 assert_eq!(world.entity(parent).get::<Children>().unwrap().0, new_order);
1116 }
1117
1118 #[test]
1119 #[should_panic]
1120 #[cfg_attr(
1121 not(debug_assertions),
1122 ignore = "we don't check invariants if debug assertions are off"
1123 )]
1124 fn replace_diff_invariant_overlapping_unrelate_with_relate() {
1125 let mut world = World::new();
1126
1127 let parent = world.spawn_empty().id();
1128 let child_a = world.spawn_empty().id();
1129
1130 world
1131 .entity_mut(parent)
1132 .replace_children_with_difference(&[], &[child_a], &[child_a]);
1133
1134 world
1136 .entity_mut(parent)
1137 .replace_children_with_difference(&[child_a], &[child_a], &[]);
1138 }
1139
1140 #[test]
1141 #[should_panic]
1142 #[cfg_attr(
1143 not(debug_assertions),
1144 ignore = "we don't check invariants if debug assertions are off"
1145 )]
1146 fn replace_diff_invariant_overlapping_unrelate_with_newly() {
1147 let mut world = World::new();
1148
1149 let parent = world.spawn_empty().id();
1150 let child_a = world.spawn_empty().id();
1151 let child_b = world.spawn_empty().id();
1152
1153 world
1154 .entity_mut(parent)
1155 .replace_children_with_difference(&[], &[child_a], &[child_a]);
1156
1157 world.entity_mut(parent).replace_children_with_difference(
1159 &[child_b],
1160 &[child_a, child_b],
1161 &[child_b],
1162 );
1163 }
1164
1165 #[test]
1166 #[should_panic]
1167 #[cfg_attr(
1168 not(debug_assertions),
1169 ignore = "we don't check invariants if debug assertions are off"
1170 )]
1171 fn replace_diff_invariant_newly_not_subset() {
1172 let mut world = World::new();
1173
1174 let parent = world.spawn_empty().id();
1175 let child_a = world.spawn_empty().id();
1176 let child_b = world.spawn_empty().id();
1177
1178 world.entity_mut(parent).replace_children_with_difference(
1180 &[],
1181 &[child_a, child_b],
1182 &[child_a],
1183 );
1184 }
1185
1186 #[test]
1187 fn child_replace_hook_skip() {
1188 let mut world = World::new();
1189 let parent = world.spawn_empty().id();
1190 let other = world.spawn_empty().id();
1191 let child = world.spawn(ChildOf(parent)).id();
1192 world
1193 .entity_mut(child)
1194 .insert_with_relationship_hook_mode(ChildOf(other), RelationshipHookMode::Skip);
1195 assert_eq!(
1196 &**world.entity(parent).get::<Children>().unwrap(),
1197 &[child],
1198 "Children should still have the old value, as on_insert/on_replace didn't run"
1199 );
1200 }
1201}