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 relationship::{RelatedSpawner, RelatedSpawnerCommands},
17 system::EntityCommands,
18 world::{DeferredWorld, EntityWorldMut, FromWorld, World},
19};
20use alloc::{format, string::String, 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 bevy_utils::prelude::DebugName;
26use core::ops::Deref;
27use core::slice;
28use log::warn;
29
30#[derive(Component, Clone, PartialEq, Eq, Debug)]
97#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
98#[cfg_attr(
99 feature = "bevy_reflect",
100 reflect(Component, PartialEq, Debug, FromWorld, Clone)
101)]
102#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
103#[cfg_attr(
104 all(feature = "serialize", feature = "bevy_reflect"),
105 reflect(Serialize, Deserialize)
106)]
107#[relationship(relationship_target = Children)]
108#[doc(alias = "IsChild", alias = "Parent")]
109pub struct ChildOf(#[entities] pub Entity);
110
111impl ChildOf {
112 #[inline]
114 pub fn parent(&self) -> Entity {
115 self.0
116 }
117}
118
119impl FromWorld for ChildOf {
124 #[inline(always)]
125 fn from_world(_world: &mut World) -> Self {
126 ChildOf(Entity::PLACEHOLDER)
127 }
128}
129
130#[derive(Component, Default, Debug, PartialEq, Eq)]
150#[relationship_target(relationship = ChildOf, linked_spawn)]
151#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
152#[cfg_attr(feature = "bevy_reflect", reflect(Component, FromWorld, Default))]
153#[doc(alias = "IsParent")]
154pub struct Children(Vec<Entity>);
155
156impl Children {
157 #[inline]
159 pub fn swap(&mut self, a_index: usize, b_index: usize) {
160 self.0.swap(a_index, b_index);
161 }
162
163 #[inline]
172 pub fn sort_by<F>(&mut self, compare: F)
173 where
174 F: FnMut(&Entity, &Entity) -> core::cmp::Ordering,
175 {
176 self.0.sort_by(compare);
177 }
178
179 #[inline]
188 pub fn sort_by_key<K, F>(&mut self, compare: F)
189 where
190 F: FnMut(&Entity) -> K,
191 K: Ord,
192 {
193 self.0.sort_by_key(compare);
194 }
195
196 #[inline]
204 pub fn sort_by_cached_key<K, F>(&mut self, compare: F)
205 where
206 F: FnMut(&Entity) -> K,
207 K: Ord,
208 {
209 self.0.sort_by_cached_key(compare);
210 }
211
212 #[inline]
221 pub fn sort_unstable_by<F>(&mut self, compare: F)
222 where
223 F: FnMut(&Entity, &Entity) -> core::cmp::Ordering,
224 {
225 self.0.sort_unstable_by(compare);
226 }
227
228 #[inline]
237 pub fn sort_unstable_by_key<K, F>(&mut self, compare: F)
238 where
239 F: FnMut(&Entity) -> K,
240 K: Ord,
241 {
242 self.0.sort_unstable_by_key(compare);
243 }
244}
245
246impl<'a> IntoIterator for &'a Children {
247 type Item = <Self::IntoIter as Iterator>::Item;
248
249 type IntoIter = slice::Iter<'a, Entity>;
250
251 #[inline(always)]
252 fn into_iter(self) -> Self::IntoIter {
253 self.0.iter()
254 }
255}
256
257impl Deref for Children {
258 type Target = [Entity];
259
260 fn deref(&self) -> &Self::Target {
261 &self.0
262 }
263}
264
265pub type ChildSpawner<'w> = RelatedSpawner<'w, ChildOf>;
267
268pub type ChildSpawnerCommands<'w> = RelatedSpawnerCommands<'w, ChildOf>;
270
271impl<'w> EntityWorldMut<'w> {
272 pub fn with_children(&mut self, func: impl FnOnce(&mut ChildSpawner)) -> &mut Self {
275 self.with_related_entities(func);
276 self
277 }
278
279 pub fn add_children(&mut self, children: &[Entity]) -> &mut Self {
282 self.add_related::<ChildOf>(children)
283 }
284
285 pub fn clear_children(&mut self) -> &mut Self {
288 self.clear_related::<ChildOf>()
289 }
290
291 pub fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self {
294 self.insert_related::<ChildOf>(index, children)
295 }
296
297 pub fn insert_child(&mut self, index: usize, child: Entity) -> &mut Self {
300 self.insert_related::<ChildOf>(index, &[child])
301 }
302
303 pub fn add_child(&mut self, child: Entity) -> &mut Self {
306 self.add_related::<ChildOf>(&[child])
307 }
308
309 pub fn remove_children(&mut self, children: &[Entity]) -> &mut Self {
311 self.remove_related::<ChildOf>(children)
312 }
313
314 pub fn remove_child(&mut self, child: Entity) -> &mut Self {
316 self.remove_related::<ChildOf>(&[child])
317 }
318
319 pub fn replace_children(&mut self, children: &[Entity]) -> &mut Self {
321 self.replace_related::<ChildOf>(children)
322 }
323
324 pub fn replace_children_with_difference(
335 &mut self,
336 entities_to_unrelate: &[Entity],
337 entities_to_relate: &[Entity],
338 newly_related_entities: &[Entity],
339 ) -> &mut Self {
340 self.replace_related_with_difference::<ChildOf>(
341 entities_to_unrelate,
342 entities_to_relate,
343 newly_related_entities,
344 )
345 }
346
347 pub fn with_child(&mut self, bundle: impl Bundle) -> &mut Self {
353 let parent = self.id();
354 self.world_scope(|world| {
355 world.spawn((bundle, ChildOf(parent)));
356 });
357 self
358 }
359}
360
361impl<'a> EntityCommands<'a> {
362 pub fn with_children(
364 &mut self,
365 func: impl FnOnce(&mut RelatedSpawnerCommands<ChildOf>),
366 ) -> &mut Self {
367 self.with_related_entities(func);
368 self
369 }
370
371 pub fn add_children(&mut self, children: &[Entity]) -> &mut Self {
373 self.add_related::<ChildOf>(children)
374 }
375
376 pub fn clear_children(&mut self) -> &mut Self {
379 self.clear_related::<ChildOf>()
380 }
381
382 pub fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self {
385 self.insert_related::<ChildOf>(index, children)
386 }
387
388 pub fn insert_child(&mut self, index: usize, child: Entity) -> &mut Self {
391 self.insert_related::<ChildOf>(index, &[child])
392 }
393
394 pub fn add_child(&mut self, child: Entity) -> &mut Self {
396 self.add_related::<ChildOf>(&[child])
397 }
398
399 pub fn remove_children(&mut self, children: &[Entity]) -> &mut Self {
401 self.remove_related::<ChildOf>(children)
402 }
403
404 pub fn remove_child(&mut self, child: Entity) -> &mut Self {
406 self.remove_related::<ChildOf>(&[child])
407 }
408
409 pub fn replace_children(&mut self, children: &[Entity]) -> &mut Self {
411 self.replace_related::<ChildOf>(children)
412 }
413
414 pub fn replace_children_with_difference(
425 &mut self,
426 entities_to_unrelate: &[Entity],
427 entities_to_relate: &[Entity],
428 newly_related_entities: &[Entity],
429 ) -> &mut Self {
430 self.replace_related_with_difference::<ChildOf>(
431 entities_to_unrelate,
432 entities_to_relate,
433 newly_related_entities,
434 )
435 }
436
437 pub fn with_child(&mut self, bundle: impl Bundle) -> &mut Self {
443 self.with_related::<ChildOf>(bundle);
444 self
445 }
446}
447
448pub fn validate_parent_has_component<C: Component>(
451 world: DeferredWorld,
452 HookContext { entity, caller, .. }: HookContext,
453) {
454 let entity_ref = world.entity(entity);
455 let Some(child_of) = entity_ref.get::<ChildOf>() else {
456 return;
457 };
458 let parent = child_of.parent();
459 if !world.get_entity(parent).is_ok_and(|e| e.contains::<C>()) {
460 let name: Option<String> = None;
462 let debug_name = DebugName::type_name::<C>();
463 warn!(
464 "warning[B0004]: {}{name} with the {ty_name} component has a parent ({parent}) without {ty_name}.\n\
465 This will cause inconsistent behaviors! See: https://bevy.org/learn/errors/b0004",
466 caller.map(|c| format!("{c}: ")).unwrap_or_default(),
467 ty_name = debug_name.shortname(),
468 name = name.map_or_else(
469 || format!("Entity {entity}"),
470 |s| format!("The {s} entity")
471 ),
472 );
473 }
474}
475
476#[macro_export]
506macro_rules! children {
507 [$($child:expr),*$(,)?] => {
508 $crate::hierarchy::Children::spawn($crate::recursive_spawn!($($child),*))
509 };
510}
511
512#[cfg(test)]
513mod tests {
514 use crate::{
515 entity::Entity,
516 hierarchy::{ChildOf, Children},
517 relationship::{RelationshipHookMode, RelationshipTarget},
518 spawn::{Spawn, SpawnRelated},
519 world::World,
520 };
521 use alloc::{vec, vec::Vec};
522
523 #[derive(PartialEq, Eq, Debug)]
524 struct Node {
525 entity: Entity,
526 children: Vec<Node>,
527 }
528
529 impl Node {
530 fn new(entity: Entity) -> Self {
531 Self {
532 entity,
533 children: Vec::new(),
534 }
535 }
536
537 fn new_with(entity: Entity, children: Vec<Node>) -> Self {
538 Self { entity, children }
539 }
540 }
541
542 fn get_hierarchy(world: &World, entity: Entity) -> Node {
543 Node {
544 entity,
545 children: world
546 .entity(entity)
547 .get::<Children>()
548 .map_or_else(Default::default, |c| {
549 c.iter().map(|e| get_hierarchy(world, e)).collect()
550 }),
551 }
552 }
553
554 #[test]
555 fn hierarchy() {
556 let mut world = World::new();
557 let root = world.spawn_empty().id();
558 let child1 = world.spawn(ChildOf(root)).id();
559 let grandchild = world.spawn(ChildOf(child1)).id();
560 let child2 = world.spawn(ChildOf(root)).id();
561
562 let hierarchy = get_hierarchy(&world, root);
564 assert_eq!(
565 hierarchy,
566 Node::new_with(
567 root,
568 vec![
569 Node::new_with(child1, vec![Node::new(grandchild)]),
570 Node::new(child2)
571 ]
572 )
573 );
574
575 world.entity_mut(child1).remove::<ChildOf>();
577 let hierarchy = get_hierarchy(&world, root);
578 assert_eq!(hierarchy, Node::new_with(root, vec![Node::new(child2)]));
579
580 world.entity_mut(child1).insert(ChildOf(root));
582 let hierarchy = get_hierarchy(&world, root);
583 assert_eq!(
584 hierarchy,
585 Node::new_with(
586 root,
587 vec![
588 Node::new(child2),
589 Node::new_with(child1, vec![Node::new(grandchild)])
590 ]
591 )
592 );
593
594 world.entity_mut(root).despawn();
596 assert!(world.get_entity(root).is_err());
597 assert!(world.get_entity(child1).is_err());
598 assert!(world.get_entity(child2).is_err());
599 assert!(world.get_entity(grandchild).is_err());
600 }
601
602 #[test]
603 fn with_children() {
604 let mut world = World::new();
605 let mut child1 = Entity::PLACEHOLDER;
606 let mut child2 = Entity::PLACEHOLDER;
607 let root = world
608 .spawn_empty()
609 .with_children(|p| {
610 child1 = p.spawn_empty().id();
611 child2 = p.spawn_empty().id();
612 })
613 .id();
614
615 let hierarchy = get_hierarchy(&world, root);
616 assert_eq!(
617 hierarchy,
618 Node::new_with(root, vec![Node::new(child1), Node::new(child2)])
619 );
620 }
621
622 #[test]
623 fn add_children() {
624 let mut world = World::new();
625 let child1 = world.spawn_empty().id();
626 let child2 = world.spawn_empty().id();
627 let root = world.spawn_empty().add_children(&[child1, child2]).id();
628
629 let hierarchy = get_hierarchy(&world, root);
630 assert_eq!(
631 hierarchy,
632 Node::new_with(root, vec![Node::new(child1), Node::new(child2)])
633 );
634 }
635
636 #[test]
637 fn insert_children() {
638 let mut world = World::new();
639 let child1 = world.spawn_empty().id();
640 let child2 = world.spawn_empty().id();
641 let child3 = world.spawn_empty().id();
642 let child4 = world.spawn_empty().id();
643
644 let mut entity_world_mut = world.spawn_empty();
645
646 let first_children = entity_world_mut.add_children(&[child1, child2]);
647
648 let root = first_children.insert_children(1, &[child3, child4]).id();
649
650 let hierarchy = get_hierarchy(&world, root);
651 assert_eq!(
652 hierarchy,
653 Node::new_with(
654 root,
655 vec![
656 Node::new(child1),
657 Node::new(child3),
658 Node::new(child4),
659 Node::new(child2)
660 ]
661 )
662 );
663 }
664
665 #[test]
666 fn insert_child() {
667 let mut world = World::new();
668 let child1 = world.spawn_empty().id();
669 let child2 = world.spawn_empty().id();
670 let child3 = world.spawn_empty().id();
671
672 let mut entity_world_mut = world.spawn_empty();
673
674 let first_children = entity_world_mut.add_children(&[child1, child2]);
675
676 let root = first_children.insert_child(1, child3).id();
677
678 let hierarchy = get_hierarchy(&world, root);
679 assert_eq!(
680 hierarchy,
681 Node::new_with(
682 root,
683 vec![Node::new(child1), Node::new(child3), Node::new(child2)]
684 )
685 );
686 }
687
688 #[test]
690 fn insert_children_index_bound() {
691 let mut world = World::new();
692 let child1 = world.spawn_empty().id();
693 let child2 = world.spawn_empty().id();
694 let child3 = world.spawn_empty().id();
695 let child4 = world.spawn_empty().id();
696
697 let mut entity_world_mut = world.spawn_empty();
698
699 let first_children = entity_world_mut.add_children(&[child1, child2]).id();
700 let hierarchy = get_hierarchy(&world, first_children);
701 assert_eq!(
702 hierarchy,
703 Node::new_with(first_children, vec![Node::new(child1), Node::new(child2)])
704 );
705
706 let root = world
707 .entity_mut(first_children)
708 .insert_children(usize::MAX, &[child3, child4])
709 .id();
710 let hierarchy = get_hierarchy(&world, root);
711 assert_eq!(
712 hierarchy,
713 Node::new_with(
714 root,
715 vec![
716 Node::new(child1),
717 Node::new(child2),
718 Node::new(child3),
719 Node::new(child4),
720 ]
721 )
722 );
723 }
724
725 #[test]
726 fn remove_children() {
727 let mut world = World::new();
728 let child1 = world.spawn_empty().id();
729 let child2 = world.spawn_empty().id();
730 let child3 = world.spawn_empty().id();
731 let child4 = world.spawn_empty().id();
732
733 let mut root = world.spawn_empty();
734 root.add_children(&[child1, child2, child3, child4]);
735 root.remove_children(&[child2, child3]);
736 let root = root.id();
737
738 let hierarchy = get_hierarchy(&world, root);
739 assert_eq!(
740 hierarchy,
741 Node::new_with(root, vec![Node::new(child1), Node::new(child4)])
742 );
743 }
744
745 #[test]
746 fn remove_child() {
747 let mut world = World::new();
748 let child1 = world.spawn_empty().id();
749 let child2 = world.spawn_empty().id();
750 let child3 = world.spawn_empty().id();
751
752 let mut root = world.spawn_empty();
753 root.add_children(&[child1, child2, child3]);
754 root.remove_child(child2);
755 let root = root.id();
756
757 let hierarchy = get_hierarchy(&world, root);
758 assert_eq!(
759 hierarchy,
760 Node::new_with(root, vec![Node::new(child1), Node::new(child3)])
761 );
762 }
763
764 #[test]
765 fn self_parenting_invalid() {
766 let mut world = World::new();
767 let id = world.spawn_empty().id();
768 world.entity_mut(id).insert(ChildOf(id));
769 assert!(
770 world.entity(id).get::<ChildOf>().is_none(),
771 "invalid ChildOf relationships should self-remove"
772 );
773 }
774
775 #[test]
776 fn missing_parent_invalid() {
777 let mut world = World::new();
778 let parent = world.spawn_empty().id();
779 world.entity_mut(parent).despawn();
780 let id = world.spawn(ChildOf(parent)).id();
781 assert!(
782 world.entity(id).get::<ChildOf>().is_none(),
783 "invalid ChildOf relationships should self-remove"
784 );
785 }
786
787 #[test]
788 fn reinsert_same_parent() {
789 let mut world = World::new();
790 let parent = world.spawn_empty().id();
791 let id = world.spawn(ChildOf(parent)).id();
792 world.entity_mut(id).insert(ChildOf(parent));
793 assert_eq!(
794 Some(&ChildOf(parent)),
795 world.entity(id).get::<ChildOf>(),
796 "ChildOf should still be there"
797 );
798 }
799
800 #[test]
801 fn spawn_children() {
802 let mut world = World::new();
803 let id = world.spawn(Children::spawn((Spawn(()), Spawn(())))).id();
804 assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 2,);
805 }
806
807 #[test]
808 fn spawn_many_children() {
809 let mut world = World::new();
810
811 world.spawn(children![]);
813
814 let id = world
816 .spawn(children![(), (), (), (), (), (), (), (), (), (), (), ()])
817 .id();
818
819 assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 12,);
820
821 let id = world
823 .spawn(children![
824 (),
825 (),
826 (),
827 (),
828 (),
829 (),
830 (),
831 (),
832 (),
833 (),
834 (),
835 (),
836 (),
837 ])
838 .id();
839
840 assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 13,);
841 }
842
843 #[test]
844 fn replace_children() {
845 let mut world = World::new();
846 let parent = world.spawn(Children::spawn((Spawn(()), Spawn(())))).id();
847 let &[child_a, child_b] = &world.entity(parent).get::<Children>().unwrap().0[..] else {
848 panic!("Tried to spawn 2 children on an entity and didn't get 2 children");
849 };
850
851 let child_c = world.spawn_empty().id();
852
853 world
854 .entity_mut(parent)
855 .replace_children(&[child_a, child_c]);
856
857 let children = world.entity(parent).get::<Children>().unwrap();
858
859 assert!(children.contains(&child_a));
860 assert!(children.contains(&child_c));
861 assert!(!children.contains(&child_b));
862
863 assert_eq!(
864 world.entity(child_a).get::<ChildOf>().unwrap(),
865 &ChildOf(parent)
866 );
867 assert_eq!(
868 world.entity(child_c).get::<ChildOf>().unwrap(),
869 &ChildOf(parent)
870 );
871 assert!(world.entity(child_b).get::<ChildOf>().is_none());
872 }
873
874 #[test]
875 fn replace_children_with_nothing() {
876 let mut world = World::new();
877 let parent = world.spawn_empty().id();
878 let child_a = world.spawn_empty().id();
879 let child_b = world.spawn_empty().id();
880
881 world.entity_mut(parent).add_children(&[child_a, child_b]);
882
883 assert_eq!(world.entity(parent).get::<Children>().unwrap().len(), 2);
884
885 world.entity_mut(parent).replace_children(&[]);
886
887 assert!(world.entity(child_a).get::<ChildOf>().is_none());
888 assert!(world.entity(child_b).get::<ChildOf>().is_none());
889 }
890
891 #[test]
892 fn insert_same_child_twice() {
893 let mut world = World::new();
894
895 let parent = world.spawn_empty().id();
896 let child = world.spawn_empty().id();
897
898 world.entity_mut(parent).add_child(child);
899 world.entity_mut(parent).add_child(child);
900
901 let children = world.get::<Children>(parent).unwrap();
902 assert_eq!(children.0, [child]);
903 assert_eq!(
904 world.entity(child).get::<ChildOf>().unwrap(),
905 &ChildOf(parent)
906 );
907 }
908
909 #[test]
910 fn replace_with_difference() {
911 let mut world = World::new();
912
913 let parent = world.spawn_empty().id();
914 let child_a = world.spawn_empty().id();
915 let child_b = world.spawn_empty().id();
916 let child_c = world.spawn_empty().id();
917 let child_d = world.spawn_empty().id();
918
919 world.entity_mut(parent).replace_children_with_difference(
921 &[],
922 &[child_a, child_b],
923 &[child_a, child_b],
924 );
925
926 assert_eq!(
927 world.entity(child_a).get::<ChildOf>().unwrap(),
928 &ChildOf(parent)
929 );
930 assert_eq!(
931 world.entity(child_b).get::<ChildOf>().unwrap(),
932 &ChildOf(parent)
933 );
934 assert_eq!(
935 world.entity(parent).get::<Children>().unwrap().0,
936 [child_a, child_b]
937 );
938
939 world.entity_mut(parent).replace_children_with_difference(
941 &[child_b],
942 &[child_d, child_c, child_a],
943 &[child_c, child_d],
944 );
945 assert_eq!(
946 world.entity(child_a).get::<ChildOf>().unwrap(),
947 &ChildOf(parent)
948 );
949 assert_eq!(
950 world.entity(child_c).get::<ChildOf>().unwrap(),
951 &ChildOf(parent)
952 );
953 assert_eq!(
954 world.entity(child_d).get::<ChildOf>().unwrap(),
955 &ChildOf(parent)
956 );
957 assert_eq!(
958 world.entity(parent).get::<Children>().unwrap().0,
959 [child_d, child_c, child_a]
960 );
961 assert!(!world.entity(child_b).contains::<ChildOf>());
962
963 world.entity_mut(parent).replace_children_with_difference(
965 &[child_a, child_d, child_c],
966 &[],
967 &[],
968 );
969 assert!(!world.entity(parent).contains::<Children>());
970 assert!(!world.entity(child_a).contains::<ChildOf>());
971 assert!(!world.entity(child_b).contains::<ChildOf>());
972 assert!(!world.entity(child_c).contains::<ChildOf>());
973 assert!(!world.entity(child_d).contains::<ChildOf>());
974 }
975
976 #[test]
977 fn replace_with_difference_on_empty() {
978 let mut world = World::new();
979
980 let parent = world.spawn_empty().id();
981 let child_a = world.spawn_empty().id();
982
983 world
984 .entity_mut(parent)
985 .replace_children_with_difference(&[child_a], &[], &[]);
986
987 assert!(!world.entity(parent).contains::<Children>());
988 assert!(!world.entity(child_a).contains::<ChildOf>());
989 }
990
991 #[test]
992 fn replace_with_difference_totally_new_children() {
993 let mut world = World::new();
994
995 let parent = world.spawn_empty().id();
996 let child_a = world.spawn_empty().id();
997 let child_b = world.spawn_empty().id();
998 let child_c = world.spawn_empty().id();
999 let child_d = world.spawn_empty().id();
1000
1001 world.entity_mut(parent).replace_children_with_difference(
1003 &[],
1004 &[child_a, child_b],
1005 &[child_a, child_b],
1006 );
1007
1008 assert_eq!(
1009 world.entity(child_a).get::<ChildOf>().unwrap(),
1010 &ChildOf(parent)
1011 );
1012 assert_eq!(
1013 world.entity(child_b).get::<ChildOf>().unwrap(),
1014 &ChildOf(parent)
1015 );
1016 assert_eq!(
1017 world.entity(parent).get::<Children>().unwrap().0,
1018 [child_a, child_b]
1019 );
1020
1021 world.entity_mut(parent).replace_children_with_difference(
1023 &[child_b, child_a],
1024 &[child_d, child_c],
1025 &[child_c, child_d],
1026 );
1027 assert_eq!(
1028 world.entity(child_c).get::<ChildOf>().unwrap(),
1029 &ChildOf(parent)
1030 );
1031 assert_eq!(
1032 world.entity(child_d).get::<ChildOf>().unwrap(),
1033 &ChildOf(parent)
1034 );
1035 assert_eq!(
1036 world.entity(parent).get::<Children>().unwrap().0,
1037 [child_d, child_c]
1038 );
1039 assert!(!world.entity(child_a).contains::<ChildOf>());
1040 assert!(!world.entity(child_b).contains::<ChildOf>());
1041 }
1042
1043 #[test]
1044 fn replace_children_order() {
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 let initial_order = [child_a, child_b, child_c, child_d];
1054 world.entity_mut(parent).add_children(&initial_order);
1055
1056 assert_eq!(
1057 world.entity_mut(parent).get::<Children>().unwrap().0,
1058 initial_order
1059 );
1060
1061 let new_order = [child_d, child_b, child_a, child_c];
1062 world.entity_mut(parent).replace_children(&new_order);
1063
1064 assert_eq!(world.entity(parent).get::<Children>().unwrap().0, new_order);
1065 }
1066
1067 #[test]
1068 #[should_panic]
1069 #[cfg_attr(
1070 not(debug_assertions),
1071 ignore = "we don't check invariants if debug assertions are off"
1072 )]
1073 fn replace_diff_invariant_overlapping_unrelate_with_relate() {
1074 let mut world = World::new();
1075
1076 let parent = world.spawn_empty().id();
1077 let child_a = world.spawn_empty().id();
1078
1079 world
1080 .entity_mut(parent)
1081 .replace_children_with_difference(&[], &[child_a], &[child_a]);
1082
1083 world
1085 .entity_mut(parent)
1086 .replace_children_with_difference(&[child_a], &[child_a], &[]);
1087 }
1088
1089 #[test]
1090 #[should_panic]
1091 #[cfg_attr(
1092 not(debug_assertions),
1093 ignore = "we don't check invariants if debug assertions are off"
1094 )]
1095 fn replace_diff_invariant_overlapping_unrelate_with_newly() {
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
1102 world
1103 .entity_mut(parent)
1104 .replace_children_with_difference(&[], &[child_a], &[child_a]);
1105
1106 world.entity_mut(parent).replace_children_with_difference(
1108 &[child_b],
1109 &[child_a, child_b],
1110 &[child_b],
1111 );
1112 }
1113
1114 #[test]
1115 #[should_panic]
1116 #[cfg_attr(
1117 not(debug_assertions),
1118 ignore = "we don't check invariants if debug assertions are off"
1119 )]
1120 fn replace_diff_invariant_newly_not_subset() {
1121 let mut world = World::new();
1122
1123 let parent = world.spawn_empty().id();
1124 let child_a = world.spawn_empty().id();
1125 let child_b = world.spawn_empty().id();
1126
1127 world.entity_mut(parent).replace_children_with_difference(
1129 &[],
1130 &[child_a, child_b],
1131 &[child_a],
1132 );
1133 }
1134
1135 #[test]
1136 fn child_replace_hook_skip() {
1137 let mut world = World::new();
1138 let parent = world.spawn_empty().id();
1139 let other = world.spawn_empty().id();
1140 let child = world.spawn(ChildOf(parent)).id();
1141 world
1142 .entity_mut(child)
1143 .insert_with_relationship_hook_mode(ChildOf(other), RelationshipHookMode::Skip);
1144 assert_eq!(
1145 &**world.entity(parent).get::<Children>().unwrap(),
1146 &[child],
1147 "Children should still have the old value, as on_insert/on_replace didn't run"
1148 );
1149 }
1150}