@@ -185,6 +185,11 @@ impl WorldCallbackAccess {
185185 world. has_resource ( resource_id)
186186 }
187187
188+ pub fn has_entity ( & self , entity : Entity ) -> bool {
189+ let world = self . read ( ) . unwrap_or_else ( || panic ! ( "{STALE_WORLD_MSG}" ) ) ;
190+ world. has_entity ( entity)
191+ }
192+
188193 pub fn get_children ( & self , entity : Entity ) -> ScriptResult < Vec < Entity > > {
189194 let world = self . read ( ) . unwrap_or_else ( || panic ! ( "{STALE_WORLD_MSG}" ) ) ;
190195 world. get_children ( entity)
@@ -588,6 +593,11 @@ impl<'w> WorldAccessGuard<'w> {
588593 ) )
589594 }
590595 }
596+
597+ /// checks if a given entity exists and is valid
598+ pub fn is_valid_entity ( & self , entity : Entity ) -> bool {
599+ self . cell . get_entity ( entity) . is_some ( )
600+ }
591601}
592602
593603/// Impl block for higher level world methods
@@ -773,7 +783,18 @@ impl<'w> WorldAccessGuard<'w> {
773783 res_ptr. is_some ( )
774784 }
775785
786+ pub fn has_entity ( & self , entity : Entity ) -> bool {
787+ self . is_valid_entity ( entity)
788+ }
789+
776790 pub fn get_children ( & self , entity : Entity ) -> ScriptResult < Vec < Entity > > {
791+ if !self . is_valid_entity ( entity) {
792+ return Err ( ScriptError :: new_runtime_error ( format ! (
793+ "Entity does not exist or is not valid: {:?}" ,
794+ entity
795+ ) ) ) ;
796+ }
797+
777798 let access = self
778799 . get_component_access_typed :: < Children > ( )
779800 . unwrap_or_else ( || panic ! ( "{CONCURRENT_ACCESS_MSG}" ) ) ;
@@ -785,6 +806,13 @@ impl<'w> WorldAccessGuard<'w> {
785806 }
786807
787808 pub fn get_parent ( & self , entity : Entity ) -> ScriptResult < Option < Entity > > {
809+ if !self . is_valid_entity ( entity) {
810+ return Err ( ScriptError :: new_runtime_error ( format ! (
811+ "Entity does not exist or is not valid: {:?}" ,
812+ entity
813+ ) ) ) ;
814+ }
815+
788816 let access = self
789817 . get_component_access_typed :: < Parent > ( )
790818 . unwrap_or_else ( || panic ! ( "{CONCURRENT_ACCESS_MSG}" ) ) ;
@@ -795,6 +823,22 @@ impl<'w> WorldAccessGuard<'w> {
795823 }
796824
797825 pub fn push_children ( & self , parent : Entity , children : & [ Entity ] ) -> ScriptResult < ( ) > {
826+ // verify entities exist
827+ if !self . is_valid_entity ( parent) {
828+ return Err ( ScriptError :: new_runtime_error ( format ! (
829+ "The parent Entity does not exist or is not valid: {:?}" ,
830+ parent
831+ ) ) ) ;
832+ }
833+ for c in children {
834+ if !self . is_valid_entity ( * c) {
835+ return Err ( ScriptError :: new_runtime_error ( format ! (
836+ "the Entity does not exist or is not valid: {:?}" ,
837+ c
838+ ) ) ) ;
839+ }
840+ }
841+
798842 if let Some ( world) = self . get_whole_world_access ( ) {
799843 let mut queue = CommandQueue :: default ( ) ;
800844 let mut commands = Commands :: new ( & mut queue, world) ;
@@ -808,6 +852,22 @@ impl<'w> WorldAccessGuard<'w> {
808852 }
809853
810854 pub fn remove_children ( & self , parent : Entity , children : & [ Entity ] ) -> ScriptResult < ( ) > {
855+ if !self . is_valid_entity ( parent) {
856+ return Err ( ScriptError :: new_runtime_error ( format ! (
857+ "The parent Entity does not exist or is not valid: {:?}" ,
858+ parent
859+ ) ) ) ;
860+ }
861+
862+ for c in children {
863+ if !self . is_valid_entity ( * c) {
864+ return Err ( ScriptError :: new_runtime_error ( format ! (
865+ "the Entity does not exist or is not valid: {:?}" ,
866+ c
867+ ) ) ) ;
868+ }
869+ }
870+
811871 if let Some ( world) = self . get_whole_world_access ( ) {
812872 let mut queue = CommandQueue :: default ( ) ;
813873 let mut commands = Commands :: new ( & mut queue, world) ;
@@ -826,6 +886,22 @@ impl<'w> WorldAccessGuard<'w> {
826886 index : usize ,
827887 children : & [ Entity ] ,
828888 ) -> ScriptResult < ( ) > {
889+ if !self . is_valid_entity ( parent) {
890+ return Err ( ScriptError :: new_runtime_error ( format ! (
891+ "parent Entity does not exist or is not valid: {:?}" ,
892+ parent
893+ ) ) ) ;
894+ }
895+
896+ for c in children {
897+ if !self . is_valid_entity ( * c) {
898+ return Err ( ScriptError :: new_runtime_error ( format ! (
899+ "the Entity does not exist or is not valid: {:?}" ,
900+ c
901+ ) ) ) ;
902+ }
903+ }
904+
829905 if let Some ( world) = self . get_whole_world_access ( ) {
830906 let mut queue = CommandQueue :: default ( ) ;
831907 let mut commands = Commands :: new ( & mut queue, world) ;
@@ -838,11 +914,18 @@ impl<'w> WorldAccessGuard<'w> {
838914 Ok ( ( ) )
839915 }
840916
841- pub fn despawn_recursive ( & self , entity : Entity ) -> ScriptResult < ( ) > {
917+ pub fn despawn_recursive ( & self , parent : Entity ) -> ScriptResult < ( ) > {
918+ if !self . is_valid_entity ( parent) {
919+ return Err ( ScriptError :: new_runtime_error ( format ! (
920+ "parent Entity does not exist or is not valid: {:?}" ,
921+ parent
922+ ) ) ) ;
923+ }
924+
842925 if let Some ( world) = self . get_whole_world_access ( ) {
843926 let mut queue = CommandQueue :: default ( ) ;
844927 let mut commands = Commands :: new ( & mut queue, world) ;
845- commands. entity ( entity ) . despawn_recursive ( ) ;
928+ commands. entity ( parent ) . despawn_recursive ( ) ;
846929 queue. apply ( world) ;
847930 } else {
848931 panic ! ( "{CONCURRENT_WORLD_ACCESS_MSG}" )
@@ -852,6 +935,13 @@ impl<'w> WorldAccessGuard<'w> {
852935 }
853936
854937 pub fn despawn ( & self , entity : Entity ) -> ScriptResult < ( ) > {
938+ if !self . is_valid_entity ( entity) {
939+ return Err ( ScriptError :: new_runtime_error ( format ! (
940+ "Entity does not exist or is not valid: {:?}" ,
941+ entity
942+ ) ) ) ;
943+ }
944+
855945 if let Some ( world) = self . get_whole_world_access ( ) {
856946 let mut queue = CommandQueue :: default ( ) ;
857947 let mut commands = Commands :: new ( & mut queue, world) ;
@@ -864,11 +954,18 @@ impl<'w> WorldAccessGuard<'w> {
864954 Ok ( ( ) )
865955 }
866956
867- pub fn despawn_descendants ( & self , entity : Entity ) -> ScriptResult < ( ) > {
957+ pub fn despawn_descendants ( & self , parent : Entity ) -> ScriptResult < ( ) > {
958+ if !self . is_valid_entity ( parent) {
959+ return Err ( ScriptError :: new_runtime_error ( format ! (
960+ "parent Entity does not exist or is not valid: {:?}" ,
961+ parent
962+ ) ) ) ;
963+ }
964+
868965 if let Some ( world) = self . get_whole_world_access ( ) {
869966 let mut queue = CommandQueue :: default ( ) ;
870967 let mut commands = Commands :: new ( & mut queue, world) ;
871- commands. entity ( entity ) . despawn_descendants ( ) ;
968+ commands. entity ( parent ) . despawn_descendants ( ) ;
872969 queue. apply ( world) ;
873970 } else {
874971 panic ! ( "{CONCURRENT_WORLD_ACCESS_MSG}" )
0 commit comments