From a735f352f789a440508cf9dd1c554b4d1db6cbb7 Mon Sep 17 00:00:00 2001 From: HampusM Date: Tue, 4 Feb 2025 19:04:51 +0100 Subject: fix(ecs): make ComponentRef & ComponentRefMut deref not able to panic --- ecs/src/system.rs | 76 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 26 deletions(-) (limited to 'ecs/src/system.rs') diff --git a/ecs/src/system.rs b/ecs/src/system.rs index 48c2723..b410d8f 100644 --- a/ecs/src/system.rs +++ b/ecs/src/system.rs @@ -13,7 +13,14 @@ use crate::component::{ FromOptional as FromOptionalComponent, FromOptionalMut as FromOptionalMutComponent, }; -use crate::lock::{Error as LockError, Lock, ReadGuard, WriteGuard}; +use crate::lock::{ + Error as LockError, + Lock, + MappedReadGuard, + MappedWriteGuard, + ReadGuard, + WriteGuard, +}; use crate::tuple::{ReduceElement as TupleReduceElement, Tuple}; use crate::World; @@ -190,7 +197,7 @@ impl TupleReduceElement for () #[derive(Debug)] pub struct ComponentRefMut<'a, ComponentT: Component> { - inner: WriteGuard<'a, Box>, + inner: MappedWriteGuard<'a, ComponentT>, _ph: PhantomData, } @@ -198,7 +205,19 @@ impl<'a, ComponentT: Component> ComponentRefMut<'a, ComponentT> { pub(crate) fn new(inner: WriteGuard<'a, Box>) -> Self { - Self { inner, _ph: PhantomData } + Self { + inner: inner.map(|component| { + let component_type_name = component.type_name(); + + component.downcast_mut::().unwrap_or_else(|| { + panic!( + "Cannot downcast component {component_type_name} to type {}", + type_name::() + ); + }) + }), + _ph: PhantomData, + } } } @@ -210,15 +229,12 @@ impl<'component, ComponentT: Component> FromOptionalMutComponent<'component> _world: &'component World, ) -> Self { - Self { - inner: inner.unwrap_or_else(|| { - panic!( - "Component {} was not found in entity", - type_name::() - ); - }), - _ph: PhantomData, - } + Self::new(inner.unwrap_or_else(|| { + panic!( + "Component {} was not found in entity", + type_name::() + ); + })) } } @@ -275,7 +291,7 @@ impl<'a, ComponentT: Component> Deref for ComponentRefMut<'a, ComponentT> fn deref(&self) -> &Self::Target { - self.inner.downcast_ref().unwrap() + &self.inner } } @@ -283,14 +299,14 @@ impl<'a, ComponentT: Component> DerefMut for ComponentRefMut<'a, ComponentT> { fn deref_mut(&mut self) -> &mut Self::Target { - self.inner.downcast_mut().unwrap() + &mut self.inner } } #[derive(Debug)] pub struct ComponentRef<'a, ComponentT: Component> { - inner: ReadGuard<'a, Box>, + inner: MappedReadGuard<'a, ComponentT>, _ph: PhantomData, } @@ -298,7 +314,18 @@ impl<'a, ComponentT: Component> ComponentRef<'a, ComponentT> { pub(crate) fn new(inner: ReadGuard<'a, Box>) -> Self { - Self { inner, _ph: PhantomData } + Self { + inner: inner.map(|component| { + component.downcast_ref::().unwrap_or_else(|| { + panic!( + "Cannot downcast component {} to type {}", + component.type_name(), + type_name::() + ); + }) + }), + _ph: PhantomData, + } } } @@ -310,15 +337,12 @@ impl<'component, ComponentT: Component> FromOptionalComponent<'component> _world: &'component World, ) -> Self { - Self { - inner: inner.unwrap_or_else(|| { - panic!( - "Component {} was not found in entity", - type_name::() - ); - }), - _ph: PhantomData, - } + Self::new(inner.unwrap_or_else(|| { + panic!( + "Component {} was not found in entity", + type_name::() + ); + })) } } @@ -375,7 +399,7 @@ impl<'a, ComponentT: Component> Deref for ComponentRef<'a, ComponentT> fn deref(&self) -> &Self::Target { - self.inner.downcast_ref().unwrap() + &self.inner } } -- cgit v1.2.3-18-g5258