diff --git a/fyrox-animation/src/lib.rs b/fyrox-animation/src/lib.rs index f5245a34b..a8dee5d9f 100644 --- a/fyrox-animation/src/lib.rs +++ b/fyrox-animation/src/lib.rs @@ -41,6 +41,7 @@ use crate::{ }; use fxhash::FxHashMap; pub use fyrox_core as core; +use fyrox_core::pool::PoolError; use fyrox_resource::untyped::ResourceKind; use fyrox_resource::{Resource, ResourceData}; pub use pose::{AnimationPose, NodePose}; @@ -1008,7 +1009,7 @@ impl AnimationContainer { /// Tries to remove an animation from the container by its handle. #[inline] - pub fn remove(&mut self, handle: Handle>) -> Option> { + pub fn remove(&mut self, handle: Handle>) -> Result, PoolError> { self.pool.try_free(handle) } @@ -1055,13 +1056,16 @@ impl AnimationContainer { /// Tries to borrow a reference to an animation in the container. #[inline] - pub fn try_get(&self, handle: Handle>) -> Option<&Animation> { + pub fn try_get(&self, handle: Handle>) -> Result<&Animation, PoolError> { self.pool.try_borrow(handle) } /// Tries to borrow a mutable reference to an animation in the container. #[inline] - pub fn try_get_mut(&mut self, handle: Handle>) -> Option<&mut Animation> { + pub fn try_get_mut( + &mut self, + handle: Handle>, + ) -> Result<&mut Animation, PoolError> { self.pool.try_borrow_mut(handle) } diff --git a/fyrox-animation/src/machine/layer.rs b/fyrox-animation/src/machine/layer.rs index aaaaebdc3..29cf7718c 100644 --- a/fyrox-animation/src/machine/layer.rs +++ b/fyrox-animation/src/machine/layer.rs @@ -310,7 +310,7 @@ impl MachineLayer { animations: &AnimationContainer, strategy: AnimationEventCollectionStrategy, ) -> LayerAnimationEventsCollection { - if let Some(state) = self.states.try_borrow(self.active_state) { + if let Ok(state) = self.states.try_borrow(self.active_state) { return LayerAnimationEventsCollection { source: AnimationEventsSource::State { handle: self.active_state, @@ -324,8 +324,8 @@ impl MachineLayer { }) .unwrap_or_default(), }; - } else if let Some(transition) = self.transitions.try_borrow(self.active_transition) { - if let (Some(source_state), Some(dest_state)) = ( + } else if let Ok(transition) = self.transitions.try_borrow(self.active_transition) { + if let (Ok(source_state), Ok(dest_state)) = ( self.states.try_borrow(transition.source()), self.states.try_borrow(transition.dest()), ) { @@ -333,7 +333,7 @@ impl MachineLayer { match strategy { AnimationEventCollectionStrategy::All => { for state in [source_state, dest_state] { - if let Some(root) = self.nodes.try_borrow(state.root) { + if let Ok(root) = self.nodes.try_borrow(state.root) { events.extend(root.collect_animation_events( &self.nodes, params, @@ -350,7 +350,7 @@ impl MachineLayer { dest_state }; - if let Some(pose_source) = self.nodes.try_borrow(input.root) { + if let Ok(pose_source) = self.nodes.try_borrow(input.root) { events = pose_source.collect_animation_events( &self.nodes, params, @@ -366,7 +366,7 @@ impl MachineLayer { source_state }; - if let Some(pose_source) = self.nodes.try_borrow(input.root) { + if let Ok(pose_source) = self.nodes.try_borrow(input.root) { events = pose_source.collect_animation_events( &self.nodes, params, @@ -581,7 +581,7 @@ impl MachineLayer { animations: &AnimationContainer, ) -> bool { self.animations_of_state(state) - .filter_map(|a| animations.try_get(a)) + .filter_map(|a| animations.try_get(a).ok()) .all(|a| a.has_ended()) } @@ -610,7 +610,7 @@ impl MachineLayer { } if transition.condition.calculate_value(parameters, animations) { - if let Some(active_state) = self.states.try_borrow(self.active_state) { + if let Ok(active_state) = self.states.try_borrow(self.active_state) { for action in active_state.on_leave_actions.iter() { action.apply(animations); } @@ -624,7 +624,7 @@ impl MachineLayer { ); } - if let Some(source) = self.states.try_borrow(transition.dest()) { + if let Ok(source) = self.states.try_borrow(transition.dest()) { for action in source.on_enter_actions.iter() { action.apply(animations); } @@ -654,11 +654,11 @@ impl MachineLayer { let transition = &mut self.transitions[self.active_transition]; // Blend between source and dest states. - if let Some(source_pose) = self.states[transition.source()].pose(&self.nodes) { + if let Ok(source_pose) = self.states[transition.source()].pose(&self.nodes) { self.final_pose .blend_with(&source_pose, 1.0 - transition.blend_factor()); } - if let Some(dest_pose) = self.states[transition.dest()].pose(&self.nodes) { + if let Ok(dest_pose) = self.states[transition.dest()].pose(&self.nodes) { self.final_pose .blend_with(&dest_pose, transition.blend_factor()); } @@ -691,7 +691,7 @@ impl MachineLayer { } else { // We must have active state all the time when we do not have any active transition. // Just get pose from active state. - if let Some(active_state_pose) = self.states[self.active_state].pose(&self.nodes) { + if let Ok(active_state_pose) = self.states[self.active_state].pose(&self.nodes) { active_state_pose.clone_into(&mut self.final_pose); } } diff --git a/fyrox-animation/src/machine/mod.rs b/fyrox-animation/src/machine/mod.rs index 1174f4d67..b804a66f4 100644 --- a/fyrox-animation/src/machine/mod.rs +++ b/fyrox-animation/src/machine/mod.rs @@ -332,21 +332,20 @@ impl Machine { self.animations_cache.clear(); for layer in self.layers.iter_mut() { let mut states_to_check = [Some(layer.active_state()), None, None]; - if let Some(active_transition) = - layer.transitions().try_borrow(layer.active_transition()) + if let Ok(active_transition) = layer.transitions().try_borrow(layer.active_transition()) { states_to_check[1] = Some(active_transition.source); states_to_check[2] = Some(active_transition.dest); } for state_to_check in states_to_check.iter().flatten() { - if let Some(state) = layer.states().try_borrow(*state_to_check) { + if let Ok(state) = layer.states().try_borrow(*state_to_check) { state.collect_animations(layer.nodes(), &mut self.animations_cache); } } } for animation_handle in self.animations_cache.iter() { - if let Some(animation) = animations.try_get_mut(*animation_handle) { + if let Ok(animation) = animations.try_get_mut(*animation_handle) { if animation.is_enabled() { animation.tick(dt); } diff --git a/fyrox-animation/src/machine/node/blend.rs b/fyrox-animation/src/machine/node/blend.rs index 5ce291517..04715b7d6 100644 --- a/fyrox-animation/src/machine/node/blend.rs +++ b/fyrox-animation/src/machine/node/blend.rs @@ -158,7 +158,7 @@ impl AnimationPoseSource for BlendAnimations { } }; - if let Some(pose_source) = nodes + if let Ok(pose_source) = nodes .try_borrow(blend_pose.pose_source) .map(|pose_source| pose_source.eval_pose(nodes, params, animations, dt)) { @@ -185,7 +185,7 @@ impl AnimationPoseSource for BlendAnimations { AnimationEventCollectionStrategy::All => { let mut events = Vec::new(); for pose in self.pose_sources.iter() { - if let Some(source) = nodes.try_borrow(pose.pose_source) { + if let Ok(source) = nodes.try_borrow(pose.pose_source) { events.extend( source.collect_animation_events(nodes, params, animations, strategy), ); @@ -200,7 +200,7 @@ impl AnimationPoseSource for BlendAnimations { .filter_map(|s| s.weight.value(params).map(|w| (s, w))) .max_by(|(_, w1), (_, w2)| w1.partial_cmp(w2).unwrap_or(Ordering::Equal)) { - if let Some(pose_source) = nodes.try_borrow(pose.pose_source) { + if let Ok(pose_source) = nodes.try_borrow(pose.pose_source) { return pose_source .collect_animation_events(nodes, params, animations, strategy); } @@ -215,7 +215,7 @@ impl AnimationPoseSource for BlendAnimations { .filter_map(|s| s.weight.value(params).map(|w| (s, w))) .min_by(|(_, w1), (_, w2)| w1.partial_cmp(w2).unwrap_or(Ordering::Equal)) { - if let Some(pose_source) = nodes.try_borrow(pose.pose_source) { + if let Ok(pose_source) = nodes.try_borrow(pose.pose_source) { return pose_source .collect_animation_events(nodes, params, animations, strategy); } @@ -396,7 +396,7 @@ impl AnimationPoseSource for BlendAnimationsByIndex { AnimationEventCollectionStrategy::All => { let mut events = Vec::new(); for input in [prev_input, current_input] { - if let Some(source) = nodes.try_borrow(input.pose_source) { + if let Ok(source) = nodes.try_borrow(input.pose_source) { events.extend(source.collect_animation_events( nodes, params, animations, strategy, )); @@ -411,7 +411,7 @@ impl AnimationPoseSource for BlendAnimationsByIndex { current_input }; - if let Some(pose_source) = nodes.try_borrow(input.pose_source) { + if let Ok(pose_source) = nodes.try_borrow(input.pose_source) { return pose_source.collect_animation_events( nodes, params, animations, strategy, ); @@ -424,7 +424,7 @@ impl AnimationPoseSource for BlendAnimationsByIndex { prev_input }; - if let Some(pose_source) = nodes.try_borrow(input.pose_source) { + if let Ok(pose_source) = nodes.try_borrow(input.pose_source) { return pose_source.collect_animation_events( nodes, params, animations, strategy, ); @@ -436,7 +436,7 @@ impl AnimationPoseSource for BlendAnimationsByIndex { // In case where the transition is done, all the strategies does the same - just collects events // from active pose node. if let Some(current_input) = self.inputs.get(current_index as usize) { - if let Some(pose_source) = nodes.try_borrow(current_input.pose_source) { + if let Ok(pose_source) = nodes.try_borrow(current_input.pose_source) { return pose_source .collect_animation_events(nodes, params, animations, strategy); } diff --git a/fyrox-animation/src/machine/node/blendspace.rs b/fyrox-animation/src/machine/node/blendspace.rs index ac1f520fc..3aa143cab 100644 --- a/fyrox-animation/src/machine/node/blendspace.rs +++ b/fyrox-animation/src/machine/node/blendspace.rs @@ -138,7 +138,7 @@ impl AnimationPoseSource for BlendSpace { let (ib, wb) = weights[1]; let (ic, wc) = weights[2]; - if let (Some(pose_a), Some(pose_b), Some(pose_c)) = ( + if let (Ok(pose_a), Ok(pose_b), Ok(pose_c)) = ( nodes.try_borrow(self.points[ia].pose_source), nodes.try_borrow(self.points[ib].pose_source), nodes.try_borrow(self.points[ic].pose_source), @@ -173,7 +173,7 @@ impl AnimationPoseSource for BlendSpace { let (ib, wb) = weights[1]; let (ic, wc) = weights[2]; - if let (Some(pose_a), Some(pose_b), Some(pose_c)) = ( + if let (Ok(pose_a), Ok(pose_b), Ok(pose_c)) = ( nodes.try_borrow(self.points[ia].pose_source), nodes.try_borrow(self.points[ib].pose_source), nodes.try_borrow(self.points[ic].pose_source), diff --git a/fyrox-animation/src/machine/node/mod.rs b/fyrox-animation/src/machine/node/mod.rs index 36cf12075..3c3b46a3c 100644 --- a/fyrox-animation/src/machine/node/mod.rs +++ b/fyrox-animation/src/machine/node/mod.rs @@ -122,21 +122,21 @@ impl PoseNode { } PoseNode::BlendAnimations(blend_animations) => { for input in blend_animations.pose_sources.iter() { - if let Some(source) = nodes.try_borrow(input.pose_source) { + if let Ok(source) = nodes.try_borrow(input.pose_source) { source.collect_animations(nodes, animations) } } } PoseNode::BlendAnimationsByIndex(blend_animations_by_index) => { for input in blend_animations_by_index.inputs.iter() { - if let Some(source) = nodes.try_borrow(input.pose_source) { + if let Ok(source) = nodes.try_borrow(input.pose_source) { source.collect_animations(nodes, animations) } } } PoseNode::BlendSpace(blend_space) => { for point in blend_space.points() { - if let Some(source) = nodes.try_borrow(point.pose_source) { + if let Ok(source) = nodes.try_borrow(point.pose_source) { source.collect_animations(nodes, animations) } } diff --git a/fyrox-animation/src/machine/node/play.rs b/fyrox-animation/src/machine/node/play.rs index 9de955bc8..a40b53f6f 100644 --- a/fyrox-animation/src/machine/node/play.rs +++ b/fyrox-animation/src/machine/node/play.rs @@ -89,7 +89,7 @@ impl AnimationPoseSource for PlayAnimation { animations: &AnimationContainer, _dt: f32, ) -> Ref> { - if let Some(animation) = animations.try_get(self.animation) { + if let Ok(animation) = animations.try_get(self.animation) { let mut output_pose = self.output_pose.borrow_mut(); animation.pose().clone_into(&mut output_pose); // Pass the root motion (if any) so it will be blended correctly. diff --git a/fyrox-animation/src/machine/state.rs b/fyrox-animation/src/machine/state.rs index 7825c5ea0..c0f1082c4 100644 --- a/fyrox-animation/src/machine/state.rs +++ b/fyrox-animation/src/machine/state.rs @@ -32,6 +32,7 @@ use crate::{ Animation, AnimationContainer, AnimationPose, EntityId, }; use fxhash::FxHashSet; +use fyrox_core::pool::PoolError; use fyrox_core::uuid::{uuid, Uuid}; use fyrox_core::{NameProvider, TypeUuidProvider}; use std::{ @@ -100,23 +101,23 @@ impl StateAction { match self { StateAction::None => {} StateAction::RewindAnimation(animation) => { - if let Some(animation) = animations.try_get_mut(*animation) { + if let Ok(animation) = animations.try_get_mut(*animation) { animation.rewind(); } } StateAction::EnableAnimation(animation) => { - if let Some(animation) = animations.try_get_mut(*animation) { + if let Ok(animation) = animations.try_get_mut(*animation) { animation.set_enabled(true); } } StateAction::DisableAnimation(animation) => { - if let Some(animation) = animations.try_get_mut(*animation) { + if let Ok(animation) = animations.try_get_mut(*animation) { animation.set_enabled(false); } } StateAction::EnableRandomAnimation(animation_handles) => { if let Some(animation) = animation_handles.iter().choose(&mut rand::thread_rng()) { - if let Some(animation) = animations.try_get_mut(*animation) { + if let Ok(animation) = animations.try_get_mut(*animation) { animation.set_enabled(true); } } @@ -167,7 +168,10 @@ impl State { } /// Returns a final pose of the state. - pub fn pose<'a>(&self, nodes: &'a Pool>) -> Option>> { + pub fn pose<'a>( + &self, + nodes: &'a Pool>, + ) -> Result>, PoolError> { nodes.try_borrow(self.root).map(|root| root.pose()) } @@ -177,7 +181,7 @@ impl State { nodes: &Pool>, animations: &mut FxHashSet>>, ) { - if let Some(root) = nodes.try_borrow(self.root) { + if let Ok(root) = nodes.try_borrow(self.root) { root.collect_animations(nodes, animations); } } @@ -189,7 +193,7 @@ impl State { animations: &AnimationContainer, dt: f32, ) { - if let Some(root) = nodes.try_borrow(self.root) { + if let Ok(root) = nodes.try_borrow(self.root) { root.eval_pose(nodes, params, animations, dt); } } diff --git a/fyrox-animation/src/machine/transition.rs b/fyrox-animation/src/machine/transition.rs index 9f2824d1c..22d28a783 100644 --- a/fyrox-animation/src/machine/transition.rs +++ b/fyrox-animation/src/machine/transition.rs @@ -436,9 +436,10 @@ impl LogicNode { lhs_value ^ rhs_value } LogicNode::Not(node) => !node.lhs.calculate_value(parameters, animations), - LogicNode::IsAnimationEnded(animation) => { - animations.try_get(*animation).is_none_or(|a| a.has_ended()) - } + LogicNode::IsAnimationEnded(animation) => animations + .try_get(*animation) + .ok() + .is_none_or(|a| a.has_ended()), } } } diff --git a/fyrox-core/src/pool/mod.rs b/fyrox-core/src/pool/mod.rs index db106752e..307f8492f 100644 --- a/fyrox-core/src/pool/mod.rs +++ b/fyrox-core/src/pool/mod.rs @@ -427,21 +427,21 @@ where } } -#[derive(PartialEq)] -pub enum PoolError { +#[derive(PartialEq, Copy, Clone)] +pub enum PoolError { InvalidIndex(u32), InvalidGeneration(u32), - InvalidType(Handle), - Empty(Handle), - NoSuchComponent(Handle), - MutablyBorrowed(Handle), - ImmutablyBorrowed(Handle), - UnknownDependentObject(Handle), + InvalidType(ErasedHandle), + Empty(ErasedHandle), + NoSuchComponent(ErasedHandle), + MutablyBorrowed(ErasedHandle), + ImmutablyBorrowed(ErasedHandle), + UnknownDependentObject(ErasedHandle), } -impl std::error::Error for PoolError {} +impl std::error::Error for PoolError {} -impl Display for PoolError { +impl Display for PoolError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { Self::InvalidIndex(index) => { @@ -495,7 +495,7 @@ impl Display for PoolError { } } -impl Debug for PoolError { +impl Debug for PoolError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self) } @@ -526,33 +526,33 @@ where u32::try_from(self.records.len()).expect("Number of records overflowed u32") } - fn records_get(&self, index: u32) -> Result<&PoolRecord, PoolError> { + fn records_get(&self, index: u32) -> Result<&PoolRecord, PoolError> { self.records .get(usize::try_from(index).expect("Index overflowed usize")) .ok_or(PoolError::InvalidIndex(index)) } - fn records_get_mut(&mut self, index: u32) -> Result<&mut PoolRecord, PoolError> { + fn records_get_mut(&mut self, index: u32) -> Result<&mut PoolRecord, PoolError> { self.records .get_mut(usize::try_from(index).expect("Index overflowed usize")) .ok_or(PoolError::InvalidIndex(index)) } #[inline] - pub fn try_get>(&self, handle: Handle) -> Result<&U, PoolError> { + pub fn try_get>(&self, handle: Handle) -> Result<&U, PoolError> { let handle = handle.transmute(); let pool_object = self.try_borrow(handle)?; - U::convert_to_dest_type(pool_object).ok_or(PoolError::InvalidType(handle)) + U::convert_to_dest_type(pool_object).ok_or(PoolError::InvalidType(handle.into())) } #[inline] pub fn try_get_mut>( &mut self, handle: Handle, - ) -> Result<&mut U, PoolError> { + ) -> Result<&mut U, PoolError> { let handle = handle.transmute(); let pool_object = self.try_borrow_mut(handle)?; - U::convert_to_dest_type_mut(pool_object).ok_or(PoolError::InvalidType(handle)) + U::convert_to_dest_type_mut(pool_object).ok_or(PoolError::InvalidType(handle.into())) } #[inline] @@ -830,10 +830,10 @@ where /// generation of pool record at handle index (in other words it means that object /// at handle's index is different than the object was there before). #[inline] - pub fn try_borrow(&self, handle: Handle) -> Result<&T, PoolError> { + pub fn try_borrow(&self, handle: Handle) -> Result<&T, PoolError> { self.records_get(handle.index).and_then(|r| { if r.generation == handle.generation { - r.payload.as_ref().ok_or(PoolError::Empty(handle)) + r.payload.as_ref().ok_or(PoolError::Empty(handle.into())) } else { Err(PoolError::InvalidGeneration(handle.generation)) } @@ -846,10 +846,10 @@ where /// generation of pool record at handle index (in other words it means that object /// at handle's index is different than the object was there before). #[inline] - pub fn try_borrow_mut(&mut self, handle: Handle) -> Result<&mut T, PoolError> { + pub fn try_borrow_mut(&mut self, handle: Handle) -> Result<&mut T, PoolError> { self.records_get_mut(handle.index).and_then(|r| { if r.generation == handle.generation { - r.payload.as_mut().ok_or(PoolError::Empty(handle)) + r.payload.as_mut().ok_or(PoolError::Empty(handle.into())) } else { Err(PoolError::InvalidGeneration(handle.generation)) } @@ -981,7 +981,7 @@ where &mut self, handle: Handle, func: F, - ) -> (Result<&mut T, PoolError>, Result<&mut T, PoolError>) + ) -> (Result<&mut T, PoolError>, Result<&mut T, PoolError>) where F: FnOnce(&T) -> Handle, { @@ -992,11 +992,11 @@ where if second_handle != handle { return (first, this.try_borrow_mut(second_handle)); } else { - return (first, Err(PoolError::MutablyBorrowed(second_handle))); + return (first, Err(PoolError::MutablyBorrowed(second_handle.into()))); } } - (first, Err(PoolError::UnknownDependentObject(handle))) + (first, Err(PoolError::UnknownDependentObject(handle.into()))) } /// Moves object out of the pool using the given handle. All handles to the object will become invalid. @@ -1006,33 +1006,14 @@ where /// Panics if the given handle is invalid. #[inline] pub fn free(&mut self, handle: Handle) -> T { - let index = usize::try_from(handle.index).expect("index overflowed usize"); - if let Some(record) = self.records.get_mut(index) { - if record.generation == handle.generation { - // Remember this index as free - self.free_stack.push(handle.index); - // Return current payload. - if let Some(payload) = record.payload.take() { - payload - } else { - panic!("Attempt to double free object at handle {handle:?}!"); - } - } else { - panic!( - "Attempt to free object using dangling handle {:?}! Record generation is {}", - handle, record.generation - ); - } - } else { - panic!("Attempt to free destroyed object using out-of-bounds handle {:?}! Record count is {}", handle, self.records.len()); - } + self.try_free(handle).unwrap() } /// Tries to move object out of the pool using the given handle. Returns None if given handle /// is invalid. After object is moved out if the pool, all handles to the object will become /// invalid. #[inline] - pub fn try_free(&mut self, handle: Handle) -> Result> { + pub fn try_free(&mut self, handle: Handle) -> Result { let index = usize::try_from(handle.index).expect("index overflowed usize"); self.records .get_mut(index) @@ -1043,7 +1024,7 @@ where self.free_stack.push(handle.index); Ok(payload) } else { - Err(PoolError::Empty(handle)) + Err(PoolError::Empty(handle.into())) } } else { Err(PoolError::InvalidGeneration(handle.generation)) @@ -1080,7 +1061,7 @@ where /// /// [`take_reserve`]: Pool::take_reserve #[inline] - pub fn try_take_reserve(&mut self, handle: Handle) -> Result<(Ticket, T), PoolError> { + pub fn try_take_reserve(&mut self, handle: Handle) -> Result<(Ticket, T), PoolError> { let record = self.records_get_mut(handle.index)?; if record.generation == handle.generation { if let Some(payload) = record.payload.take() { @@ -1090,7 +1071,7 @@ where }; Ok((ticket, payload)) } else { - Err(PoolError::Empty(handle)) + Err(PoolError::Empty(handle.into())) } } else { Err(PoolError::InvalidGeneration(handle.generation)) @@ -1143,21 +1124,21 @@ where } #[inline] - pub fn at_mut(&mut self, n: u32) -> Result<&mut T, PoolError> { + pub fn at_mut(&mut self, n: u32) -> Result<&mut T, PoolError> { self.records_get_mut(n).and_then(|rec| { rec.payload .as_mut() - .ok_or(PoolError::Empty(Handle::new(n, 0))) + .ok_or(PoolError::Empty(ErasedHandle::new(n, 0))) }) } #[inline] - pub fn at(&self, n: u32) -> Result<&T, PoolError> { + pub fn at(&self, n: u32) -> Result<&T, PoolError> { self.records_get(n).and_then(|rec| { rec.payload .get() .as_ref() - .ok_or(PoolError::Empty(Handle::new(n, 0))) + .ok_or(PoolError::Empty(ErasedHandle::new(n, 0))) }) } @@ -1409,16 +1390,19 @@ where { /// Tries to mutably borrow an object and fetch its component of specified type. #[inline] - pub fn try_get_component_of_type(&self, handle: Handle) -> Result<&C, PoolError> + pub fn try_get_component_of_type(&self, handle: Handle) -> Result<&C, PoolError> where C: 'static, { self.try_borrow(handle) .and_then(|n| { n.query_component_ref(TypeId::of::()) - .ok_or(PoolError::NoSuchComponent(handle)) + .ok_or(PoolError::NoSuchComponent(handle.into())) + }) + .and_then(|c| { + c.downcast_ref() + .ok_or(PoolError::InvalidType(handle.into())) }) - .and_then(|c| c.downcast_ref().ok_or(PoolError::InvalidType(handle))) } /// Tries to mutably borrow an object and fetch its component of specified type. @@ -1426,16 +1410,19 @@ where pub fn try_get_component_of_type_mut( &mut self, handle: Handle, - ) -> Result<&mut C, PoolError> + ) -> Result<&mut C, PoolError> where C: 'static, { self.try_borrow_mut(handle) .and_then(|n| { n.query_component_mut(TypeId::of::()) - .ok_or(PoolError::NoSuchComponent(handle)) + .ok_or(PoolError::NoSuchComponent(handle.into())) + }) + .and_then(|c| { + c.downcast_mut() + .ok_or(PoolError::InvalidType(handle.into())) }) - .and_then(|c| c.downcast_mut().ok_or(PoolError::InvalidType(handle))) } } @@ -1752,7 +1739,7 @@ mod test { let handle = pool.spawn(Payload); assert_eq!(pool.try_free(handle), Ok(Payload)); assert_eq!(pool.free_stack.len(), 1); - assert_eq!(pool.try_free(handle), Err(PoolError::Empty(handle))); + assert_eq!(pool.try_free(handle), Err(PoolError::Empty(handle.into()))); assert_eq!(pool.free_stack.len(), 1); } @@ -1849,7 +1836,7 @@ mod test { assert_eq!( pool.try_borrow_dependant_mut(a, |_| a), - (Ok(&mut 42), Err(PoolError::MutablyBorrowed(a))) + (Ok(&mut 42), Err(PoolError::MutablyBorrowed(a.into()))) ); } diff --git a/fyrox-core/src/pool/multiborrow.rs b/fyrox-core/src/pool/multiborrow.rs index f510f8add..5b357d1d2 100644 --- a/fyrox-core/src/pool/multiborrow.rs +++ b/fyrox-core/src/pool/multiborrow.rs @@ -163,10 +163,10 @@ where &'b self, handle: Handle, func: F, - ) -> Result, PoolError> + ) -> Result, PoolError> where C: ?Sized, - F: FnOnce(&T) -> Result<&C, PoolError>, + F: FnOnce(&T) -> Result<&C, PoolError>, { let record = self.pool.records_get(handle.index)?; @@ -176,14 +176,14 @@ where let current_ref_count = unsafe { record.ref_counter.get() }; if current_ref_count < 0 { - return Err(PoolError::MutablyBorrowed(handle)); + return Err(PoolError::MutablyBorrowed(handle.into())); } // SAFETY: We've enforced borrowing rules by the previous check. let payload_container = unsafe { &*record.payload.0.get() }; let Some(payload) = payload_container.as_ref() else { - return Err(PoolError::Empty(handle)); + return Err(PoolError::Empty(handle.into())); }; unsafe { @@ -206,7 +206,7 @@ where /// in the internal handles storage) - in this case you must increase `N`. /// 3) A given handle is invalid. #[inline] - pub fn try_get<'b: 'a>(&'b self, handle: Handle) -> Result, PoolError> { + pub fn try_get<'b: 'a>(&'b self, handle: Handle) -> Result, PoolError> { self.try_get_internal(handle, |obj| Ok(obj)) } @@ -220,10 +220,10 @@ where &'b self, handle: Handle, func: F, - ) -> Result, PoolError> + ) -> Result, PoolError> where C: ?Sized, - F: FnOnce(&mut T) -> Result<&mut C, PoolError>, + F: FnOnce(&mut T) -> Result<&mut C, PoolError>, { let record = self.pool.records_get(handle.index)?; @@ -236,10 +236,10 @@ where let current_ref_count = unsafe { record.ref_counter.get() }; match current_ref_count.cmp(&0) { Ordering::Less => { - return Err(PoolError::MutablyBorrowed(handle)); + return Err(PoolError::MutablyBorrowed(handle.into())); } Ordering::Greater => { - return Err(PoolError::ImmutablyBorrowed(handle)); + return Err(PoolError::ImmutablyBorrowed(handle.into())); } _ => (), } @@ -248,7 +248,7 @@ where let payload_container = unsafe { &mut *record.payload.0.get() }; let Some(payload) = payload_container.as_mut() else { - return Err(PoolError::Empty(handle)); + return Err(PoolError::Empty(handle.into())); }; // SAFETY: It is safe to access the counter because of borrow checker guarantees that @@ -268,7 +268,7 @@ where pub fn try_get_mut<'b: 'a>( &'b self, handle: Handle, - ) -> Result, PoolError> { + ) -> Result, PoolError> { self.try_get_mut_internal(handle, |obj| Ok(obj)) } @@ -278,7 +278,7 @@ where } #[inline] - pub fn free(&self, handle: Handle) -> Result> { + pub fn free(&self, handle: Handle) -> Result { let record = self.pool.records_get(handle.index)?; if handle.generation != record.generation { @@ -291,10 +291,10 @@ where let current_ref_count = unsafe { record.ref_counter.get() }; match current_ref_count.cmp(&0) { Ordering::Less => { - return Err(PoolError::MutablyBorrowed(handle)); + return Err(PoolError::MutablyBorrowed(handle.into())); } Ordering::Greater => { - return Err(PoolError::ImmutablyBorrowed(handle)); + return Err(PoolError::ImmutablyBorrowed(handle.into())); } _ => (), } @@ -303,7 +303,7 @@ where let payload_container = unsafe { &mut *record.payload.0.get() }; let Some(payload) = payload_container.take() else { - return Err(PoolError::Empty(handle)); + return Err(PoolError::Empty(handle.into())); }; self.free_indices.borrow_mut().push(handle.index); @@ -322,14 +322,14 @@ where pub fn try_get_component_of_type<'b: 'a, C>( &'b self, handle: Handle, - ) -> Result, PoolError> + ) -> Result, PoolError> where C: 'static, { self.try_get_internal(handle, move |obj| { obj.query_component_ref(TypeId::of::()) .and_then(|c| c.downcast_ref()) - .ok_or(PoolError::NoSuchComponent(handle)) + .ok_or(PoolError::NoSuchComponent(handle.into())) }) } @@ -338,14 +338,14 @@ where pub fn try_get_component_of_type_mut<'b: 'a, C>( &'b self, handle: Handle, - ) -> Result, PoolError> + ) -> Result, PoolError> where C: 'static, { self.try_get_mut_internal(handle, move |obj| { obj.query_component_mut(TypeId::of::()) .and_then(|c| c.downcast_mut()) - .ok_or(PoolError::NoSuchComponent(handle)) + .ok_or(PoolError::NoSuchComponent(handle.into())) }) } } @@ -378,10 +378,13 @@ mod test { // Test empty. { - assert_eq!(ctx.try_get(d).as_deref(), Err(PoolError::Empty(d)).as_ref()); + assert_eq!( + ctx.try_get(d).as_deref(), + Err(PoolError::Empty(d.into())).as_ref() + ); assert_eq!( ctx.try_get_mut(d).as_deref_mut(), - Err(PoolError::Empty(d)).as_mut() + Err(PoolError::Empty(d.into())).as_mut() ); } @@ -404,7 +407,7 @@ mod test { assert_eq!(ref_a_2.as_deref(), Ok(&val_a)); assert_eq!( ctx.try_get_mut(a).as_deref(), - Err(PoolError::ImmutablyBorrowed(a)).as_ref() + Err(PoolError::ImmutablyBorrowed(a.into())).as_ref() ); drop(ref_a_1); @@ -433,7 +436,7 @@ mod test { assert_eq!(ref_b_1.as_deref_mut(), Ok(&mut val_b)); assert_eq!( ref_b_2.as_deref_mut(), - Err(PoolError::MutablyBorrowed(b)).as_mut() + Err(PoolError::MutablyBorrowed(b.into())).as_mut() ); let mut ref_c_1 = ctx.try_get_mut(c); @@ -441,7 +444,7 @@ mod test { assert_eq!(ref_c_1.as_deref_mut(), Ok(&mut val_c)); assert_eq!( ref_c_2.as_deref_mut(), - Err(PoolError::MutablyBorrowed(c)).as_mut() + Err(PoolError::MutablyBorrowed(c.into())).as_mut() ); } } diff --git a/fyrox-core/src/visitor/mod.rs b/fyrox-core/src/visitor/mod.rs index 5bb888fae..6f6de9249 100644 --- a/fyrox-core/src/visitor/mod.rs +++ b/fyrox-core/src/visitor/mod.rs @@ -697,7 +697,7 @@ impl Visitor { /// The name of the current region. This should never be None if the Visitor is operating normally, /// because there should be no way to leave the initial `__ROOT__` region. - pub fn current_region(&self) -> Result<&str, PoolError> { + pub fn current_region(&self) -> Result<&str, PoolError> { self.nodes .try_borrow(self.current_node) .map(|n| n.name.as_str()) diff --git a/fyrox-graph/src/lib.rs b/fyrox-graph/src/lib.rs index d6818a747..d8f58908b 100644 --- a/fyrox-graph/src/lib.rs +++ b/fyrox-graph/src/lib.rs @@ -29,7 +29,7 @@ pub mod prelude { } use fxhash::FxHashMap; -use fyrox_core::pool::{ErasedHandle, ObjectOrVariant, PayloadContainer}; +use fyrox_core::pool::{ErasedHandle, ObjectOrVariant, PayloadContainer, PoolError}; use fyrox_core::reflect::ReflectHandle; use fyrox_core::{ log::{Log, MessageKind}, @@ -679,11 +679,14 @@ impl Default for LinkScheme { } pub trait AbstractSceneGraph: 'static { - fn try_get_node_untyped(&self, handle: ErasedHandle) -> Option<&dyn AbstractSceneNode>; + fn try_get_node_untyped( + &self, + handle: ErasedHandle, + ) -> Result<&dyn AbstractSceneNode, PoolError>; fn try_get_node_untyped_mut( &mut self, handle: ErasedHandle, - ) -> Option<&mut dyn AbstractSceneNode>; + ) -> Result<&mut dyn AbstractSceneNode, PoolError>; } /// BaseSceneGraph is a dyn-compatible trait for all scene graphs to implement. @@ -698,13 +701,13 @@ pub trait BaseSceneGraph: AbstractSceneGraph { fn summary(&self) -> String; /// Returns actual type id of the node. - fn actual_type_id(&self, handle: Handle) -> Option; + fn actual_type_id(&self, handle: Handle) -> Result; /// Returns actual type name of the node. - fn actual_type_name(&self, handle: Handle) -> Option<&'static str>; + fn actual_type_name(&self, handle: Handle) -> Result<&'static str, PoolError>; /// Returns a list of derived type ids of the node. - fn derived_type_ids(&self, handle: Handle) -> Option>; + fn derived_type_ids(&self, handle: Handle) -> Result, PoolError>; /// Returns a handle of the root node of the graph. fn root(&self) -> Handle; @@ -713,10 +716,13 @@ pub trait BaseSceneGraph: AbstractSceneGraph { fn set_root(&mut self, root: Handle); /// Tries to borrow a node, returns Some(node) if the handle is valid, None - otherwise. - fn try_get_node(&self, handle: Handle) -> Option<&Self::Node>; + fn try_get_node(&self, handle: Handle) -> Result<&Self::Node, PoolError>; /// Tries to borrow a node, returns Some(node) if the handle is valid, None - otherwise. - fn try_get_node_mut(&mut self, handle: Handle) -> Option<&mut Self::Node>; + fn try_get_node_mut( + &mut self, + handle: Handle, + ) -> Result<&mut Self::Node, PoolError>; /// Checks whether the given node handle is valid or not. fn is_valid_handle(&self, handle: Handle) -> bool; @@ -854,33 +860,48 @@ pub trait SceneGraph: BaseSceneGraph { /// of nodes. It does *not* perform any tree traversal! fn linear_iter_mut(&mut self) -> impl Iterator; - fn try_get>(&self, handle: Handle) -> Option<&U>; + fn try_get>( + &self, + handle: Handle, + ) -> Result<&U, PoolError>; fn try_get_mut>( &mut self, handle: Handle, - ) -> Option<&mut U>; + ) -> Result<&mut U, PoolError>; /// Tries to borrow a node and fetch its component of specified type. #[inline] - fn try_get_of_type(&self, handle: Handle) -> Option<&T> + fn try_get_of_type(&self, handle: Handle) -> Result<&T, PoolError> where T: 'static, { self.try_get_node(handle) - .and_then(|n| n.query_component_ref(TypeId::of::())) - .and_then(|c| c.downcast_ref()) + .and_then(|n| { + n.query_component_ref(TypeId::of::()) + .ok_or(PoolError::NoSuchComponent(handle.into())) + }) + .and_then(|c| { + c.downcast_ref() + .ok_or(PoolError::InvalidType(handle.into())) + }) } /// Tries to mutably borrow a node and fetch its component of specified type. #[inline] - fn try_get_mut_of_type(&mut self, handle: Handle) -> Option<&mut T> + fn try_get_mut_of_type(&mut self, handle: Handle) -> Result<&mut T, PoolError> where T: 'static, { self.try_get_node_mut(handle) - .and_then(|n| n.query_component_mut(TypeId::of::())) - .and_then(|c| c.downcast_mut()) + .and_then(|n| { + n.query_component_mut(TypeId::of::()) + .ok_or(PoolError::NoSuchComponent(handle.into())) + }) + .and_then(|c| { + c.downcast_mut() + .ok_or(PoolError::InvalidType(handle.into())) + }) } /// Tries to borrow a node by the given handle and checks if it has a component of the specified @@ -890,7 +911,7 @@ pub trait SceneGraph: BaseSceneGraph { where T: 'static, { - self.try_get_of_type::(handle).is_some() + self.try_get_of_type::(handle).is_ok() } /// Searches for a node down the tree starting from the specified node using the specified closure. Returns a tuple @@ -905,7 +926,7 @@ pub trait SceneGraph: BaseSceneGraph { C: FnMut(&Self::Node) -> Option<&T>, T: ?Sized, { - self.try_get_node(root_node).and_then(|root| { + self.try_get_node(root_node).ok().and_then(|root| { if let Some(x) = cmp(root) { Some((root_node, x)) } else { @@ -926,7 +947,7 @@ pub trait SceneGraph: BaseSceneGraph { C: FnMut(&Self::Node) -> bool, { let mut handle = root_node; - while let Some(node) = self.try_get_node(handle) { + while let Ok(node) = self.try_get_node(handle) { if cmp(node) { return Some((handle, node)); } @@ -985,7 +1006,7 @@ pub trait SceneGraph: BaseSceneGraph { T: ?Sized, { let mut handle = root_node; - while let Some(node) = self.try_get_node(handle) { + while let Ok(node) = self.try_get_node(handle) { if let Some(x) = cmp(node) { return Some((handle, x)); } @@ -1052,7 +1073,7 @@ pub trait SceneGraph: BaseSceneGraph { where C: FnMut(&Self::Node) -> bool, { - self.try_get_node(root_node).and_then(|root| { + self.try_get_node(root_node).ok().and_then(|root| { if cmp(root) { Some((root_node, root)) } else { @@ -1091,8 +1112,8 @@ pub trait SceneGraph: BaseSceneGraph { child: Handle, offset: isize, ) -> Option<(Handle, usize)> { - let parents_parent_handle = self.try_get_node(child)?.parent(); - let parents_parent_ref = self.try_get_node(parents_parent_handle)?; + let parents_parent_handle = self.try_get_node(child).ok()?.parent(); + let parents_parent_ref = self.try_get_node(parents_parent_handle).ok()?; let position = parents_parent_ref.child_position(child)?; Some(( parents_parent_handle, @@ -1320,6 +1341,7 @@ pub trait SceneGraph: BaseSceneGraph { .map(|resource_node| { (resource_node, node.original_handle_in_resource()) }) + .ok() } }; @@ -1464,7 +1486,7 @@ mod test { AbstractSceneGraph, AbstractSceneNode, BaseSceneGraph, NodeHandleMap, NodeMapping, PrefabData, SceneGraph, SceneGraphNode, }; - use fyrox_core::pool::{ObjectOrVariant, ObjectOrVariantHelper}; + use fyrox_core::pool::{ObjectOrVariant, ObjectOrVariantHelper, PoolError}; use fyrox_core::{ define_as_any_trait, pool::{ErasedHandle, Handle, PayloadContainer, Pool}, @@ -1795,7 +1817,10 @@ mod test { } impl AbstractSceneGraph for Graph { - fn try_get_node_untyped(&self, handle: ErasedHandle) -> Option<&dyn AbstractSceneNode> { + fn try_get_node_untyped( + &self, + handle: ErasedHandle, + ) -> Result<&dyn AbstractSceneNode, PoolError> { self.nodes .try_borrow(handle.into()) .map(|n| n as &dyn AbstractSceneNode) @@ -1804,7 +1829,7 @@ mod test { fn try_get_node_untyped_mut( &mut self, handle: ErasedHandle, - ) -> Option<&mut dyn AbstractSceneNode> { + ) -> Result<&mut dyn AbstractSceneNode, PoolError> { self.nodes .try_borrow_mut(handle.into()) .map(|n| n as &mut dyn AbstractSceneNode) @@ -1876,34 +1901,37 @@ mod test { let parent_handle = std::mem::replace(&mut self.nodes[node_handle].parent, Handle::NONE); - if let Some(parent) = self.nodes.try_borrow_mut(parent_handle) { + if let Ok(parent) = self.nodes.try_borrow_mut(parent_handle) { if let Some(i) = parent.children().iter().position(|h| *h == node_handle) { parent.children.remove(i); } } } - fn try_get_node(&self, handle: Handle) -> Option<&Self::Node> { + fn try_get_node(&self, handle: Handle) -> Result<&Self::Node, PoolError> { self.nodes.try_borrow(handle) } - fn try_get_node_mut(&mut self, handle: Handle) -> Option<&mut Self::Node> { + fn try_get_node_mut( + &mut self, + handle: Handle, + ) -> Result<&mut Self::Node, PoolError> { self.nodes.try_borrow_mut(handle) } - fn actual_type_id(&self, handle: Handle) -> Option { + fn actual_type_id(&self, handle: Handle) -> Result { self.nodes .try_borrow(handle) .map(|n| NodeAsAny::as_any(n.0.deref()).type_id()) } - fn derived_type_ids(&self, handle: Handle) -> Option> { + fn derived_type_ids(&self, handle: Handle) -> Result, PoolError> { self.nodes .try_borrow(handle) .map(|n| n.0.deref().query_derived_types().to_vec()) } - fn actual_type_name(&self, handle: Handle) -> Option<&'static str> { + fn actual_type_name(&self, handle: Handle) -> Result<&'static str, PoolError> { self.nodes .try_borrow(handle) .map(|n| n.0.deref().type_name()) @@ -1924,11 +1952,14 @@ mod test { self.nodes.iter_mut() } - fn try_get>(&self, handle: Handle) -> Option<&U> { + fn try_get>(&self, handle: Handle) -> Result<&U, PoolError> { self.nodes.try_get(handle) } - fn try_get_mut>(&mut self, handle: Handle) -> Option<&mut U> { + fn try_get_mut>( + &mut self, + handle: Handle, + ) -> Result<&mut U, PoolError> { self.nodes.try_get_mut(handle) } } diff --git a/fyrox-impl/src/engine/hotreload.rs b/fyrox-impl/src/engine/hotreload.rs index a2b0efe0e..2e96cae8d 100644 --- a/fyrox-impl/src/engine/hotreload.rs +++ b/fyrox-impl/src/engine/hotreload.rs @@ -75,7 +75,7 @@ impl SceneState { for index in 0..scene.graph.capacity() { let handle = scene.graph.handle_from_index(index); - let Some(node) = scene.graph.try_get_node_mut(handle) else { + let Ok(node) = scene.graph.try_get_node_mut(handle) else { continue; }; diff --git a/fyrox-impl/src/engine/mod.rs b/fyrox-impl/src/engine/mod.rs index e629ef681..9359f6561 100644 --- a/fyrox-impl/src/engine/mod.rs +++ b/fyrox-impl/src/engine/mod.rs @@ -642,7 +642,7 @@ impl ScriptMessageDispatcher { ScriptMessageKind::Hierarchical { root, routing } => match routing { RoutingStrategy::Up => { let mut node = root; - while let Some(node_ref) = scene.graph.try_get_node(node) { + while let Ok(node_ref) = scene.graph.try_get_node(node) { let parent = node_ref.parent(); let mut context = ScriptMessageContext { @@ -1188,7 +1188,7 @@ where T: FnMut(&mut Script, &mut C), C: UniversalScriptContext, { - let Some(node) = context.node() else { + let Ok(node) = context.node() else { // A node was destroyed. return false; }; @@ -1209,7 +1209,7 @@ where func(&mut script, context); match context.node() { - Some(node) => { + Ok(node) => { let entry = node .scripts .get_mut(index) @@ -1222,7 +1222,7 @@ where entry.script = Some(script); } } - None => { + Err(_) => { // If the node was deleted by the `func` call, we must send the script to destruction // queue, not silently drop it. context.destroy_script_deferred(script, index); @@ -2032,8 +2032,8 @@ impl Engine { .find(|e| e.handle == node_task_handler.scene_handle) { let payload = result.payload; - if let Some(scene) = self.scenes.try_get_mut(node_task_handler.scene_handle) { - if let Some(node) = + if let Ok(scene) = self.scenes.try_get_mut(node_task_handler.scene_handle) { + if let Ok(node) = scene.graph.try_get_node_mut(node_task_handler.node_handle) { if let Some(mut script) = node @@ -2062,7 +2062,7 @@ impl Engine { }, ); - if let Some(node) = + if let Ok(node) = scene.graph.try_get_node_mut(node_task_handler.node_handle) { if let Some(entry) = @@ -2129,6 +2129,7 @@ impl Engine { while let Some(message) = self .user_interfaces .try_get_mut(ui) + .ok() .and_then(|ui| ui.poll_message()) { let mut context = PluginContext { diff --git a/fyrox-impl/src/renderer/bundle.rs b/fyrox-impl/src/renderer/bundle.rs index 18787f2ef..2009d2673 100644 --- a/fyrox-impl/src/renderer/bundle.rs +++ b/fyrox-impl/src/renderer/bundle.rs @@ -897,7 +897,7 @@ impl RenderDataBundleStorage { if let Some(lod_group) = node.lod_group() { for level in lod_group.levels.iter() { for &object in level.objects.iter() { - if let Some(object_ref) = graph.try_get_node(object) { + if let Ok(object_ref) = graph.try_get_node(object) { let distance = observer_position .translation .metric_distance(&object_ref.global_position()); diff --git a/fyrox-impl/src/renderer/occlusion/mod.rs b/fyrox-impl/src/renderer/occlusion/mod.rs index 6e8f45b0d..59c485e33 100644 --- a/fyrox-impl/src/renderer/occlusion/mod.rs +++ b/fyrox-impl/src/renderer/occlusion/mod.rs @@ -115,6 +115,7 @@ impl TileBuffer { fn inflated_world_aabb(graph: &Graph, object: Handle) -> Option { let mut aabb = graph .try_get_node(object) + .ok() .map(|node_ref| node_ref.world_bounding_box())?; aabb.inflate(Vector3::repeat(0.01)); Some(aabb) @@ -228,7 +229,7 @@ impl OcclusionTester { let mut lines = Vec::new(); for (object_index, object) in self.objects_to_test.iter().enumerate() { let object_index = object_index as u32; - let Some(node_ref) = graph.try_get_node(*object) else { + let Ok(node_ref) = graph.try_get_node(*object) else { continue; }; diff --git a/fyrox-impl/src/renderer/visibility.rs b/fyrox-impl/src/renderer/visibility.rs index f3e7f3e40..bdab8e2a3 100644 --- a/fyrox-impl/src/renderer/visibility.rs +++ b/fyrox-impl/src/renderer/visibility.rs @@ -282,7 +282,7 @@ impl VisibilityCache { /// Updates the cache by removing unused data. pub fn update(&mut self, graph: &Graph) { self.observers.retain(|observer, data| { - let Some(observer_ref) = graph.try_get_node(*observer) else { + let Ok(observer_ref) = graph.try_get_node(*observer) else { return false; }; diff --git a/fyrox-impl/src/resource/fbx/scene/texture.rs b/fyrox-impl/src/resource/fbx/scene/texture.rs index d196a3fb1..e371739bf 100644 --- a/fyrox-impl/src/resource/fbx/scene/texture.rs +++ b/fyrox-impl/src/resource/fbx/scene/texture.rs @@ -66,6 +66,7 @@ impl FbxTexture { if self.filename == PathBuf::default() { components .try_borrow(self.ancestor) + .ok() .and_then(|parent| parent.as_texture().ok()) .map(|texture| texture.get_root_file_path(components)) .unwrap_or_default() diff --git a/fyrox-impl/src/resource/gltf/animation.rs b/fyrox-impl/src/resource/gltf/animation.rs index f56935ef7..f7699730d 100644 --- a/fyrox-impl/src/resource/gltf/animation.rs +++ b/fyrox-impl/src/resource/gltf/animation.rs @@ -111,7 +111,7 @@ impl ImportedTarget { self.binding.value_binding() } fn value_in_graph(&self, graph: &Graph) -> Option> { - let node: &Node = graph.try_get_node(self.handle)?; + let node: &Node = graph.try_get_node(self.handle).ok()?; match self.binding { ImportedBinding::Position => { Some(node.local_transform().position().data.as_slice().into()) diff --git a/fyrox-impl/src/resource/gltf/node_names.rs b/fyrox-impl/src/resource/gltf/node_names.rs index b7fe381a4..012f12bb3 100644 --- a/fyrox-impl/src/resource/gltf/node_names.rs +++ b/fyrox-impl/src/resource/gltf/node_names.rs @@ -170,13 +170,13 @@ fn get_ancestor_names<'a>( fn get_ancestor_name(mut handle: Handle, depth: usize, graph: &Graph) -> Option<&str> { for _ in 0..depth { - if let Some(n) = graph.try_get_node(handle) { + if let Ok(n) = graph.try_get_node(handle) { handle = n.parent(); } else { return None; } } - graph.try_get_node(handle).map(Node::name) + graph.try_get_node(handle).ok().map(Node::name) } fn contains_duplicate_name(names: &[&str]) -> bool { @@ -192,7 +192,7 @@ fn contains_duplicate_name(names: &[&str]) -> bool { fn count_ancestor_depth(mut handle: Handle, list: &[Handle], graph: &Graph) -> usize { let mut count: usize = 0; - while let Some(node) = graph.try_get_node(handle) { + while let Ok(node) = graph.try_get_node(handle) { handle = node.parent(); if list.contains(&handle) { count += 1; diff --git a/fyrox-impl/src/scene/animation/absm.rs b/fyrox-impl/src/scene/animation/absm.rs index 0ba4b6ad6..125768544 100644 --- a/fyrox-impl/src/scene/animation/absm.rs +++ b/fyrox-impl/src/scene/animation/absm.rs @@ -41,7 +41,7 @@ use crate::{ }, }; use fyrox_graph::constructor::ConstructorProvider; -use fyrox_graph::{BaseSceneGraph, SceneGraph, SceneGraphNode}; +use fyrox_graph::{BaseSceneGraph, SceneGraph}; use std::ops::{Deref, DerefMut}; /// Scene specific root motion settings. @@ -312,10 +312,9 @@ impl NodeTrait for AnimationBlendingStateMachine { } fn update(&mut self, context: &mut UpdateContext) { - if let Some(animation_player) = context + if let Ok(animation_player) = context .nodes - .try_borrow_mut(*self.animation_player) - .and_then(|n| n.component_mut::()) + .try_get_component_of_type_mut::(*self.animation_player) { // Prevent animation player to apply animation to scene nodes. The animation will // do than instead. @@ -333,9 +332,8 @@ impl NodeTrait for AnimationBlendingStateMachine { fn validate(&self, scene: &Scene) -> Result<(), String> { if scene .graph - .try_get_node(*self.animation_player) - .and_then(|n| n.component_ref::()) - .is_none() + .try_get_of_type::(*self.animation_player) + .is_err() { Err( "Animation player is not set or invalid! Animation blending state \ diff --git a/fyrox-impl/src/scene/animation/mod.rs b/fyrox-impl/src/scene/animation/mod.rs index 64c70342e..b9d9d6af2 100644 --- a/fyrox-impl/src/scene/animation/mod.rs +++ b/fyrox-impl/src/scene/animation/mod.rs @@ -109,7 +109,7 @@ impl AnimationPoseExt for AnimationPose { for (node, local_pose) in self.poses() { if node.is_none() { Log::writeln(MessageKind::Error, "Invalid node handle found for animation pose, most likely it means that animation retargeting failed!"); - } else if let Some(node) = nodes.try_borrow_mut(*node) { + } else if let Ok(node) = nodes.try_borrow_mut(*node) { local_pose.values.apply(node); } } @@ -119,7 +119,7 @@ impl AnimationPoseExt for AnimationPose { for (node, local_pose) in self.poses() { if node.is_none() { Log::writeln(MessageKind::Error, "Invalid node handle found for animation pose, most likely it means that animation retargeting failed!"); - } else if let Some(node) = graph.try_get_node_mut(*node) { + } else if let Ok(node) = graph.try_get_node_mut(*node) { local_pose.values.apply(node); } } @@ -132,7 +132,7 @@ impl AnimationPoseExt for AnimationPose { for (node, local_pose) in self.poses() { if node.is_none() { Log::writeln(MessageKind::Error, "Invalid node handle found for animation pose, most likely it means that animation retargeting failed!"); - } else if let Some(node_ref) = graph.try_get_node_mut(*node) { + } else if let Ok(node_ref) = graph.try_get_node_mut(*node) { callback(node_ref, *node, local_pose); } } diff --git a/fyrox-impl/src/scene/base.rs b/fyrox-impl/src/scene/base.rs index 059d64c1a..65f3e39ef 100644 --- a/fyrox-impl/src/scene/base.rs +++ b/fyrox-impl/src/scene/base.rs @@ -1181,7 +1181,7 @@ impl Base { if let Some(resource) = self.resource.as_ref() { let mut state = resource.state(); if let Some(model) = state.data() { - if let Some(ancestor_node) = model + if let Ok(ancestor_node) = model .get_scene() .graph .try_get_node(self.original_handle_in_resource) diff --git a/fyrox-impl/src/scene/collider.rs b/fyrox-impl/src/scene/collider.rs index 12fa871a5..9aee5c34c 100644 --- a/fyrox-impl/src/scene/collider.rs +++ b/fyrox-impl/src/scene/collider.rs @@ -50,7 +50,7 @@ use fyrox_core::algebra::{Isometry3, Translation3}; use fyrox_core::uuid_provider; use fyrox_graph::constructor::ConstructorProvider; -use fyrox_graph::{BaseSceneGraph, SceneGraphNode}; +use fyrox_graph::{BaseSceneGraph, SceneGraph}; use rapier3d::geometry::{self, ColliderHandle}; use std::fmt::Write; use std::{ @@ -1044,9 +1044,8 @@ impl NodeTrait for Collider { if scene .graph - .try_get_node(self.parent()) - .and_then(|p| p.component_ref::()) - .is_none() + .try_get_of_type::(self.parent()) + .is_err() { message += "3D Collider must be a direct child of a 3D Rigid Body node, \ otherwise it will not have any effect!"; diff --git a/fyrox-impl/src/scene/dim2/collider.rs b/fyrox-impl/src/scene/dim2/collider.rs index 685310c67..7e7302cfb 100644 --- a/fyrox-impl/src/scene/dim2/collider.rs +++ b/fyrox-impl/src/scene/dim2/collider.rs @@ -36,7 +36,7 @@ use crate::{ visitor::prelude::*, ImmutableString, TypeUuidProvider, }, - graph::{BaseSceneGraph, SceneGraphNode}, + graph::BaseSceneGraph, scene::{ base::{Base, BaseBuilder}, collider::InteractionGroups, @@ -51,6 +51,7 @@ use crate::{ }; use fyrox_graph::constructor::ConstructorProvider; +use fyrox_graph::SceneGraph; use rapier2d::geometry::ColliderHandle; use std::{ cell::Cell, @@ -703,9 +704,8 @@ impl NodeTrait for Collider { if scene .graph - .try_get_node(self.parent()) - .and_then(|p| p.component_ref::()) - .is_none() + .try_get_of_type::(self.parent()) + .is_err() { message += "2D Collider must be a direct child of a 3D Rigid Body node, \ otherwise it will not have any effect!"; diff --git a/fyrox-impl/src/scene/dim2/joint.rs b/fyrox-impl/src/scene/dim2/joint.rs index 996981bc0..a82b59be0 100644 --- a/fyrox-impl/src/scene/dim2/joint.rs +++ b/fyrox-impl/src/scene/dim2/joint.rs @@ -588,13 +588,13 @@ impl NodeTrait for Joint { } fn validate(&self, scene: &Scene) -> Result<(), String> { - if scene.graph.try_get(self.body1()).is_none() { + if scene.graph.try_get(self.body1()).is_err() { return Err("2D Joint has invalid or unassigned handle to a \ first body, the joint will not operate!" .to_string()); } - if scene.graph.try_get(self.body2()).is_none() { + if scene.graph.try_get(self.body2()).is_err() { return Err("2D Joint has invalid or unassigned handle to a \ second body, the joint will not operate!" .to_string()); diff --git a/fyrox-impl/src/scene/dim2/physics.rs b/fyrox-impl/src/scene/dim2/physics.rs index 028b59cd0..3dea58db5 100644 --- a/fyrox-impl/src/scene/dim2/physics.rs +++ b/fyrox-impl/src/scene/dim2/physics.rs @@ -58,6 +58,7 @@ use crate::{ tilemap::TileMap, }, }; +use fyrox_graph::SceneGraph; pub use rapier2d::geometry::shape::*; use rapier2d::parry::query::DefaultQueryDispatcher; use rapier2d::{ @@ -361,7 +362,10 @@ fn tile_map_to_collider_shape( nodes: &NodePool, collider_name: &ImmutableString, ) -> Option { - let tile_map = nodes.try_borrow(tile_map.0)?.component_ref::()?; + let tile_map = nodes + .try_borrow(tile_map.0) + .ok()? + .component_ref::()?; let tile_set_resource = tile_map.tile_set()?.data_ref(); let tile_set = tile_set_resource.as_loaded_ref()?; @@ -847,13 +851,11 @@ impl PhysicsWorld { }), exclude_collider: filter .exclude_collider - .and_then(|h| graph.try_get_node(h)) - .and_then(|n| n.component_ref::()) + .and_then(|h| graph.try_get_of_type::(h).ok()) .map(|c| c.native.get()), exclude_rigid_body: filter .exclude_collider - .and_then(|h| graph.try_get_node(h)) - .and_then(|n| n.component_ref::()) + .and_then(|h| graph.try_get_of_type::(h).ok()) .map(|c| c.native.get()), predicate: Some(&predicate), }; @@ -1163,9 +1165,8 @@ impl PhysicsWorld { } } } - } else if let Some(parent_body) = nodes - .try_borrow(collider_node.parent()) - .and_then(|n| n.cast::()) + } else if let Ok(parent_body) = + nodes.try_get_component_of_type::(collider_node.parent()) { if parent_body.native.get() != RigidBodyHandle::invalid() { let rigid_body_native = parent_body.native.get(); @@ -1235,12 +1236,12 @@ impl PhysicsWorld { if let Some(native) = self.joints.set.get_mut(joint.native.get(), false) { joint.body1.try_sync_model(|v| { - if let Some(rigid_body_node) = nodes.try_get(v) { + if let Ok(rigid_body_node) = nodes.try_get(v) { native.body1 = rigid_body_node.native.get(); } }); joint.body2.try_sync_model(|v| { - if let Some(rigid_body_node) = nodes.try_get(v) { + if let Ok(rigid_body_node) = nodes.try_get(v) { native.body2 = rigid_body_node.native.get(); } }); @@ -1288,7 +1289,7 @@ impl PhysicsWorld { }); let mut local_frames = joint.local_frames.borrow_mut(); if local_frames.is_none() { - if let (Some(body1), Some(body2)) = + if let (Ok(body1), Ok(body2)) = (nodes.try_get(joint.body1()), nodes.try_get(joint.body2())) { let (local_frame1, local_frame2) = calculate_local_frames(joint, body1, body2); @@ -1303,7 +1304,7 @@ impl PhysicsWorld { let params = joint.params().clone(); // A native joint can be created iff both rigid bodies are correctly assigned. - if let (Some(body1), Some(body2)) = + if let (Ok(body1), Ok(body2)) = (nodes.try_get(body1_handle), nodes.try_get(body2_handle)) { let native_body1 = body1.native.get(); diff --git a/fyrox-impl/src/scene/dim2/rigidbody.rs b/fyrox-impl/src/scene/dim2/rigidbody.rs index 51faa9082..e801be25a 100644 --- a/fyrox-impl/src/scene/dim2/rigidbody.rs +++ b/fyrox-impl/src/scene/dim2/rigidbody.rs @@ -511,6 +511,7 @@ impl NodeTrait for RigidBody { context .nodes .try_borrow(self.parent) + .ok() .map(|p| p.global_transform()) .unwrap_or_else(Matrix4::identity), ); @@ -518,7 +519,7 @@ impl NodeTrait for RigidBody { fn validate(&self, scene: &Scene) -> Result<(), String> { for &child in self.children() { - if scene.graph.try_get_of_type::(child).is_some() { + if scene.graph.try_get_of_type::(child).is_ok() { return Ok(()); } } diff --git a/fyrox-impl/src/scene/graph/mod.rs b/fyrox-impl/src/scene/graph/mod.rs index d5e295281..71b118704 100644 --- a/fyrox-impl/src/scene/graph/mod.rs +++ b/fyrox-impl/src/scene/graph/mod.rs @@ -76,9 +76,9 @@ use crate::{ }; use bitflags::bitflags; use fxhash::{FxHashMap, FxHashSet}; -use fyrox_core::pool::ObjectOrVariant; +use fyrox_core::pool::{ObjectOrVariant, PoolError}; use fyrox_graph::SceneGraphNode; -use std::fmt::Write; +use std::fmt::{Display, Formatter, Write}; use std::ops::Deref; use std::{ any::{Any, TypeId}, @@ -319,6 +319,63 @@ impl Default for GraphUpdateSwitches { } } +#[derive(PartialEq)] +pub enum GraphError { + PoolError(PoolError), + NoScript { + handle: Handle, + script_type_name: &'static str, + }, + NoScriptComponent { + handle: Handle, + component_type_name: &'static str, + }, + UnknownId(SceneNodeId), +} + +impl Display for GraphError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + GraphError::PoolError(err) => std::fmt::Display::fmt(&err, f), + GraphError::NoScript { + handle, + script_type_name, + } => { + write!( + f, + "There's no script {script_type_name} on the scene node {handle}" + ) + } + GraphError::NoScriptComponent { + handle, + component_type_name, + } => { + write!( + f, + "There's no script component {component_type_name} on the scene node {handle}" + ) + } + GraphError::UnknownId(id) => { + write!(f, "There's no scene node with {id:?} id!") + } + } + } +} + +impl Debug for GraphError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self) + } +} + +impl std::error::Error for GraphError {} + +impl From for GraphError { + fn from(value: PoolError) -> Self { + Self::PoolError(value) + } +} + impl Graph { /// Creates new graph instance with single root node. #[inline] @@ -412,7 +469,7 @@ impl Graph { for _ in 0..indent { result.push_str(" "); } - let Some(node) = self.try_get(current) else { + let Ok(node) = self.try_get(current) else { use std::fmt::Write; writeln!(result, "{}: Failed to get", current).unwrap(); return; @@ -481,8 +538,8 @@ impl Graph { let (node, parent) = self .pool .try_borrow_dependant_mut(node_handle, |node| node.parent()); - if let Some(node) = node { - if let Some(parent) = parent { + if let Ok(node) = node { + if let Ok(parent) = parent { let relative_position = parent .global_transform() .try_inverse() @@ -514,8 +571,8 @@ impl Graph { let (node, parent) = self .pool .try_borrow_dependant_mut(node, |node| node.parent()); - if let Some(node) = node { - if let Some(parent) = parent { + if let Ok(node) = node { + if let Ok(parent) = parent { let basis = parent .global_transform() .try_inverse() @@ -989,7 +1046,7 @@ impl Graph { where F: FnMut(Handle, &Node) -> bool, { - graph.try_get_node(node).and_then(|n| { + graph.try_get_node(node).ok().and_then(|n| { if filter(node, n) { let mut aabb = n.local_bounding_box(); if aabb.is_invalid_or_degenerate() { @@ -1014,12 +1071,13 @@ impl Graph { } pub(crate) fn update_enabled_flag_recursively(nodes: &NodePool, node_handle: Handle) { - let Some(node) = nodes.try_borrow(node_handle) else { + let Ok(node) = nodes.try_borrow(node_handle) else { return; }; let parent_enabled = nodes .try_borrow(node.parent()) + .ok() .is_none_or(|p| p.is_globally_enabled()); node.global_enabled.set(parent_enabled && node.is_enabled()); @@ -1029,12 +1087,13 @@ impl Graph { } pub(crate) fn update_visibility_recursively(nodes: &NodePool, node_handle: Handle) { - let Some(node) = nodes.try_borrow(node_handle) else { + let Ok(node) = nodes.try_borrow(node_handle) else { return; }; let parent_visibility = nodes .try_borrow(node.parent()) + .ok() .is_none_or(|p| p.global_visibility()); node.global_visibility .set(parent_visibility && node.visibility()); @@ -1051,11 +1110,11 @@ impl Graph { physics2d: &mut dim2::physics::PhysicsWorld, node_handle: Handle, ) { - let Some(node) = nodes.try_borrow(node_handle) else { + let Ok(node) = nodes.try_borrow(node_handle) else { return; }; - let parent_global_transform = if let Some(parent) = nodes.try_borrow(node.parent()) { + let parent_global_transform = if let Ok(parent) = nodes.try_borrow(node.parent()) { parent.global_transform() } else { Matrix4::identity() @@ -1161,7 +1220,7 @@ impl Graph { while let Ok(message) = self.message_receiver.try_recv() { if let NodeMessageKind::TransformChanged = message.kind { - if let Some(node) = self.pool.try_borrow(message.node) { + if let Ok(node) = self.pool.try_borrow(message.node) { node.on_local_transform_changed(&mut SyncContext { nodes: &self.pool, physics: &mut self.physics, @@ -1199,7 +1258,7 @@ impl Graph { func: &mut impl FnMut(Handle), ) { func(from); - if let Some(node) = graph.try_get_node(from) { + if let Ok(node) = graph.try_get_node(from) { for &child in node.children() { traverse_recursive(graph, child, func) } @@ -1264,7 +1323,7 @@ impl Graph { dt: f32, delete_dead_nodes: bool, ) { - if let Some((ticket, mut node)) = self.pool.try_take_reserve(handle) { + if let Ok((ticket, mut node)) = self.pool.try_take_reserve(handle) { let mut is_alive = node.is_alive(); if node.is_globally_enabled() { @@ -1650,7 +1709,7 @@ impl Graph { #[inline] pub fn global_scale(&self, mut node: Handle) -> Vector3 { let mut global_scale = Vector3::repeat(1.0); - while let Some(node_ref) = self.try_get_node(node) { + while let Ok(node_ref) = self.try_get_node(node) { global_scale = global_scale.component_mul(node_ref.local_transform().scale()); node = node_ref.parent; } @@ -1660,12 +1719,16 @@ impl Graph { /// Tries to borrow a node using the given handle and searches the script buffer for a script /// of type T and cast the first script, that could be found to the specified type. #[inline] - pub fn try_get_script_of(&self, node: Handle) -> Option<&T> + pub fn try_get_script_of(&self, handle: Handle) -> Result<&T, GraphError> where T: ScriptTrait, { - self.try_get_node(node) - .and_then(|node| node.try_get_script::()) + let node = self.try_get_node(handle)?; + node.try_get_script::() + .ok_or_else(|| GraphError::NoScript { + handle, + script_type_name: std::any::type_name::(), + }) } /// Tries to borrow a node and query all scripts of the given type `T`. This method returns @@ -1674,55 +1737,75 @@ impl Graph { #[inline] pub fn try_get_scripts_of( &self, - node: Handle, - ) -> Option> { - self.try_get_node(node).map(|n| n.try_get_scripts()) + handle: Handle, + ) -> Result, GraphError> { + let node = self.try_get_node(handle)?; + Ok(node.try_get_scripts()) } /// Tries to borrow a node using the given handle and searches the script buffer for a script /// of type T and cast the first script, that could be found to the specified type. #[inline] - pub fn try_get_script_of_mut(&mut self, node: Handle) -> Option<&mut T> + pub fn try_get_script_of_mut(&mut self, handle: Handle) -> Result<&mut T, GraphError> where T: ScriptTrait, { - self.try_get_node_mut(node) - .and_then(|node| node.try_get_script_mut::()) + let node = self.try_get_node_mut(handle)?; + node.try_get_script_mut::() + .ok_or_else(|| GraphError::NoScript { + handle, + script_type_name: std::any::type_name::(), + }) } /// Tries to borrow a node and query all scripts of the given type `T`. This method returns /// [`None`] if the given node handle is invalid, otherwise it returns an iterator over the /// scripts of the type `T`. #[inline] - pub fn try_get_scripts_of_mut( + pub fn try_get_scripts_of_mut( &mut self, - node: Handle, - ) -> Option> { - self.try_get_node_mut(node).map(|n| n.try_get_scripts_mut()) + handle: Handle, + ) -> Result, GraphError> + where + T: ScriptTrait, + { + let node = self.try_get_node_mut(handle)?; + Ok(node.try_get_scripts_mut()) } /// Tries to borrow a node and find a component of the given type `C` across **all** available /// scripts of the node. If you want to search a component `C` in a particular script, then use /// [`Self::try_get_script_of`] and then search for component in it. #[inline] - pub fn try_get_script_component_of(&self, node: Handle) -> Option<&C> + pub fn try_get_script_component_of(&self, handle: Handle) -> Result<&C, GraphError> where C: Any, { - self.try_get_node(node) - .and_then(|node| node.try_get_script_component()) + let node = self.try_get_node(handle)?; + node.try_get_script_component() + .ok_or_else(|| GraphError::NoScriptComponent { + handle, + component_type_name: std::any::type_name::(), + }) } /// Tries to borrow a node and find a component of the given type `C` across **all** available /// scripts of the node. If you want to search a component `C` in a particular script, then use /// [`Self::try_get_script_of_mut`] and then search for component in it. #[inline] - pub fn try_get_script_component_of_mut(&mut self, node: Handle) -> Option<&mut C> + pub fn try_get_script_component_of_mut( + &mut self, + handle: Handle, + ) -> Result<&mut C, GraphError> where C: Any, { - self.try_get_node_mut(node) - .and_then(|node| node.try_get_script_component_mut()) + let node = self.try_get_node_mut(handle)?; + node.try_get_script_component_mut() + .ok_or_else(|| GraphError::NoScriptComponent { + handle, + component_type_name: std::any::type_name::(), + }) } /// Returns a handle of the node that has the given id. @@ -1731,17 +1814,22 @@ impl Graph { } /// Tries to borrow a node by its id. - pub fn node_by_id(&self, id: SceneNodeId) -> Option<(Handle, &Node)> { + pub fn node_by_id(&self, id: SceneNodeId) -> Result<(Handle, &Node), GraphError> { self.instance_id_map .get(&id) - .and_then(|h| self.pool.try_borrow(*h).map(|n| (*h, n))) + .ok_or_else(|| GraphError::UnknownId(id)) + .and_then(|h| Ok(self.pool.try_borrow(*h).map(|n| (*h, n))?)) } /// Tries to borrow a node by its id. - pub fn node_by_id_mut(&mut self, id: SceneNodeId) -> Option<(Handle, &mut Node)> { + pub fn node_by_id_mut( + &mut self, + id: SceneNodeId, + ) -> Result<(Handle, &mut Node), GraphError> { self.instance_id_map .get(&id) - .and_then(|h| self.pool.try_borrow_mut(*h).map(|n| (*h, n))) + .ok_or_else(|| GraphError::UnknownId(id)) + .and_then(|h| Ok(self.pool.try_borrow_mut(*h).map(|n| (*h, n))?)) } } @@ -1784,7 +1872,10 @@ impl Visit for Graph { } impl AbstractSceneGraph for Graph { - fn try_get_node_untyped(&self, handle: ErasedHandle) -> Option<&dyn AbstractSceneNode> { + fn try_get_node_untyped( + &self, + handle: ErasedHandle, + ) -> Result<&dyn AbstractSceneNode, PoolError> { self.pool .try_borrow(handle.into()) .map(|n| n as &dyn AbstractSceneNode) @@ -1793,7 +1884,7 @@ impl AbstractSceneGraph for Graph { fn try_get_node_untyped_mut( &mut self, handle: ErasedHandle, - ) -> Option<&mut dyn AbstractSceneNode> { + ) -> Result<&mut dyn AbstractSceneNode, PoolError> { self.pool .try_borrow_mut(handle.into()) .map(|n| n as &mut dyn AbstractSceneNode) @@ -1813,7 +1904,7 @@ impl BaseSceneGraph for Graph { } #[inline] - fn actual_type_id(&self, handle: Handle) -> Option { + fn actual_type_id(&self, handle: Handle) -> Result { self.pool .try_borrow(handle) .map(|n| NodeAsAny::as_any(n.0.deref()).type_id()) @@ -1919,7 +2010,7 @@ impl BaseSceneGraph for Graph { let parent_handle = std::mem::replace(&mut self.pool[node_handle].parent, Handle::NONE); // Remove child from parent's children list - if let Some(parent) = self.pool.try_borrow_mut(parent_handle) { + if let Ok(parent) = self.pool.try_borrow_mut(parent_handle) { if let Some(i) = parent.children().iter().position(|h| *h == node_handle) { parent.children.remove(i); } @@ -1931,22 +2022,25 @@ impl BaseSceneGraph for Graph { } #[inline] - fn try_get_node(&self, handle: Handle) -> Option<&Self::Node> { + fn try_get_node(&self, handle: Handle) -> Result<&Self::Node, PoolError> { self.pool.try_borrow(handle) } #[inline] - fn try_get_node_mut(&mut self, handle: Handle) -> Option<&mut Self::Node> { + fn try_get_node_mut( + &mut self, + handle: Handle, + ) -> Result<&mut Self::Node, PoolError> { self.pool.try_borrow_mut(handle) } - fn derived_type_ids(&self, handle: Handle) -> Option> { + fn derived_type_ids(&self, handle: Handle) -> Result, PoolError> { self.pool .try_borrow(handle) .map(|n| Box::deref(&n.0).query_derived_types().to_vec()) } - fn actual_type_name(&self, handle: Handle) -> Option<&'static str> { + fn actual_type_name(&self, handle: Handle) -> Result<&'static str, PoolError> { self.pool .try_borrow(handle) .map(|n| n.0.deref().type_name()) @@ -1970,11 +2064,14 @@ impl SceneGraph for Graph { self.pool.iter_mut() } - fn try_get>(&self, handle: Handle) -> Option<&U> { + fn try_get>(&self, handle: Handle) -> Result<&U, PoolError> { self.pool.try_get(handle) } - fn try_get_mut>(&mut self, handle: Handle) -> Option<&mut U> { + fn try_get_mut>( + &mut self, + handle: Handle, + ) -> Result<&mut U, PoolError> { self.pool.try_get_mut(handle) } } @@ -2056,14 +2153,14 @@ mod test { assert_eq!( graph.try_get_script_of::(handle), - Some(&MyScript { + Ok(&MyScript { foo: "Stuff".to_string(), bar: 123.321, }) ); assert_eq!( graph.try_get_script_of_mut::(handle), - Some(&mut MyScript { + Ok(&mut MyScript { foo: "Stuff".to_string(), bar: 123.321, }) @@ -2090,14 +2187,14 @@ mod test { assert_eq!( graph.try_get_script_of::(handle), - Some(&MyOtherScript { + Ok(&MyOtherScript { baz: 321, foobar: vec![1, 2, 3], }) ); assert_eq!( graph.try_get_script_of_mut::(handle), - Some(&mut MyOtherScript { + Ok(&mut MyOtherScript { baz: 321, foobar: vec![1, 2, 3], }) @@ -2482,18 +2579,15 @@ mod test { let pivot = PivotBuilder::new(BaseBuilder::new()).build(&mut graph); let rigid_body = RigidBodyBuilder::new(BaseBuilder::new()).build(&mut graph); - assert!(graph.pool.try_get(pivot).is_some()); - assert!(graph.pool.try_get(pivot.transmute::()).is_some()); - assert!(graph.pool.try_get(pivot.transmute::()).is_none()); + assert!(graph.pool.try_get(pivot).is_ok()); + assert!(graph.pool.try_get(pivot.transmute::()).is_ok()); + assert!(graph.pool.try_get(pivot.transmute::()).is_err()); - assert!(graph.pool.try_get(rigid_body).is_some()); + assert!(graph.pool.try_get(rigid_body).is_ok()); assert!(graph .pool .try_get(rigid_body.transmute::()) - .is_some()); - assert!(graph - .pool - .try_get(rigid_body.transmute::()) - .is_none()); + .is_ok()); + assert!(graph.pool.try_get(rigid_body.transmute::()).is_err()); } } diff --git a/fyrox-impl/src/scene/graph/physics.rs b/fyrox-impl/src/scene/graph/physics.rs index e23949d7e..f2eea7c55 100644 --- a/fyrox-impl/src/scene/graph/physics.rs +++ b/fyrox-impl/src/scene/graph/physics.rs @@ -78,7 +78,7 @@ use std::{ }; use strum_macros::{AsRefStr, EnumString, VariantNames}; -use fyrox_graph::{BaseSceneGraph, SceneGraphNode}; +use fyrox_graph::{BaseSceneGraph, SceneGraph, SceneGraphNode}; pub use rapier3d::geometry::shape::*; use rapier3d::parry::query::DefaultQueryDispatcher; use rapier3d::prelude::FrictionModel; @@ -512,7 +512,7 @@ fn make_trimesh( let root_inv_transform = owner_inv_transform; for &source in sources { - if let Some(mesh) = nodes.try_borrow(source.0).and_then(|n| n.cast::()) { + if let Ok(mesh) = nodes.try_get_component_of_type::(source.0) { let global_transform = root_inv_transform * mesh.global_transform(); for surface in mesh.surfaces() { @@ -800,12 +800,12 @@ fn collider_shape_into_native_shape( } } ColliderShape::Heightfield(heightfield) => pool - .try_borrow(heightfield.geometry_source.0) - .and_then(|n| n.cast::()) + .try_get_component_of_type::(heightfield.geometry_source.0) + .ok() .and_then(make_heightfield), ColliderShape::Polyhedron(polyhedron) => pool - .try_borrow(polyhedron.geometry_source.0) - .and_then(|n| n.cast::()) + .try_get_component_of_type::(polyhedron.geometry_source.0) + .ok() .map(|mesh| make_polyhedron_shape(owner_inv_global_transform, mesh)), } } @@ -1334,13 +1334,11 @@ impl PhysicsWorld { }), exclude_collider: filter .exclude_collider - .and_then(|h| graph.try_get_node(h)) - .and_then(|n| n.component_ref::()) + .and_then(|h| graph.try_get_of_type::(h).ok()) .map(|c| c.native.get()), exclude_rigid_body: filter .exclude_collider - .and_then(|h| graph.try_get_node(h)) - .and_then(|n| n.component_ref::()) + .and_then(|h| graph.try_get_of_type::(h).ok()) .map(|c| c.native.get()), predicate: Some(&predicate), }; @@ -1727,9 +1725,8 @@ impl PhysicsWorld { } } } - } else if let Some(parent_body) = nodes - .try_borrow(collider_node.parent()) - .and_then(|n| n.cast::()) + } else if let Ok(parent_body) = + nodes.try_get_component_of_type::(collider_node.parent()) { if parent_body.native.get() != RigidBodyHandle::invalid() { let inv_global_transform = isometric_global_transform(nodes, handle) @@ -1798,12 +1795,12 @@ impl PhysicsWorld { if let Some(native) = self.joints.set.get_mut(joint.native.get(), false) { joint.body1.try_sync_model(|v| { - if let Some(rigid_body_node) = nodes.try_get(v) { + if let Ok(rigid_body_node) = nodes.try_get(v) { native.body1 = rigid_body_node.native.get(); } }); joint.body2.try_sync_model(|v| { - if let Some(rigid_body_node) = nodes.try_get(v) { + if let Ok(rigid_body_node) = nodes.try_get(v) { native.body2 = rigid_body_node.native.get(); } }); @@ -1855,7 +1852,7 @@ impl PhysicsWorld { let mut local_frames = joint.local_frames.borrow_mut(); if local_frames.is_none() { - if let (Some(body1), Some(body2)) = + if let (Ok(body1), Ok(body2)) = (nodes.try_get(joint.body1()), nodes.try_get(joint.body2())) { let (local_frame1, local_frame2) = calculate_local_frames(joint, body1, body2); @@ -1874,9 +1871,11 @@ impl PhysicsWorld { if let (Some(body1), Some(body2)) = ( nodes .try_get(body1_handle) + .ok() .filter(|b| self.bodies.get(b.native.get()).is_some()), nodes .try_get(body2_handle) + .ok() .filter(|b| self.bodies.get(b.native.get()).is_some()), ) { let native_body1 = body1.native.get(); diff --git a/fyrox-impl/src/scene/joint.rs b/fyrox-impl/src/scene/joint.rs index 174d0f9da..fc7449281 100644 --- a/fyrox-impl/src/scene/joint.rs +++ b/fyrox-impl/src/scene/joint.rs @@ -666,13 +666,13 @@ impl NodeTrait for Joint { } fn validate(&self, scene: &Scene) -> Result<(), String> { - if scene.graph.try_get(self.body1()).is_none() { + if scene.graph.try_get(self.body1()).is_err() { return Err("3D Joint has invalid or unassigned handle to a \ first body, the joint will not operate!" .to_string()); } - if scene.graph.try_get(self.body2()).is_none() { + if scene.graph.try_get(self.body2()).is_err() { return Err("3D Joint has invalid or unassigned handle to a \ second body, the joint will not operate!" .to_string()); diff --git a/fyrox-impl/src/scene/mesh/mod.rs b/fyrox-impl/src/scene/mesh/mod.rs index 46cb8f138..0831f3600 100644 --- a/fyrox-impl/src/scene/mesh/mod.rs +++ b/fyrox-impl/src/scene/mesh/mod.rs @@ -674,7 +674,7 @@ impl NodeTrait for Mesh { // Special case for skinned meshes. for surface in self.surfaces.iter() { for &bone in surface.bones() { - if let Some(node) = context.nodes.try_borrow(bone) { + if let Ok(node) = context.nodes.try_borrow(bone) { world_aabb.add_point(node.global_position()) } } @@ -781,8 +781,7 @@ impl NodeTrait for Mesh { .bones .iter() .map(|bone_handle| { - if let Some(bone_node) = - ctx.graph.try_get_node(*bone_handle) + if let Ok(bone_node) = ctx.graph.try_get_node(*bone_handle) { bone_node.global_transform() * bone_node.inv_bind_pose_transform() diff --git a/fyrox-impl/src/scene/mod.rs b/fyrox-impl/src/scene/mod.rs index 3bc571fed..c7295ff9b 100644 --- a/fyrox-impl/src/scene/mod.rs +++ b/fyrox-impl/src/scene/mod.rs @@ -78,6 +78,7 @@ use crate::{ utils::navmesh::Navmesh, }; use fxhash::FxHashSet; +use fyrox_core::pool::PoolError; use std::{ fmt::{Display, Formatter}, ops::{Index, IndexMut}, @@ -130,22 +131,22 @@ impl NavMeshContainer { } /// Tries to borrow a navmesh by its index. - pub fn at(&self, i: u32) -> Option<&Navmesh> { + pub fn at(&self, i: u32) -> Result<&Navmesh, PoolError> { self.pool.at(i) } /// Tries to borrow a navmesh by its handle. - pub fn try_get(&self, handle: Handle) -> Option<&Navmesh> { + pub fn try_get(&self, handle: Handle) -> Result<&Navmesh, PoolError> { self.pool.try_borrow(handle) } /// Tries to borrow a navmesh by its index. - pub fn at_mut(&mut self, i: u32) -> Option<&mut Navmesh> { + pub fn at_mut(&mut self, i: u32) -> Result<&mut Navmesh, PoolError> { self.pool.at_mut(i) } /// Tries to borrow a navmesh by its handle. - pub fn try_get_mut(&mut self, handle: Handle) -> Option<&mut Navmesh> { + pub fn try_get_mut(&mut self, handle: Handle) -> Result<&mut Navmesh, PoolError> { self.pool.try_borrow_mut(handle) } } @@ -654,12 +655,12 @@ impl SceneContainer { } /// Tries to borrow a scene using its handle. - pub fn try_get(&self, handle: Handle) -> Option<&Scene> { + pub fn try_get(&self, handle: Handle) -> Result<&Scene, PoolError> { self.pool.try_borrow(handle) } /// Tries to borrow a scene using its handle. - pub fn try_get_mut(&mut self, handle: Handle) -> Option<&mut Scene> { + pub fn try_get_mut(&mut self, handle: Handle) -> Result<&mut Scene, PoolError> { self.pool.try_borrow_mut(handle) } diff --git a/fyrox-impl/src/scene/ragdoll.rs b/fyrox-impl/src/scene/ragdoll.rs index 30663bfb6..902fbadef 100644 --- a/fyrox-impl/src/scene/ragdoll.rs +++ b/fyrox-impl/src/scene/ragdoll.rs @@ -351,10 +351,9 @@ impl NodeTrait for Ragdoll { let mut new_lin_vel = None; let mut new_ang_vel = None; if *self.is_active && !self.prev_enabled { - if let Some(character_rigid_body) = ctx + if let Ok(character_rigid_body) = ctx .nodes - .try_borrow_mut(*self.character_rigid_body) - .and_then(|n| n.component_mut::()) + .try_get_component_of_type::(*self.character_rigid_body) { new_lin_vel = Some(character_rigid_body.lin_vel()); new_ang_vel = Some(character_rigid_body.ang_vel()); @@ -475,12 +474,11 @@ impl NodeTrait for Ragdoll { } }); - if let Some(root_limb_body) = ctx.nodes.try_borrow(self.root_limb.bone) { + if let Ok(root_limb_body) = ctx.nodes.try_borrow(self.root_limb.bone) { let position = root_limb_body.global_position(); - if let Some(character_rigid_body) = ctx + if let Ok(character_rigid_body) = ctx .nodes - .try_borrow_mut(*self.character_rigid_body) - .and_then(|n| n.component_mut::()) + .try_get_component_of_type_mut::(*self.character_rigid_body) { if *self.is_active { character_rigid_body.set_lin_vel(Default::default()); diff --git a/fyrox-impl/src/scene/rigidbody.rs b/fyrox-impl/src/scene/rigidbody.rs index 746bd43dd..c143b7d6b 100644 --- a/fyrox-impl/src/scene/rigidbody.rs +++ b/fyrox-impl/src/scene/rigidbody.rs @@ -647,6 +647,7 @@ impl NodeTrait for RigidBody { context .nodes .try_borrow(self.parent) + .ok() .map(|p| p.global_transform()) .unwrap_or_else(Matrix4::identity), ); @@ -654,7 +655,7 @@ impl NodeTrait for RigidBody { fn validate(&self, scene: &Scene) -> Result<(), String> { for &child in self.children() { - if scene.graph.try_get_of_type::(child).is_some() { + if scene.graph.try_get_of_type::(child).is_ok() { return Ok(()); } } diff --git a/fyrox-impl/src/scene/sound/context.rs b/fyrox-impl/src/scene/sound/context.rs index 5a4fc0371..cdf5442f5 100644 --- a/fyrox-impl/src/scene/sound/context.rs +++ b/fyrox-impl/src/scene/sound/context.rs @@ -157,13 +157,13 @@ impl SoundContext { } pub(crate) fn set_sound_position(&mut self, sound: &Sound) { - if let Some(source) = self.native.state().try_get_source_mut(sound.native.get()) { + if let Ok(source) = self.native.state().try_get_source_mut(sound.native.get()) { source.set_position(sound.global_position()); } } pub(crate) fn sync_with_sound(&self, sound: &mut Sound) { - if let Some(source) = self.native.state().try_get_source_mut(sound.native.get()) { + if let Ok(source) = self.native.state().try_get_source_mut(sound.native.get()) { // Sync back. sound.status.set_value_silent(source.status()); sound diff --git a/fyrox-impl/src/script/mod.rs b/fyrox-impl/src/script/mod.rs index c35228c91..7aee6e026 100644 --- a/fyrox-impl/src/script/mod.rs +++ b/fyrox-impl/src/script/mod.rs @@ -22,6 +22,7 @@ //! Script is used to add custom logic to scene nodes. See [ScriptTrait] for more info. +use crate::engine::input::InputState; use crate::{ asset::manager::ResourceManager, core::{ @@ -39,7 +40,10 @@ use crate::{ plugin::{Plugin, PluginContainer}, scene::{base::NodeScriptMessage, node::Node, Scene}, }; +use fyrox_core::pool::PoolError; use fyrox_core::reflect::FieldMut; +pub use fyrox_core_derive::ScriptMessagePayload; +use fyrox_graph::BaseSceneGraph; use std::{ any::{Any, TypeId}, fmt::{Debug, Formatter}, @@ -47,14 +51,10 @@ use std::{ str::FromStr, sync::mpsc::Sender, }; - -use crate::engine::input::InputState; -pub use fyrox_core_derive::ScriptMessagePayload; -use fyrox_graph::BaseSceneGraph; pub mod constructor; pub(crate) trait UniversalScriptContext { - fn node(&mut self) -> Option<&mut Node>; + fn node(&mut self) -> Result<&mut Node, PoolError>; fn destroy_script_deferred(&self, script: Script, index: usize); fn set_script_index(&mut self, index: usize); } @@ -417,7 +417,7 @@ pub struct ScriptContext<'a, 'b, 'c> { } impl UniversalScriptContext for ScriptContext<'_, '_, '_> { - fn node(&mut self) -> Option<&mut Node> { + fn node(&mut self) -> Result<&mut Node, PoolError> { self.scene.graph.try_get_node_mut(self.handle) } @@ -501,7 +501,7 @@ pub struct ScriptMessageContext<'a, 'b, 'c> { } impl UniversalScriptContext for ScriptMessageContext<'_, '_, '_> { - fn node(&mut self) -> Option<&mut Node> { + fn node(&mut self) -> Result<&mut Node, PoolError> { self.scene.graph.try_get_node_mut(self.handle) } @@ -576,7 +576,7 @@ pub struct ScriptDeinitContext<'a, 'b, 'c> { } impl UniversalScriptContext for ScriptDeinitContext<'_, '_, '_> { - fn node(&mut self) -> Option<&mut Node> { + fn node(&mut self) -> Result<&mut Node, PoolError> { self.scene.graph.try_get_node_mut(self.node_handle) } diff --git a/fyrox-impl/src/utils/behavior/mod.rs b/fyrox-impl/src/utils/behavior/mod.rs index a4cfd8796..9836664e4 100644 --- a/fyrox-impl/src/utils/behavior/mod.rs +++ b/fyrox-impl/src/utils/behavior/mod.rs @@ -44,6 +44,7 @@ use crate::{ leaf::LeafNode, }, }; +use fyrox_core::pool::PoolError; use std::{ fmt::Debug, ops::{Index, IndexMut}, @@ -224,12 +225,15 @@ where } /// Tries to get a shared reference to a node by given handle. - pub fn node(&self, handle: Handle>) -> Option<&BehaviorNode> { + pub fn node(&self, handle: Handle>) -> Result<&BehaviorNode, PoolError> { self.nodes.try_borrow(handle) } /// Tries to get a mutable reference to a node by given handle. - pub fn node_mut(&mut self, handle: Handle>) -> Option<&mut BehaviorNode> { + pub fn node_mut( + &mut self, + handle: Handle>, + ) -> Result<&mut BehaviorNode, PoolError> { self.nodes.try_borrow_mut(handle) } diff --git a/fyrox-sound/src/bus.rs b/fyrox-sound/src/bus.rs index cd5c330ee..c8eec4dff 100644 --- a/fyrox-sound/src/bus.rs +++ b/fyrox-sound/src/bus.rs @@ -22,6 +22,7 @@ //! for more info and examples use crate::effects::{Effect, EffectRenderTrait}; +use fyrox_core::pool::PoolError; use fyrox_core::{ pool::{Handle, Pool, Ticket}, reflect::prelude::*, @@ -355,7 +356,7 @@ impl AudioBusGraph { std::mem::replace(&mut self.buses[node_handle].parent_bus, Handle::NONE); // Remove child from parent's children list - if let Some(parent) = self.buses.try_borrow_mut(parent_handle) { + if let Ok(parent) = self.buses.try_borrow_mut(parent_handle) { if let Some(i) = parent.children().iter().position(|h| *h == node_handle) { parent.child_buses.remove(i); } @@ -415,12 +416,15 @@ impl AudioBusGraph { } /// Tries to borrow an audio bus by its handle. - pub fn try_get_bus_ref(&self, handle: Handle) -> Option<&AudioBus> { + pub fn try_get_bus_ref(&self, handle: Handle) -> Result<&AudioBus, PoolError> { self.buses.try_borrow(handle) } /// Tries to borrow an audio bus by its handle. - pub fn try_get_bus_mut(&mut self, handle: Handle) -> Option<&mut AudioBus> { + pub fn try_get_bus_mut( + &mut self, + handle: Handle, + ) -> Result<&mut AudioBus, PoolError> { self.buses.try_borrow_mut(handle) } @@ -439,7 +443,7 @@ impl AudioBusGraph { pub fn try_take_reserve_bus( &mut self, handle: Handle, - ) -> Option<(Ticket, AudioBus)> { + ) -> Result<(Ticket, AudioBus), PoolError> { self.buses.try_take_reserve(handle) } diff --git a/fyrox-sound/src/context.rs b/fyrox-sound/src/context.rs index 05db3c46c..0ede44012 100644 --- a/fyrox-sound/src/context.rs +++ b/fyrox-sound/src/context.rs @@ -37,6 +37,7 @@ use crate::{ renderer::{render_source_default, Renderer}, source::{SoundSource, Status}, }; +use fyrox_core::pool::PoolError; use fyrox_core::{ pool::{Handle, Pool}, reflect::prelude::*, @@ -247,7 +248,10 @@ impl State { } /// Returns mutable reference to sound source at given handle. If handle is invalid, this method will panic. - pub fn try_get_source_mut(&mut self, handle: Handle) -> Option<&mut SoundSource> { + pub fn try_get_source_mut( + &mut self, + handle: Handle, + ) -> Result<&mut SoundSource, PoolError> { self.sources.try_borrow_mut(handle) } diff --git a/fyrox-ui/src/absm.rs b/fyrox-ui/src/absm.rs index 0700543c2..09654ced1 100644 --- a/fyrox-ui/src/absm.rs +++ b/fyrox-ui/src/absm.rs @@ -34,7 +34,7 @@ use crate::{ }; use fyrox_animation::machine::Parameter; use fyrox_graph::constructor::{ConstructorProvider, GraphNodeConstructor}; -use fyrox_graph::{SceneGraph, SceneGraphNode}; +use fyrox_graph::SceneGraph; use strum_macros::{AsRefStr, EnumString, VariantNames}; /// UI-specific root motion settings. @@ -179,10 +179,9 @@ define_widget_deref!(AnimationBlendingStateMachine); impl Control for AnimationBlendingStateMachine { fn update(&mut self, dt: f32, ui: &mut UserInterface) { - if let Some(animation_player) = ui + if let Ok(animation_player) = ui .nodes - .try_borrow_mut(*self.animation_player) - .and_then(|n| n.component_mut::()) + .try_get_component_of_type_mut::(*self.animation_player) { // Prevent animation player to apply animation to scene nodes. The animation will // do than instead. @@ -316,7 +315,7 @@ impl AbsmEventProvider { return; }; - let Some(absm) = ui.try_get_mut_of_type::(*self.absm) else { + let Ok(absm) = ui.try_get_mut_of_type::(*self.absm) else { return; }; diff --git a/fyrox-ui/src/animation.rs b/fyrox-ui/src/animation.rs index b249dedf6..fa981fdd4 100644 --- a/fyrox-ui/src/animation.rs +++ b/fyrox-ui/src/animation.rs @@ -100,7 +100,7 @@ impl AnimationPoseExt for AnimationPose { for (node, local_pose) in self.poses() { if node.is_none() { Log::writeln(MessageKind::Error, "Invalid node handle found for animation pose, most likely it means that animation retargeting failed!"); - } else if let Some(node) = ui.try_get_node_mut(*node) { + } else if let Ok(node) = ui.try_get_node_mut(*node) { node.invalidate_layout(); local_pose.values.apply(node); diff --git a/fyrox-ui/src/build.rs b/fyrox-ui/src/build.rs index c50dedeff..4abba47a5 100644 --- a/fyrox-ui/src/build.rs +++ b/fyrox-ui/src/build.rs @@ -25,6 +25,7 @@ use crate::{ core::pool::Handle, font::FontResource, message::UiMessage, style::resource::StyleResource, Control, RestrictionEntry, UiNode, UserInterface, }; +use fyrox_core::pool::PoolError; use fyrox_graph::BaseSceneGraph; use std::{ ops::{Index, IndexMut}, @@ -148,12 +149,12 @@ impl BuildContext<'_> { } /// Tries to fetch the node by its handle. Returns `None` if the handle is invalid. - pub fn try_get_node(&self, node: Handle) -> Option<&UiNode> { + pub fn try_get_node(&self, node: Handle) -> Result<&UiNode, PoolError> { self.ui.try_get_node(node) } /// Tries to fetch the node by its handle. Returns `None` if the handle is invalid. - pub fn try_get_node_mut(&mut self, node: Handle) -> Option<&mut UiNode> { + pub fn try_get_node_mut(&mut self, node: Handle) -> Result<&mut UiNode, PoolError> { self.ui.nodes.try_borrow_mut(node) } diff --git a/fyrox-ui/src/color/gradient.rs b/fyrox-ui/src/color/gradient.rs index bfb90e224..15e7757d9 100644 --- a/fyrox-ui/src/color/gradient.rs +++ b/fyrox-ui/src/color/gradient.rs @@ -45,7 +45,7 @@ use crate::{ use crate::message::MessageData; use fyrox_graph::constructor::{ConstructorProvider, GraphNodeConstructor}; -use fyrox_graph::BaseSceneGraph; +use fyrox_graph::{BaseSceneGraph, SceneGraph}; use std::cell::Cell; #[derive(Debug, Clone, PartialEq)] @@ -251,7 +251,7 @@ impl Control for ColorGradientEditor { ui.post(self.handle, ColorGradientEditorMessage::Value(gradient)); } else if message.destination() == self.remove_point - && ui.try_get_node(self.context_menu_target.get()).is_some() + && ui.try_get_node(self.context_menu_target.get()).is_ok() { let gradient = self.fetch_gradient(self.context_menu_target.get(), ui); @@ -290,9 +290,8 @@ impl Control for ColorGradientEditor { self.context_menu_target.set(*target); if message.destination() == self.point_context_menu.handle() { - if let Some(point) = ui - .try_get_node(self.context_menu_target.get()) - .and_then(|n| n.query_component::()) + if let Ok(point) = + ui.try_get_of_type::(self.context_menu_target.get()) { ui.send_with_flags( self.selector_field, diff --git a/fyrox-ui/src/dock/config.rs b/fyrox-ui/src/dock/config.rs index a2a44e9c9..332500a28 100644 --- a/fyrox-ui/src/dock/config.rs +++ b/fyrox-ui/src/dock/config.rs @@ -149,7 +149,7 @@ fn find_window( if window_handle.is_none() { for other_window_handle in windows.iter().cloned() { - if let Some(window_node) = ui.try_get_node(other_window_handle) { + if let Ok(window_node) = ui.try_get_node(other_window_handle) { if &window_node.name == window_name { return other_window_handle; } @@ -161,8 +161,7 @@ fn find_window( impl TileDescriptor { pub(super) fn from_tile_handle(handle: Handle, ui: &UserInterface) -> Self { - ui.try_get_node(handle) - .and_then(|t| t.query_component::()) + ui.try_get_of_type::(handle) .map(|t| Self { content: TileContentDescriptor::from_tile(&t.content, ui), }) diff --git a/fyrox-ui/src/dock/mod.rs b/fyrox-ui/src/dock/mod.rs index 0ba762353..eb32325ec 100644 --- a/fyrox-ui/src/dock/mod.rs +++ b/fyrox-ui/src/dock/mod.rs @@ -226,7 +226,7 @@ impl DockingManager { .borrow() .iter() .filter_map(|h| { - ui.try_get_node(*h).map(|w| FloatingWindowDescriptor { + ui.try_get_node(*h).ok().map(|w| FloatingWindowDescriptor { name: w.name.clone(), position: w.actual_local_position(), size: w.actual_local_size(), @@ -250,10 +250,7 @@ impl DockingManager { let mut windows = Vec::new(); let mut stack = vec![root_tile_handle]; while let Some(tile_handle) = stack.pop() { - if let Some(tile) = ui - .try_get_node(tile_handle) - .and_then(|n| n.query_component::()) - { + if let Ok(tile) = ui.try_get_of_type::(tile_handle) { match tile.content { TileContent::Window(window) => { if ui.is_valid_handle(window) { diff --git a/fyrox-ui/src/file_browser/fs_tree.rs b/fyrox-ui/src/file_browser/fs_tree.rs index 14ab52c2d..e40f51748 100644 --- a/fyrox-ui/src/file_browser/fs_tree.rs +++ b/fyrox-ui/src/file_browser/fs_tree.rs @@ -400,6 +400,7 @@ pub fn build_single_folder( pub fn tree_path(tree_handle: Handle, ui: &UserInterface) -> Option { ui.try_get(tree_handle) + .ok() .and_then(|n| n.user_data_cloned::()) } diff --git a/fyrox-ui/src/file_browser/menu.rs b/fyrox-ui/src/file_browser/menu.rs index cbf05d60f..33bbfafee 100644 --- a/fyrox-ui/src/file_browser/menu.rs +++ b/fyrox-ui/src/file_browser/menu.rs @@ -230,6 +230,7 @@ impl ItemContextMenu { fn item_path(&self, ui: &UserInterface) -> Option { ui.try_get_node(self.base_menu.popup.placement.target()) + .ok() .and_then(|n| n.user_data_cloned::()) } } diff --git a/fyrox-ui/src/file_browser/mod.rs b/fyrox-ui/src/file_browser/mod.rs index 6eef319a1..b37fe73d6 100644 --- a/fyrox-ui/src/file_browser/mod.rs +++ b/fyrox-ui/src/file_browser/mod.rs @@ -341,7 +341,7 @@ impl FileBrowser { if tree_item.is_some() { let parent_path = parent_path(path); let parent_tree = fs_tree::find_tree_item(self.tree_root, &parent_path, ui); - if let Some(parent_tree_node) = ui.try_get(parent_tree) { + if let Ok(parent_tree_node) = ui.try_get(parent_tree) { if parent_tree_node.has_component::() { ui.send(parent_tree, TreeRootMessage::RemoveItem(tree_item)) } else { diff --git a/fyrox-ui/src/grid.rs b/fyrox-ui/src/grid.rs index 8593161e3..65b2c7feb 100644 --- a/fyrox-ui/src/grid.rs +++ b/fyrox-ui/src/grid.rs @@ -422,7 +422,7 @@ impl Grid { .iter() .copied() .filter(|&c| { - let Some(child_ref) = ui.try_get_node(c) else { + let Ok(child_ref) = ui.try_get_node(c) else { return false; }; child_ref.row() == row_index && child_ref.column() == column_index @@ -446,7 +446,7 @@ impl Grid { } } for handle in self.children() { - let Some(node) = ui.try_get_node(*handle) else { + let Ok(node) = ui.try_get_node(*handle) else { continue; }; let Some(row) = rows.get_mut(node.row()) else { @@ -483,7 +483,7 @@ impl Grid { measure_width: bool, measure_height: bool, ) { - let Some(node) = ui.try_get_node(child) else { + let Ok(node) = ui.try_get_node(child) else { return; }; let mut rows = self.rows.borrow_mut(); diff --git a/fyrox-ui/src/inspector/mod.rs b/fyrox-ui/src/inspector/mod.rs index 7f9940c77..0a17759e8 100644 --- a/fyrox-ui/src/inspector/mod.rs +++ b/fyrox-ui/src/inspector/mod.rs @@ -650,7 +650,7 @@ impl Inspector { } if pasted { - if let Some(inspector) = ui.try_get_of_type::(inspector) { + if let Ok(inspector) = ui.try_get_of_type::(inspector) { let ctx = inspector.context.clone(); if let Err(errs) = @@ -678,7 +678,7 @@ impl Inspector { ) -> Option<&ContextEntry> { let mut parent_handle = from; - while let Some(parent) = ui.try_get_node(parent_handle) { + while let Ok(parent) = ui.try_get_node(parent_handle) { for entry in self.context.entries.iter() { if entry.property_container == parent_handle { return Some(entry); @@ -1467,7 +1467,7 @@ impl Control for Inspector { if message.direction() == MessageDirection::FromWidget && menu.handle() == message.destination() { - if let Some(popup) = ui.try_get_of_type::(menu.handle()) { + if let Ok(popup) = ui.try_get_of_type::(menu.handle()) { if let Some(entry) = self.find_property_container(popup.owner, ui) { ui.post( self.handle, diff --git a/fyrox-ui/src/lib.rs b/fyrox-ui/src/lib.rs index d55d597e3..60e80ee1d 100644 --- a/fyrox-ui/src/lib.rs +++ b/fyrox-ui/src/lib.rs @@ -359,6 +359,7 @@ use strum_macros::{AsRefStr, EnumString, VariantNames}; pub use alignment::*; pub use build::*; pub use control::*; +use fyrox_core::pool::PoolError; pub use fyrox_texture as texture; pub use node::*; pub use thickness::*; @@ -894,7 +895,7 @@ fn invalidate_recursive_up( node: Handle, callback: fn(&UiNode), ) { - if let Some(node_ref) = nodes.try_borrow(node) { + if let Ok(node_ref) = nodes.try_borrow(node) { (callback)(node_ref); if node_ref.parent().is_some() { invalidate_recursive_up(nodes, node_ref.parent(), callback); @@ -954,12 +955,15 @@ impl UiContainer { } /// Tries to borrow a user interface using its handle. - pub fn try_get(&self, handle: Handle) -> Option<&UserInterface> { + pub fn try_get(&self, handle: Handle) -> Result<&UserInterface, PoolError> { self.pool.try_borrow(handle) } /// Tries to borrow a user interface using its handle. - pub fn try_get_mut(&mut self, handle: Handle) -> Option<&mut UserInterface> { + pub fn try_get_mut( + &mut self, + handle: Handle, + ) -> Result<&mut UserInterface, PoolError> { self.pool.try_borrow_mut(handle) } @@ -1224,7 +1228,7 @@ impl UserInterface { for _ in 0..indent { result.push_str(" "); } - let Some(node) = self.try_get(current) else { + let Ok(node) = self.try_get(current) else { use std::fmt::Write; writeln!(result, "{}: Failed to get", current).unwrap(); return; @@ -1283,10 +1287,10 @@ impl UserInterface { .nodes .try_borrow_dependant_mut(node_handle, |n| n.parent()); - if let Some(widget) = widget { + if let Ok(widget) = widget { self.stack.extend_from_slice(widget.children()); - let visibility = if let Some(parent) = parent { + let visibility = if let Ok(parent) = parent { widget.visibility() && parent.is_globally_visible() } else { widget.visibility() @@ -1316,7 +1320,7 @@ impl UserInterface { .nodes .try_borrow_dependant_mut(node_handle, |n| n.parent()); - if let Some(widget) = widget { + if let Ok(widget) = widget { if widget.is_globally_visible() { self.stack.extend_from_slice(widget.children()); @@ -1325,7 +1329,7 @@ impl UserInterface { layout_transform[6] = widget.actual_local_position().x; layout_transform[7] = widget.actual_local_position().y; - let visual_transform = if let Some(parent) = parent { + let visual_transform = if let Ok(parent) = parent { parent.visual_transform() * layout_transform * widget.render_transform() } else { layout_transform * widget.render_transform() @@ -1370,7 +1374,7 @@ impl UserInterface { self.update_global_visibility(node); } LayoutEvent::ZIndexChanged(node) => { - if let Some(node_ref) = self.nodes.try_borrow(node) { + if let Ok(node_ref) = self.nodes.try_borrow(node) { // Z index affects the location of the node in its parent's children list. // Hash set will remove duplicate requests of z-index updates, thus improving // performance. @@ -1395,7 +1399,7 @@ impl UserInterface { func: &mut impl FnMut(Handle), ) { func(from); - if let Some(node) = graph.try_get_node(from) { + if let Ok(node) = graph.try_get_node(from) { for &child in node.children() { traverse_recursive(graph, child, func) } @@ -1458,10 +1462,11 @@ impl UserInterface { self.update_visual_transform(root); // Recalculate clip bounds, because they depend on the visual transform. - if let Some(root_ref) = self.try_get_node(root) { + if let Ok(root_ref) = self.try_get_node(root) { self.calculate_clip_bounds( root, self.try_get_node(root_ref.parent()) + .ok() .map(|c| c.clip_bounds()) .unwrap_or_else(|| { Rect::new(0.0, 0.0, self.screen_size.x, self.screen_size.y) @@ -1529,7 +1534,7 @@ impl UserInterface { self.style = style; fn notify_depth_first(node: Handle, ui: &UserInterface) { - if let Some(node_ref) = ui.try_get_node(node) { + if let Ok(node_ref) = ui.try_get_node(node) { for child in node_ref.children.iter() { notify_depth_first(*child, ui); } @@ -1637,7 +1642,7 @@ impl UserInterface { } } - if let Some(keyboard_focus_node) = self.nodes.try_borrow(self.keyboard_focus_node) { + if let Ok(keyboard_focus_node) = self.nodes.try_borrow(self.keyboard_focus_node) { if keyboard_focus_node.global_visibility && keyboard_focus_node.accepts_input { let bounds = keyboard_focus_node.screen_bounds().inflate(1.0, 1.0); self.drawing_context.push_rounded_rect(&bounds, 1.0, 2.0, 6); @@ -2234,7 +2239,7 @@ impl UserInterface { } for &handle in self.methods_registry.preview_message.iter() { - if let Some(node_ref) = self.nodes.try_borrow(handle) { + if let Ok(node_ref) = self.nodes.try_borrow(handle) { node_ref.preview_message(self, &mut message); } } @@ -2395,7 +2400,7 @@ impl UserInterface { vertical_alignment, margin, } => { - if let (Some(node), Some(relative_node)) = ( + if let (Ok(node), Ok(relative_node)) = ( self.try_get_node(message.destination()), self.try_get_node(*relative_to), ) { @@ -2453,7 +2458,7 @@ impl UserInterface { } } - if let Some(parent) = self.try_get_node(node.parent()) { + if let Ok(parent) = self.try_get_node(node.parent()) { // Transform screen anchor point into the local coordinate system // of the parent node. let local_anchor_point = parent.screen_to_local(screen_anchor_point); @@ -2466,7 +2471,7 @@ impl UserInterface { } WidgetMessage::MouseUp { button, .. } => { if *button == MouseButton::Right && !message.handled() { - if let Some(picked) = self.nodes.try_borrow(self.picked_node) { + if let Ok(picked) = self.nodes.try_borrow(self.picked_node) { // Get the context menu from the current node or a parent node let (context_menu, target) = if picked.context_menu().is_some() { (picked.context_menu(), self.picked_node) @@ -2474,7 +2479,7 @@ impl UserInterface { let parent_handle = picked .find_by_criteria_up(self, |n| n.context_menu().is_some()); - if let Some(parent) = self.nodes.try_borrow(parent_handle) { + if let Ok(parent) = self.nodes.try_borrow(parent_handle) { (parent.context_menu(), parent_handle) } else { (None, Handle::NONE) @@ -2573,7 +2578,7 @@ impl UserInterface { } else { let mut tooltip_owner_hovered = false; let mut handle = self.picked_node; - while let Some(node) = self.nodes.try_borrow(handle) { + while let Ok(node) = self.nodes.try_borrow(handle) { if let Some(tooltip) = node.tooltip.as_ref() { if &entry.tooltip == tooltip { tooltip_owner_hovered = true; @@ -2598,7 +2603,7 @@ impl UserInterface { // Check for hovering over a widget with a tooltip, or hovering over a tooltip. let mut handle = self.picked_node; - while let Some(node) = self.nodes.try_borrow(handle) { + while let Ok(node) = self.nodes.try_borrow(handle) { let parent = node.parent(); if let Some(tooltip) = node.tooltip() { @@ -2874,7 +2879,7 @@ impl UserInterface { state, text, } => { - if let Some(keyboard_focus_node) = self.try_get_node(self.keyboard_focus_node) { + if let Ok(keyboard_focus_node) = self.try_get_node(self.keyboard_focus_node) { if keyboard_focus_node.is_globally_visible() { match state { ButtonState::Pressed => { @@ -3233,7 +3238,10 @@ impl UserInterface { } #[inline] - pub fn try_get_node_mut(&mut self, node_handle: Handle) -> Option<&mut UiNode> { + pub fn try_get_node_mut( + &mut self, + node_handle: Handle, + ) -> Result<&mut UiNode, PoolError> { self.nodes.try_borrow_mut(node_handle) } @@ -3353,7 +3361,7 @@ impl UserInterface { } } - let Some(node) = self.nodes.try_borrow(node_handle) else { + let Ok(node) = self.nodes.try_borrow(node_handle) else { return Default::default(); }; @@ -3488,7 +3496,10 @@ impl PrefabData for UserInterface { } impl AbstractSceneGraph for UserInterface { - fn try_get_node_untyped(&self, handle: ErasedHandle) -> Option<&dyn AbstractSceneNode> { + fn try_get_node_untyped( + &self, + handle: ErasedHandle, + ) -> Result<&dyn AbstractSceneNode, PoolError> { self.nodes .try_borrow(handle.into()) .map(|n| n as &dyn AbstractSceneNode) @@ -3497,7 +3508,7 @@ impl AbstractSceneGraph for UserInterface { fn try_get_node_untyped_mut( &mut self, handle: ErasedHandle, - ) -> Option<&mut dyn AbstractSceneNode> { + ) -> Result<&mut dyn AbstractSceneNode, PoolError> { self.nodes .try_borrow_mut(handle.into()) .map(|n| n as &mut dyn AbstractSceneNode) @@ -3516,7 +3527,7 @@ impl BaseSceneGraph for UserInterface { } #[inline] - fn actual_type_id(&self, handle: Handle) -> Option { + fn actual_type_id(&self, handle: Handle) -> Result { self.nodes .try_borrow(handle) .map(|n| ControlAsAny::as_any(n.0.deref()).type_id()) @@ -3533,12 +3544,15 @@ impl BaseSceneGraph for UserInterface { } #[inline] - fn try_get_node(&self, handle: Handle) -> Option<&Self::Node> { + fn try_get_node(&self, handle: Handle) -> Result<&Self::Node, PoolError> { self.nodes.try_borrow(handle) } #[inline] - fn try_get_node_mut(&mut self, handle: Handle) -> Option<&mut Self::Node> { + fn try_get_node_mut( + &mut self, + handle: Handle, + ) -> Result<&mut Self::Node, PoolError> { self.nodes.try_borrow_mut(handle) } @@ -3626,13 +3640,13 @@ impl BaseSceneGraph for UserInterface { } } - fn derived_type_ids(&self, handle: Handle) -> Option> { + fn derived_type_ids(&self, handle: Handle) -> Result, PoolError> { self.nodes .try_borrow(handle) .map(|n| n.0.query_derived_types().to_vec()) } - fn actual_type_name(&self, handle: Handle) -> Option<&'static str> { + fn actual_type_name(&self, handle: Handle) -> Result<&'static str, PoolError> { self.nodes .try_borrow(handle) .map(|n| Reflect::type_name(n.0.deref())) @@ -3656,11 +3670,14 @@ impl SceneGraph for UserInterface { self.nodes.iter_mut() } - fn try_get>(&self, handle: Handle) -> Option<&U> { + fn try_get>(&self, handle: Handle) -> Result<&U, PoolError> { self.nodes.try_get(handle) } - fn try_get_mut>(&mut self, handle: Handle) -> Option<&mut U> { + fn try_get_mut>( + &mut self, + handle: Handle, + ) -> Result<&mut U, PoolError> { self.nodes.try_get_mut(handle) } } diff --git a/fyrox-ui/src/menu.rs b/fyrox-ui/src/menu.rs index 334652583..137201aca 100644 --- a/fyrox-ui/src/menu.rs +++ b/fyrox-ui/src/menu.rs @@ -365,7 +365,7 @@ impl DerefMut for ItemsContainer { impl ItemsContainer { fn selected_item_index(&self, ui: &UserInterface) -> Option { for (index, item) in self.items.iter().enumerate() { - if let Some(item_ref) = ui.try_get_of_type::(*item) { + if let Ok(item_ref) = ui.try_get_of_type::(*item) { if *item_ref.is_selected { return Some(index); } @@ -388,7 +388,8 @@ impl ItemsContainer { } index %= count; let handle = self.items.get(index as usize).cloned(); - if let Some(item) = handle.and_then(|h| ui.try_get_of_type::(h)) { + if let Some(item) = handle.and_then(|h| ui.try_get_of_type::(h).ok()) + { if item.enabled() { return handle; } @@ -445,6 +446,7 @@ crate::define_widget_deref!(MenuItem); impl MenuItem { fn is_opened(&self, ui: &UserInterface) -> bool { ui.try_get_of_type::(*self.items_panel) + .ok() .is_some_and(|items_panel| *items_panel.popup.is_open) } @@ -496,7 +498,7 @@ fn close_menu_chain(from: Handle, ui: &UserInterface) { while handle.is_some() { let popup_handle = ui.find_handle_up(handle, &mut |n| n.has_component::()); - if let Some(panel) = ui.try_get_of_type::(popup_handle) { + if let Ok(panel) = ui.try_get_of_type::(popup_handle) { if *panel.popup.is_open { ui.send(popup_handle, PopupMessage::Close); } @@ -1164,7 +1166,7 @@ impl Control for ContextMenu { if let Some(WidgetMessage::KeyDown(key_code)) = message.data() { if !message.handled() { - if let Some(parent_menu_item) = ui.try_get_node(self.parent_menu_item) { + if let Ok(parent_menu_item) = ui.try_get_node(self.parent_menu_item) { if keyboard_navigation( ui, *key_code, @@ -1255,7 +1257,7 @@ fn keyboard_navigation( ui.send(selected_item, MenuItemMessage::Open); - if let Some(selected_item_ref) = ui.try_get_of_type::(selected_item) { + if let Ok(selected_item_ref) = ui.try_get_of_type::(selected_item) { if let Some(first_item) = selected_item_ref.items_container.first() { ui.send(*first_item, MenuItemMessage::Select(true)); } diff --git a/fyrox-ui/src/popup.rs b/fyrox-ui/src/popup.rs index e8aa9b2e4..def81a997 100644 --- a/fyrox-ui/src/popup.rs +++ b/fyrox-ui/src/popup.rs @@ -339,6 +339,7 @@ impl Popup { fn right_top_placement(&self, ui: &UserInterface, target: Handle) -> Vector2 { ui.try_get_node(target) + .ok() .map(|n| n.screen_position() + Vector2::new(n.actual_global_size().x, 0.0)) .unwrap_or_else(|| { Vector2::new(ui.screen_size().x - self.widget.actual_global_size().x, 0.0) @@ -347,12 +348,14 @@ impl Popup { fn center_placement(&self, ui: &UserInterface, target: Handle) -> Vector2 { ui.try_get_node(target) + .ok() .map(|n| n.screen_position() + n.actual_global_size().scale(0.5)) .unwrap_or_else(|| (ui.screen_size - self.widget.actual_global_size()).scale(0.5)) } fn left_bottom_placement(&self, ui: &UserInterface, target: Handle) -> Vector2 { ui.try_get_node(target) + .ok() .map(|n| n.screen_position() + Vector2::new(0.0, n.actual_global_size().y)) .unwrap_or_else(|| { Vector2::new(0.0, ui.screen_size().y - self.widget.actual_global_size().y) @@ -361,6 +364,7 @@ impl Popup { fn right_bottom_placement(&self, ui: &UserInterface, target: Handle) -> Vector2 { ui.try_get_node(target) + .ok() .map(|n| n.screen_position() + n.actual_global_size()) .unwrap_or_else(|| ui.screen_size - self.widget.actual_global_size()) } diff --git a/fyrox-ui/src/scroll_panel.rs b/fyrox-ui/src/scroll_panel.rs index 47ca4d07b..1f3be594f 100644 --- a/fyrox-ui/src/scroll_panel.rs +++ b/fyrox-ui/src/scroll_panel.rs @@ -182,7 +182,7 @@ impl ScrollPanel { children_size } fn bring_into_view(&self, ui: &UserInterface, handle: Handle) { - let Some(node_to_focus_ref) = ui.try_get_node(handle) else { + let Ok(node_to_focus_ref) = ui.try_get_node(handle) else { return; }; let mut parent = handle; diff --git a/fyrox-ui/src/tab_control.rs b/fyrox-ui/src/tab_control.rs index 84189e998..7d605e55d 100644 --- a/fyrox-ui/src/tab_control.rs +++ b/fyrox-ui/src/tab_control.rs @@ -655,7 +655,7 @@ impl TabControlBuilder { let tab_count = self.tabs.len(); // Hide everything but initial tab content. for (i, (_, tab)) in self.tabs.iter().enumerate() { - if let Some(content) = ctx.try_get_node_mut(tab.content) { + if let Ok(content) = ctx.try_get_node_mut(tab.content) { content.set_visibility(i == self.initial_tab); } } diff --git a/fyrox-ui/src/test.rs b/fyrox-ui/src/test.rs index 1b8027829..3034b3015 100644 --- a/fyrox-ui/src/test.rs +++ b/fyrox-ui/src/test.rs @@ -65,7 +65,7 @@ pub trait UserInterfaceTestingExtension { } fn is_enabled(mut handle: Handle, ui: &UserInterface) -> bool { - while let Some(node) = ui.try_get(handle) { + while let Ok(node) = ui.try_get(handle) { if !node.enabled() { return false; } @@ -158,7 +158,7 @@ impl UserInterfaceTestingExtension for UserInterface { fn poll_all_messages(&mut self) { while let Some(msg) = self.poll_message() { - if let Some(widget) = self.try_get(msg.destination()) { + if let Ok(widget) = self.try_get(msg.destination()) { let ty = Reflect::type_name(widget); info!("[{ty}]{msg:?}"); } @@ -170,7 +170,7 @@ impl UserInterfaceTestingExtension for UserInterface { fn poll_and_count(&mut self, mut pred: impl FnMut(&UiMessage) -> bool) -> usize { let mut num = 0; while let Some(msg) = self.poll_message() { - if let Some(widget) = self.try_get(msg.destination()) { + if let Ok(widget) = self.try_get(msg.destination()) { let ty = Reflect::type_name(widget); info!("[{ty}]{msg:?}"); } diff --git a/fyrox-ui/src/text_box.rs b/fyrox-ui/src/text_box.rs index 13b55e92f..a6431e7ee 100644 --- a/fyrox-ui/src/text_box.rs +++ b/fyrox-ui/src/text_box.rs @@ -1692,7 +1692,7 @@ impl<'a> TextBoxBuilder<'a> { self.widget_builder.cursor = Some(CursorIcon::Text); } let placeholder = self.placeholder.build(&self.text, ctx); - if let Some(placeholder_ref) = ctx.try_get_node_mut(placeholder) { + if let Ok(placeholder_ref) = ctx.try_get_node_mut(placeholder) { placeholder_ref .hit_test_visibility .set_value_and_mark_modified(false); diff --git a/fyrox-ui/src/tree.rs b/fyrox-ui/src/tree.rs index e1433fadc..597927155 100644 --- a/fyrox-ui/src/tree.rs +++ b/fyrox-ui/src/tree.rs @@ -865,7 +865,7 @@ impl Control for TreeRoot { if &self.selected != selected { let mut items = self.items.clone(); while let Some(handle) = items.pop() { - if let Some(tree_ref) = ui.try_get_of_type::(handle) { + if let Ok(tree_ref) = ui.try_get_of_type::(handle) { items.extend_from_slice(&tree_ref.items); let new_selection_state = if selected.contains(&handle) { @@ -903,10 +903,7 @@ impl Control for TreeRoot { } KeyCode::ArrowLeft => { if let Some(selection) = self.selected.first() { - if let Some(item) = ui - .try_get_node(*selection) - .and_then(|n| n.component_ref::()) - { + if let Ok(item) = ui.try_get_of_type::(*selection) { if item.is_expanded { ui.send( *selection, @@ -967,10 +964,7 @@ impl TreeRoot { fn move_selection(&self, ui: &UserInterface, direction: Direction, expand: bool) { if let Some(selected_item) = self.selected.first() { - let Some(item) = ui - .try_get_node(*selected_item) - .and_then(|n| n.component_ref::()) - else { + let Ok(item) = ui.try_get_of_type::(*selected_item) else { return; }; diff --git a/fyrox-ui/src/widget.rs b/fyrox-ui/src/widget.rs index c087273af..c105652b1 100644 --- a/fyrox-ui/src/widget.rs +++ b/fyrox-ui/src/widget.rs @@ -1197,7 +1197,7 @@ impl Widget { ) -> Handle { let mut parent_handle = self.parent; while parent_handle.is_some() { - if let Some(parent_node) = ui.nodes.try_borrow(parent_handle) { + if let Ok(parent_node) = ui.nodes.try_borrow(parent_handle) { if func(parent_node) { return parent_handle; } diff --git a/fyrox-ui/src/window.rs b/fyrox-ui/src/window.rs index 5032100ce..b3f90c7e0 100644 --- a/fyrox-ui/src/window.rs +++ b/fyrox-ui/src/window.rs @@ -703,7 +703,7 @@ impl Control for Window { font, font_size, } => { - if ui.try_get_of_type::(self.title).is_some() { + if ui.try_get_of_type::(self.title).is_ok() { // Just modify existing text, this is much faster than // re-create text everytime. ui.send(self.title, TextMessage::Text(text.clone()));