mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
error handling for graph + fixes for the engine
- editor fixes on their way
This commit is contained in:
@@ -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<T: EntityId> AnimationContainer<T> {
|
||||
|
||||
/// Tries to remove an animation from the container by its handle.
|
||||
#[inline]
|
||||
pub fn remove(&mut self, handle: Handle<Animation<T>>) -> Option<Animation<T>> {
|
||||
pub fn remove(&mut self, handle: Handle<Animation<T>>) -> Result<Animation<T>, PoolError> {
|
||||
self.pool.try_free(handle)
|
||||
}
|
||||
|
||||
@@ -1055,13 +1056,16 @@ impl<T: EntityId> AnimationContainer<T> {
|
||||
|
||||
/// Tries to borrow a reference to an animation in the container.
|
||||
#[inline]
|
||||
pub fn try_get(&self, handle: Handle<Animation<T>>) -> Option<&Animation<T>> {
|
||||
pub fn try_get(&self, handle: Handle<Animation<T>>) -> Result<&Animation<T>, 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<Animation<T>>) -> Option<&mut Animation<T>> {
|
||||
pub fn try_get_mut(
|
||||
&mut self,
|
||||
handle: Handle<Animation<T>>,
|
||||
) -> Result<&mut Animation<T>, PoolError> {
|
||||
self.pool.try_borrow_mut(handle)
|
||||
}
|
||||
|
||||
|
||||
@@ -310,7 +310,7 @@ impl<T: EntityId> MachineLayer<T> {
|
||||
animations: &AnimationContainer<T>,
|
||||
strategy: AnimationEventCollectionStrategy,
|
||||
) -> LayerAnimationEventsCollection<T> {
|
||||
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<T: EntityId> MachineLayer<T> {
|
||||
})
|
||||
.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<T: EntityId> MachineLayer<T> {
|
||||
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<T: EntityId> MachineLayer<T> {
|
||||
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<T: EntityId> MachineLayer<T> {
|
||||
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<T: EntityId> MachineLayer<T> {
|
||||
animations: &AnimationContainer<T>,
|
||||
) -> 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<T: EntityId> MachineLayer<T> {
|
||||
}
|
||||
|
||||
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<T: EntityId> MachineLayer<T> {
|
||||
);
|
||||
}
|
||||
|
||||
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<T: EntityId> MachineLayer<T> {
|
||||
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<T: EntityId> MachineLayer<T> {
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,21 +332,20 @@ impl<T: EntityId> Machine<T> {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ impl<T: EntityId> AnimationPoseSource<T> for BlendAnimations<T> {
|
||||
}
|
||||
};
|
||||
|
||||
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<T: EntityId> AnimationPoseSource<T> for BlendAnimations<T> {
|
||||
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<T: EntityId> AnimationPoseSource<T> for BlendAnimations<T> {
|
||||
.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<T: EntityId> AnimationPoseSource<T> for BlendAnimations<T> {
|
||||
.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<T: EntityId> AnimationPoseSource<T> for BlendAnimationsByIndex<T> {
|
||||
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<T: EntityId> AnimationPoseSource<T> for BlendAnimationsByIndex<T> {
|
||||
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<T: EntityId> AnimationPoseSource<T> for BlendAnimationsByIndex<T> {
|
||||
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<T: EntityId> AnimationPoseSource<T> for BlendAnimationsByIndex<T> {
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ impl<T: EntityId> AnimationPoseSource<T> for BlendSpace<T> {
|
||||
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<T: EntityId> AnimationPoseSource<T> for BlendSpace<T> {
|
||||
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),
|
||||
|
||||
@@ -122,21 +122,21 @@ impl<T: EntityId> PoseNode<T> {
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ impl<T: EntityId> AnimationPoseSource<T> for PlayAnimation<T> {
|
||||
animations: &AnimationContainer<T>,
|
||||
_dt: f32,
|
||||
) -> Ref<AnimationPose<T>> {
|
||||
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.
|
||||
|
||||
@@ -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<T: EntityId> StateAction<T> {
|
||||
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<T: EntityId> State<T> {
|
||||
}
|
||||
|
||||
/// Returns a final pose of the state.
|
||||
pub fn pose<'a>(&self, nodes: &'a Pool<PoseNode<T>>) -> Option<Ref<'a, AnimationPose<T>>> {
|
||||
pub fn pose<'a>(
|
||||
&self,
|
||||
nodes: &'a Pool<PoseNode<T>>,
|
||||
) -> Result<Ref<'a, AnimationPose<T>>, PoolError> {
|
||||
nodes.try_borrow(self.root).map(|root| root.pose())
|
||||
}
|
||||
|
||||
@@ -177,7 +181,7 @@ impl<T: EntityId> State<T> {
|
||||
nodes: &Pool<PoseNode<T>>,
|
||||
animations: &mut FxHashSet<Handle<Animation<T>>>,
|
||||
) {
|
||||
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<T: EntityId> State<T> {
|
||||
animations: &AnimationContainer<T>,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,9 +436,10 @@ impl<T: EntityId> LogicNode<T> {
|
||||
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()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+47
-60
@@ -427,21 +427,21 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum PoolError<T> {
|
||||
#[derive(PartialEq, Copy, Clone)]
|
||||
pub enum PoolError {
|
||||
InvalidIndex(u32),
|
||||
InvalidGeneration(u32),
|
||||
InvalidType(Handle<T>),
|
||||
Empty(Handle<T>),
|
||||
NoSuchComponent(Handle<T>),
|
||||
MutablyBorrowed(Handle<T>),
|
||||
ImmutablyBorrowed(Handle<T>),
|
||||
UnknownDependentObject(Handle<T>),
|
||||
InvalidType(ErasedHandle),
|
||||
Empty(ErasedHandle),
|
||||
NoSuchComponent(ErasedHandle),
|
||||
MutablyBorrowed(ErasedHandle),
|
||||
ImmutablyBorrowed(ErasedHandle),
|
||||
UnknownDependentObject(ErasedHandle),
|
||||
}
|
||||
|
||||
impl<T> std::error::Error for PoolError<T> {}
|
||||
impl std::error::Error for PoolError {}
|
||||
|
||||
impl<T> Display for PoolError<T> {
|
||||
impl Display for PoolError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::InvalidIndex(index) => {
|
||||
@@ -495,7 +495,7 @@ impl<T> Display for PoolError<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Debug for PoolError<T> {
|
||||
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<T, P>, PoolError<T>> {
|
||||
fn records_get(&self, index: u32) -> Result<&PoolRecord<T, P>, 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<T, P>, PoolError<T>> {
|
||||
fn records_get_mut(&mut self, index: u32) -> Result<&mut PoolRecord<T, P>, PoolError> {
|
||||
self.records
|
||||
.get_mut(usize::try_from(index).expect("Index overflowed usize"))
|
||||
.ok_or(PoolError::InvalidIndex(index))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_get<U: ObjectOrVariant<T>>(&self, handle: Handle<U>) -> Result<&U, PoolError<T>> {
|
||||
pub fn try_get<U: ObjectOrVariant<T>>(&self, handle: Handle<U>) -> 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<U: ObjectOrVariant<T>>(
|
||||
&mut self,
|
||||
handle: Handle<U>,
|
||||
) -> Result<&mut U, PoolError<T>> {
|
||||
) -> 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<T>) -> Result<&T, PoolError<T>> {
|
||||
pub fn try_borrow(&self, handle: Handle<T>) -> 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<T>) -> Result<&mut T, PoolError<T>> {
|
||||
pub fn try_borrow_mut(&mut self, handle: Handle<T>) -> 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<T>,
|
||||
func: F,
|
||||
) -> (Result<&mut T, PoolError<T>>, Result<&mut T, PoolError<T>>)
|
||||
) -> (Result<&mut T, PoolError>, Result<&mut T, PoolError>)
|
||||
where
|
||||
F: FnOnce(&T) -> Handle<T>,
|
||||
{
|
||||
@@ -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>) -> 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<T>) -> Result<T, PoolError<T>> {
|
||||
pub fn try_free(&mut self, handle: Handle<T>) -> Result<T, PoolError> {
|
||||
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<T>) -> Result<(Ticket<T>, T), PoolError<T>> {
|
||||
pub fn try_take_reserve(&mut self, handle: Handle<T>) -> Result<(Ticket<T>, 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<T>> {
|
||||
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<T>> {
|
||||
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<C>(&self, handle: Handle<T>) -> Result<&C, PoolError<T>>
|
||||
pub fn try_get_component_of_type<C>(&self, handle: Handle<T>) -> Result<&C, PoolError>
|
||||
where
|
||||
C: 'static,
|
||||
{
|
||||
self.try_borrow(handle)
|
||||
.and_then(|n| {
|
||||
n.query_component_ref(TypeId::of::<C>())
|
||||
.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<C>(
|
||||
&mut self,
|
||||
handle: Handle<T>,
|
||||
) -> Result<&mut C, PoolError<T>>
|
||||
) -> Result<&mut C, PoolError>
|
||||
where
|
||||
C: 'static,
|
||||
{
|
||||
self.try_borrow_mut(handle)
|
||||
.and_then(|n| {
|
||||
n.query_component_mut(TypeId::of::<C>())
|
||||
.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())))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -163,10 +163,10 @@ where
|
||||
&'b self,
|
||||
handle: Handle<T>,
|
||||
func: F,
|
||||
) -> Result<Ref<'a, 'b, C>, PoolError<T>>
|
||||
) -> Result<Ref<'a, 'b, C>, PoolError>
|
||||
where
|
||||
C: ?Sized,
|
||||
F: FnOnce(&T) -> Result<&C, PoolError<T>>,
|
||||
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<T>) -> Result<Ref<'a, 'b, T>, PoolError<T>> {
|
||||
pub fn try_get<'b: 'a>(&'b self, handle: Handle<T>) -> Result<Ref<'a, 'b, T>, PoolError> {
|
||||
self.try_get_internal(handle, |obj| Ok(obj))
|
||||
}
|
||||
|
||||
@@ -220,10 +220,10 @@ where
|
||||
&'b self,
|
||||
handle: Handle<T>,
|
||||
func: F,
|
||||
) -> Result<RefMut<'a, 'b, C>, PoolError<T>>
|
||||
) -> Result<RefMut<'a, 'b, C>, PoolError>
|
||||
where
|
||||
C: ?Sized,
|
||||
F: FnOnce(&mut T) -> Result<&mut C, PoolError<T>>,
|
||||
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<T>,
|
||||
) -> Result<RefMut<'a, 'b, T>, PoolError<T>> {
|
||||
) -> Result<RefMut<'a, 'b, T>, PoolError> {
|
||||
self.try_get_mut_internal(handle, |obj| Ok(obj))
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ where
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn free(&self, handle: Handle<T>) -> Result<T, PoolError<T>> {
|
||||
pub fn free(&self, handle: Handle<T>) -> Result<T, PoolError> {
|
||||
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<T>,
|
||||
) -> Result<Ref<'a, 'b, C>, PoolError<T>>
|
||||
) -> Result<Ref<'a, 'b, C>, PoolError>
|
||||
where
|
||||
C: 'static,
|
||||
{
|
||||
self.try_get_internal(handle, move |obj| {
|
||||
obj.query_component_ref(TypeId::of::<C>())
|
||||
.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<T>,
|
||||
) -> Result<RefMut<'a, 'b, C>, PoolError<T>>
|
||||
) -> Result<RefMut<'a, 'b, C>, PoolError>
|
||||
where
|
||||
C: 'static,
|
||||
{
|
||||
self.try_get_mut_internal(handle, move |obj| {
|
||||
obj.query_component_mut(TypeId::of::<C>())
|
||||
.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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<VisitorNode>> {
|
||||
pub fn current_region(&self) -> Result<&str, PoolError> {
|
||||
self.nodes
|
||||
.try_borrow(self.current_node)
|
||||
.map(|n| n.name.as_str())
|
||||
|
||||
+65
-34
@@ -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<N> Default for LinkScheme<N> {
|
||||
}
|
||||
|
||||
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<Self::Node>) -> Option<TypeId>;
|
||||
fn actual_type_id(&self, handle: Handle<Self::Node>) -> Result<TypeId, PoolError>;
|
||||
|
||||
/// Returns actual type name of the node.
|
||||
fn actual_type_name(&self, handle: Handle<Self::Node>) -> Option<&'static str>;
|
||||
fn actual_type_name(&self, handle: Handle<Self::Node>) -> Result<&'static str, PoolError>;
|
||||
|
||||
/// Returns a list of derived type ids of the node.
|
||||
fn derived_type_ids(&self, handle: Handle<Self::Node>) -> Option<Vec<TypeId>>;
|
||||
fn derived_type_ids(&self, handle: Handle<Self::Node>) -> Result<Vec<TypeId>, PoolError>;
|
||||
|
||||
/// Returns a handle of the root node of the graph.
|
||||
fn root(&self) -> Handle<Self::Node>;
|
||||
@@ -713,10 +716,13 @@ pub trait BaseSceneGraph: AbstractSceneGraph {
|
||||
fn set_root(&mut self, root: Handle<Self::Node>);
|
||||
|
||||
/// Tries to borrow a node, returns Some(node) if the handle is valid, None - otherwise.
|
||||
fn try_get_node(&self, handle: Handle<Self::Node>) -> Option<&Self::Node>;
|
||||
fn try_get_node(&self, handle: Handle<Self::Node>) -> 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<Self::Node>) -> Option<&mut Self::Node>;
|
||||
fn try_get_node_mut(
|
||||
&mut self,
|
||||
handle: Handle<Self::Node>,
|
||||
) -> Result<&mut Self::Node, PoolError>;
|
||||
|
||||
/// Checks whether the given node handle is valid or not.
|
||||
fn is_valid_handle(&self, handle: Handle<Self::Node>) -> 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<Item = &mut Self::Node>;
|
||||
|
||||
fn try_get<U: ObjectOrVariant<Self::ObjectType>>(&self, handle: Handle<U>) -> Option<&U>;
|
||||
fn try_get<U: ObjectOrVariant<Self::ObjectType>>(
|
||||
&self,
|
||||
handle: Handle<U>,
|
||||
) -> Result<&U, PoolError>;
|
||||
|
||||
fn try_get_mut<U: ObjectOrVariant<Self::ObjectType>>(
|
||||
&mut self,
|
||||
handle: Handle<U>,
|
||||
) -> 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<T>(&self, handle: Handle<Self::Node>) -> Option<&T>
|
||||
fn try_get_of_type<T>(&self, handle: Handle<Self::Node>) -> Result<&T, PoolError>
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
self.try_get_node(handle)
|
||||
.and_then(|n| n.query_component_ref(TypeId::of::<T>()))
|
||||
.and_then(|c| c.downcast_ref())
|
||||
.and_then(|n| {
|
||||
n.query_component_ref(TypeId::of::<T>())
|
||||
.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<T>(&mut self, handle: Handle<Self::Node>) -> Option<&mut T>
|
||||
fn try_get_mut_of_type<T>(&mut self, handle: Handle<Self::Node>) -> Result<&mut T, PoolError>
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
self.try_get_node_mut(handle)
|
||||
.and_then(|n| n.query_component_mut(TypeId::of::<T>()))
|
||||
.and_then(|c| c.downcast_mut())
|
||||
.and_then(|n| {
|
||||
n.query_component_mut(TypeId::of::<T>())
|
||||
.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::<T>(handle).is_some()
|
||||
self.try_get_of_type::<T>(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<Self::Node>,
|
||||
offset: isize,
|
||||
) -> Option<(Handle<Self::Node>, 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<Self::Node>) -> Option<&Self::Node> {
|
||||
fn try_get_node(&self, handle: Handle<Self::Node>) -> Result<&Self::Node, PoolError> {
|
||||
self.nodes.try_borrow(handle)
|
||||
}
|
||||
|
||||
fn try_get_node_mut(&mut self, handle: Handle<Self::Node>) -> Option<&mut Self::Node> {
|
||||
fn try_get_node_mut(
|
||||
&mut self,
|
||||
handle: Handle<Self::Node>,
|
||||
) -> Result<&mut Self::Node, PoolError> {
|
||||
self.nodes.try_borrow_mut(handle)
|
||||
}
|
||||
|
||||
fn actual_type_id(&self, handle: Handle<Self::Node>) -> Option<TypeId> {
|
||||
fn actual_type_id(&self, handle: Handle<Self::Node>) -> Result<TypeId, PoolError> {
|
||||
self.nodes
|
||||
.try_borrow(handle)
|
||||
.map(|n| NodeAsAny::as_any(n.0.deref()).type_id())
|
||||
}
|
||||
|
||||
fn derived_type_ids(&self, handle: Handle<Self::Node>) -> Option<Vec<TypeId>> {
|
||||
fn derived_type_ids(&self, handle: Handle<Self::Node>) -> Result<Vec<TypeId>, PoolError> {
|
||||
self.nodes
|
||||
.try_borrow(handle)
|
||||
.map(|n| n.0.deref().query_derived_types().to_vec())
|
||||
}
|
||||
|
||||
fn actual_type_name(&self, handle: Handle<Self::Node>) -> Option<&'static str> {
|
||||
fn actual_type_name(&self, handle: Handle<Self::Node>) -> 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<U: ObjectOrVariant<Node>>(&self, handle: Handle<U>) -> Option<&U> {
|
||||
fn try_get<U: ObjectOrVariant<Node>>(&self, handle: Handle<U>) -> Result<&U, PoolError> {
|
||||
self.nodes.try_get(handle)
|
||||
}
|
||||
|
||||
fn try_get_mut<U: ObjectOrVariant<Node>>(&mut self, handle: Handle<U>) -> Option<&mut U> {
|
||||
fn try_get_mut<U: ObjectOrVariant<Node>>(
|
||||
&mut self,
|
||||
handle: Handle<U>,
|
||||
) -> Result<&mut U, PoolError> {
|
||||
self.nodes.try_get_mut(handle)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -115,6 +115,7 @@ impl TileBuffer {
|
||||
fn inflated_world_aabb(graph: &Graph, object: Handle<Node>) -> Option<AxisAlignedBoundingBox> {
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -111,7 +111,7 @@ impl ImportedTarget {
|
||||
self.binding.value_binding()
|
||||
}
|
||||
fn value_in_graph(&self, graph: &Graph) -> Option<Box<[f32]>> {
|
||||
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())
|
||||
|
||||
@@ -170,13 +170,13 @@ fn get_ancestor_names<'a>(
|
||||
|
||||
fn get_ancestor_name(mut handle: Handle<Node>, 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<Node>, list: &[Handle<Node>], 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;
|
||||
|
||||
@@ -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::<AnimationPlayer>())
|
||||
.try_get_component_of_type_mut::<AnimationPlayer>(*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::<AnimationPlayer>())
|
||||
.is_none()
|
||||
.try_get_of_type::<AnimationPlayer>(*self.animation_player)
|
||||
.is_err()
|
||||
{
|
||||
Err(
|
||||
"Animation player is not set or invalid! Animation blending state \
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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::<RigidBody>())
|
||||
.is_none()
|
||||
.try_get_of_type::<RigidBody>(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!";
|
||||
|
||||
@@ -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::<RigidBody>())
|
||||
.is_none()
|
||||
.try_get_of_type::<RigidBody>(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!";
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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<SharedShape> {
|
||||
let tile_map = nodes.try_borrow(tile_map.0)?.component_ref::<TileMap>()?;
|
||||
let tile_map = nodes
|
||||
.try_borrow(tile_map.0)
|
||||
.ok()?
|
||||
.component_ref::<TileMap>()?;
|
||||
|
||||
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::<dim2::collider::Collider>())
|
||||
.and_then(|h| graph.try_get_of_type::<dim2::collider::Collider>(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::<dim2::rigidbody::RigidBody>())
|
||||
.and_then(|h| graph.try_get_of_type::<dim2::rigidbody::RigidBody>(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::<dim2::rigidbody::RigidBody>())
|
||||
} else if let Ok(parent_body) =
|
||||
nodes.try_get_component_of_type::<dim2::rigidbody::RigidBody>(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();
|
||||
|
||||
@@ -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::<Collider>(child).is_some() {
|
||||
if scene.graph.try_get_of_type::<Collider>(child).is_ok() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Node>,
|
||||
script_type_name: &'static str,
|
||||
},
|
||||
NoScriptComponent {
|
||||
handle: Handle<Node>,
|
||||
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<PoolError> 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>, &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<Node>) {
|
||||
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<Node>) {
|
||||
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<Node>,
|
||||
) {
|
||||
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<Node>),
|
||||
) {
|
||||
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<Node>) -> Vector3<f32> {
|
||||
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<T>(&self, node: Handle<Node>) -> Option<&T>
|
||||
pub fn try_get_script_of<T>(&self, handle: Handle<Node>) -> Result<&T, GraphError>
|
||||
where
|
||||
T: ScriptTrait,
|
||||
{
|
||||
self.try_get_node(node)
|
||||
.and_then(|node| node.try_get_script::<T>())
|
||||
let node = self.try_get_node(handle)?;
|
||||
node.try_get_script::<T>()
|
||||
.ok_or_else(|| GraphError::NoScript {
|
||||
handle,
|
||||
script_type_name: std::any::type_name::<T>(),
|
||||
})
|
||||
}
|
||||
|
||||
/// 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<T: ScriptTrait>(
|
||||
&self,
|
||||
node: Handle<Node>,
|
||||
) -> Option<impl Iterator<Item = &T>> {
|
||||
self.try_get_node(node).map(|n| n.try_get_scripts())
|
||||
handle: Handle<Node>,
|
||||
) -> Result<impl Iterator<Item = &T>, 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<T>(&mut self, node: Handle<Node>) -> Option<&mut T>
|
||||
pub fn try_get_script_of_mut<T>(&mut self, handle: Handle<Node>) -> Result<&mut T, GraphError>
|
||||
where
|
||||
T: ScriptTrait,
|
||||
{
|
||||
self.try_get_node_mut(node)
|
||||
.and_then(|node| node.try_get_script_mut::<T>())
|
||||
let node = self.try_get_node_mut(handle)?;
|
||||
node.try_get_script_mut::<T>()
|
||||
.ok_or_else(|| GraphError::NoScript {
|
||||
handle,
|
||||
script_type_name: std::any::type_name::<T>(),
|
||||
})
|
||||
}
|
||||
|
||||
/// 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<T: ScriptTrait>(
|
||||
pub fn try_get_scripts_of_mut<T>(
|
||||
&mut self,
|
||||
node: Handle<Node>,
|
||||
) -> Option<impl Iterator<Item = &mut T>> {
|
||||
self.try_get_node_mut(node).map(|n| n.try_get_scripts_mut())
|
||||
handle: Handle<Node>,
|
||||
) -> Result<impl Iterator<Item = &mut T>, 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<C>(&self, node: Handle<Node>) -> Option<&C>
|
||||
pub fn try_get_script_component_of<C>(&self, handle: Handle<Node>) -> 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::<C>(),
|
||||
})
|
||||
}
|
||||
|
||||
/// 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<C>(&mut self, node: Handle<Node>) -> Option<&mut C>
|
||||
pub fn try_get_script_component_of_mut<C>(
|
||||
&mut self,
|
||||
handle: Handle<Node>,
|
||||
) -> 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::<C>(),
|
||||
})
|
||||
}
|
||||
|
||||
/// 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>, &Node)> {
|
||||
pub fn node_by_id(&self, id: SceneNodeId) -> Result<(Handle<Node>, &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<Node>, &mut Node)> {
|
||||
pub fn node_by_id_mut(
|
||||
&mut self,
|
||||
id: SceneNodeId,
|
||||
) -> Result<(Handle<Node>, &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<Self::Node>) -> Option<TypeId> {
|
||||
fn actual_type_id(&self, handle: Handle<Self::Node>) -> Result<TypeId, PoolError> {
|
||||
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<Self::Node>) -> Option<&Self::Node> {
|
||||
fn try_get_node(&self, handle: Handle<Self::Node>) -> Result<&Self::Node, PoolError> {
|
||||
self.pool.try_borrow(handle)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_get_node_mut(&mut self, handle: Handle<Self::Node>) -> Option<&mut Self::Node> {
|
||||
fn try_get_node_mut(
|
||||
&mut self,
|
||||
handle: Handle<Self::Node>,
|
||||
) -> Result<&mut Self::Node, PoolError> {
|
||||
self.pool.try_borrow_mut(handle)
|
||||
}
|
||||
|
||||
fn derived_type_ids(&self, handle: Handle<Self::Node>) -> Option<Vec<TypeId>> {
|
||||
fn derived_type_ids(&self, handle: Handle<Self::Node>) -> Result<Vec<TypeId>, PoolError> {
|
||||
self.pool
|
||||
.try_borrow(handle)
|
||||
.map(|n| Box::deref(&n.0).query_derived_types().to_vec())
|
||||
}
|
||||
|
||||
fn actual_type_name(&self, handle: Handle<Self::Node>) -> Option<&'static str> {
|
||||
fn actual_type_name(&self, handle: Handle<Self::Node>) -> 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<U: ObjectOrVariant<Node>>(&self, handle: Handle<U>) -> Option<&U> {
|
||||
fn try_get<U: ObjectOrVariant<Node>>(&self, handle: Handle<U>) -> Result<&U, PoolError> {
|
||||
self.pool.try_get(handle)
|
||||
}
|
||||
|
||||
fn try_get_mut<U: ObjectOrVariant<Node>>(&mut self, handle: Handle<U>) -> Option<&mut U> {
|
||||
fn try_get_mut<U: ObjectOrVariant<Node>>(
|
||||
&mut self,
|
||||
handle: Handle<U>,
|
||||
) -> Result<&mut U, PoolError> {
|
||||
self.pool.try_get_mut(handle)
|
||||
}
|
||||
}
|
||||
@@ -2056,14 +2153,14 @@ mod test {
|
||||
|
||||
assert_eq!(
|
||||
graph.try_get_script_of::<MyScript>(handle),
|
||||
Some(&MyScript {
|
||||
Ok(&MyScript {
|
||||
foo: "Stuff".to_string(),
|
||||
bar: 123.321,
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
graph.try_get_script_of_mut::<MyScript>(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::<MyOtherScript>(handle),
|
||||
Some(&MyOtherScript {
|
||||
Ok(&MyOtherScript {
|
||||
baz: 321,
|
||||
foobar: vec![1, 2, 3],
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
graph.try_get_script_of_mut::<MyOtherScript>(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::<Pivot>()).is_some());
|
||||
assert!(graph.pool.try_get(pivot.transmute::<RigidBody>()).is_none());
|
||||
assert!(graph.pool.try_get(pivot).is_ok());
|
||||
assert!(graph.pool.try_get(pivot.transmute::<Pivot>()).is_ok());
|
||||
assert!(graph.pool.try_get(pivot.transmute::<RigidBody>()).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::<RigidBody>())
|
||||
.is_some());
|
||||
assert!(graph
|
||||
.pool
|
||||
.try_get(rigid_body.transmute::<Pivot>())
|
||||
.is_none());
|
||||
.is_ok());
|
||||
assert!(graph.pool.try_get(rigid_body.transmute::<Pivot>()).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::<Mesh>()) {
|
||||
if let Ok(mesh) = nodes.try_get_component_of_type::<Mesh>(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::<Terrain>())
|
||||
.try_get_component_of_type::<Terrain>(heightfield.geometry_source.0)
|
||||
.ok()
|
||||
.and_then(make_heightfield),
|
||||
ColliderShape::Polyhedron(polyhedron) => pool
|
||||
.try_borrow(polyhedron.geometry_source.0)
|
||||
.and_then(|n| n.cast::<Mesh>())
|
||||
.try_get_component_of_type::<Mesh>(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::<collider::Collider>())
|
||||
.and_then(|h| graph.try_get_of_type::<collider::Collider>(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::<rigidbody::RigidBody>())
|
||||
.and_then(|h| graph.try_get_of_type::<rigidbody::RigidBody>(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::<scene::rigidbody::RigidBody>())
|
||||
} else if let Ok(parent_body) =
|
||||
nodes.try_get_component_of_type::<scene::rigidbody::RigidBody>(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();
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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<Navmesh>) -> Option<&Navmesh> {
|
||||
pub fn try_get(&self, handle: Handle<Navmesh>) -> 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<Navmesh>) -> Option<&mut Navmesh> {
|
||||
pub fn try_get_mut(&mut self, handle: Handle<Navmesh>) -> 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<Scene>) -> Option<&Scene> {
|
||||
pub fn try_get(&self, handle: Handle<Scene>) -> 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<Scene>) -> Option<&mut Scene> {
|
||||
pub fn try_get_mut(&mut self, handle: Handle<Scene>) -> Result<&mut Scene, PoolError> {
|
||||
self.pool.try_borrow_mut(handle)
|
||||
}
|
||||
|
||||
|
||||
@@ -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::<RigidBody>())
|
||||
.try_get_component_of_type::<RigidBody>(*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::<RigidBody>())
|
||||
.try_get_component_of_type_mut::<RigidBody>(*self.character_rigid_body)
|
||||
{
|
||||
if *self.is_active {
|
||||
character_rigid_body.set_lin_vel(Default::default());
|
||||
|
||||
@@ -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::<Collider>(child).is_some() {
|
||||
if scene.graph.try_get_of_type::<Collider>(child).is_ok() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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<BehaviorNode<B>>) -> Option<&BehaviorNode<B>> {
|
||||
pub fn node(&self, handle: Handle<BehaviorNode<B>>) -> Result<&BehaviorNode<B>, 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<BehaviorNode<B>>) -> Option<&mut BehaviorNode<B>> {
|
||||
pub fn node_mut(
|
||||
&mut self,
|
||||
handle: Handle<BehaviorNode<B>>,
|
||||
) -> Result<&mut BehaviorNode<B>, PoolError> {
|
||||
self.nodes.try_borrow_mut(handle)
|
||||
}
|
||||
|
||||
|
||||
@@ -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<AudioBus>) -> Option<&AudioBus> {
|
||||
pub fn try_get_bus_ref(&self, handle: Handle<AudioBus>) -> 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<AudioBus>) -> Option<&mut AudioBus> {
|
||||
pub fn try_get_bus_mut(
|
||||
&mut self,
|
||||
handle: Handle<AudioBus>,
|
||||
) -> 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<AudioBus>,
|
||||
) -> Option<(Ticket<AudioBus>, AudioBus)> {
|
||||
) -> Result<(Ticket<AudioBus>, AudioBus), PoolError> {
|
||||
self.buses.try_take_reserve(handle)
|
||||
}
|
||||
|
||||
|
||||
@@ -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<SoundSource>) -> Option<&mut SoundSource> {
|
||||
pub fn try_get_source_mut(
|
||||
&mut self,
|
||||
handle: Handle<SoundSource>,
|
||||
) -> Result<&mut SoundSource, PoolError> {
|
||||
self.sources.try_borrow_mut(handle)
|
||||
}
|
||||
|
||||
|
||||
@@ -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::<AnimationPlayer>())
|
||||
.try_get_component_of_type_mut::<AnimationPlayer>(*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::<AnimationBlendingStateMachine>(*self.absm) else {
|
||||
let Ok(absm) = ui.try_get_mut_of_type::<AnimationBlendingStateMachine>(*self.absm) else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<UiNode>) -> Option<&UiNode> {
|
||||
pub fn try_get_node(&self, node: Handle<UiNode>) -> 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<UiNode>) -> Option<&mut UiNode> {
|
||||
pub fn try_get_node_mut(&mut self, node: Handle<UiNode>) -> Result<&mut UiNode, PoolError> {
|
||||
self.ui.nodes.try_borrow_mut(node)
|
||||
}
|
||||
|
||||
|
||||
@@ -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::<ColorPoint>())
|
||||
if let Ok(point) =
|
||||
ui.try_get_of_type::<ColorPoint>(self.context_menu_target.get())
|
||||
{
|
||||
ui.send_with_flags(
|
||||
self.selector_field,
|
||||
|
||||
@@ -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<UiNode>, ui: &UserInterface) -> Self {
|
||||
ui.try_get_node(handle)
|
||||
.and_then(|t| t.query_component::<Tile>())
|
||||
ui.try_get_of_type::<Tile>(handle)
|
||||
.map(|t| Self {
|
||||
content: TileContentDescriptor::from_tile(&t.content, ui),
|
||||
})
|
||||
|
||||
@@ -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::<Tile>())
|
||||
{
|
||||
if let Ok(tile) = ui.try_get_of_type::<Tile>(tile_handle) {
|
||||
match tile.content {
|
||||
TileContent::Window(window) => {
|
||||
if ui.is_valid_handle(window) {
|
||||
|
||||
@@ -400,6 +400,7 @@ pub fn build_single_folder(
|
||||
|
||||
pub fn tree_path(tree_handle: Handle<UiNode>, ui: &UserInterface) -> Option<TreeItemPath> {
|
||||
ui.try_get(tree_handle)
|
||||
.ok()
|
||||
.and_then(|n| n.user_data_cloned::<TreeItemPath>())
|
||||
}
|
||||
|
||||
|
||||
@@ -230,6 +230,7 @@ impl ItemContextMenu {
|
||||
|
||||
fn item_path(&self, ui: &UserInterface) -> Option<TreeItemPath> {
|
||||
ui.try_get_node(self.base_menu.popup.placement.target())
|
||||
.ok()
|
||||
.and_then(|n| n.user_data_cloned::<TreeItemPath>())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::<TreeRoot>() {
|
||||
ui.send(parent_tree, TreeRootMessage::RemoveItem(tree_item))
|
||||
} else {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -650,7 +650,7 @@ impl Inspector {
|
||||
}
|
||||
|
||||
if pasted {
|
||||
if let Some(inspector) = ui.try_get_of_type::<Inspector>(inspector) {
|
||||
if let Ok(inspector) = ui.try_get_of_type::<Inspector>(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::<Popup>(menu.handle()) {
|
||||
if let Ok(popup) = ui.try_get_of_type::<Popup>(menu.handle()) {
|
||||
if let Some(entry) = self.find_property_container(popup.owner, ui) {
|
||||
ui.post(
|
||||
self.handle,
|
||||
|
||||
+49
-32
@@ -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<UiNode>,
|
||||
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<UserInterface>) -> Option<&UserInterface> {
|
||||
pub fn try_get(&self, handle: Handle<UserInterface>) -> 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<UserInterface>) -> Option<&mut UserInterface> {
|
||||
pub fn try_get_mut(
|
||||
&mut self,
|
||||
handle: Handle<UserInterface>,
|
||||
) -> 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<UiNode>),
|
||||
) {
|
||||
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<UiNode>, 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<UiNode>) -> Option<&mut UiNode> {
|
||||
pub fn try_get_node_mut(
|
||||
&mut self,
|
||||
node_handle: Handle<UiNode>,
|
||||
) -> 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<Self::Node>) -> Option<TypeId> {
|
||||
fn actual_type_id(&self, handle: Handle<Self::Node>) -> Result<TypeId, PoolError> {
|
||||
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<Self::Node>) -> Option<&Self::Node> {
|
||||
fn try_get_node(&self, handle: Handle<Self::Node>) -> Result<&Self::Node, PoolError> {
|
||||
self.nodes.try_borrow(handle)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_get_node_mut(&mut self, handle: Handle<Self::Node>) -> Option<&mut Self::Node> {
|
||||
fn try_get_node_mut(
|
||||
&mut self,
|
||||
handle: Handle<Self::Node>,
|
||||
) -> 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<Self::Node>) -> Option<Vec<TypeId>> {
|
||||
fn derived_type_ids(&self, handle: Handle<Self::Node>) -> Result<Vec<TypeId>, PoolError> {
|
||||
self.nodes
|
||||
.try_borrow(handle)
|
||||
.map(|n| n.0.query_derived_types().to_vec())
|
||||
}
|
||||
|
||||
fn actual_type_name(&self, handle: Handle<Self::Node>) -> Option<&'static str> {
|
||||
fn actual_type_name(&self, handle: Handle<Self::Node>) -> 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<U: ObjectOrVariant<UiNode>>(&self, handle: Handle<U>) -> Option<&U> {
|
||||
fn try_get<U: ObjectOrVariant<UiNode>>(&self, handle: Handle<U>) -> Result<&U, PoolError> {
|
||||
self.nodes.try_get(handle)
|
||||
}
|
||||
|
||||
fn try_get_mut<U: ObjectOrVariant<UiNode>>(&mut self, handle: Handle<U>) -> Option<&mut U> {
|
||||
fn try_get_mut<U: ObjectOrVariant<UiNode>>(
|
||||
&mut self,
|
||||
handle: Handle<U>,
|
||||
) -> Result<&mut U, PoolError> {
|
||||
self.nodes.try_get_mut(handle)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ impl DerefMut for ItemsContainer {
|
||||
impl ItemsContainer {
|
||||
fn selected_item_index(&self, ui: &UserInterface) -> Option<usize> {
|
||||
for (index, item) in self.items.iter().enumerate() {
|
||||
if let Some(item_ref) = ui.try_get_of_type::<MenuItem>(*item) {
|
||||
if let Ok(item_ref) = ui.try_get_of_type::<MenuItem>(*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::<MenuItem>(h)) {
|
||||
if let Some(item) = handle.and_then(|h| ui.try_get_of_type::<MenuItem>(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::<ContextMenu>(*self.items_panel)
|
||||
.ok()
|
||||
.is_some_and(|items_panel| *items_panel.popup.is_open)
|
||||
}
|
||||
|
||||
@@ -496,7 +498,7 @@ fn close_menu_chain(from: Handle<UiNode>, ui: &UserInterface) {
|
||||
while handle.is_some() {
|
||||
let popup_handle = ui.find_handle_up(handle, &mut |n| n.has_component::<ContextMenu>());
|
||||
|
||||
if let Some(panel) = ui.try_get_of_type::<ContextMenu>(popup_handle) {
|
||||
if let Ok(panel) = ui.try_get_of_type::<ContextMenu>(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::<MenuItem>(selected_item) {
|
||||
if let Ok(selected_item_ref) = ui.try_get_of_type::<MenuItem>(selected_item) {
|
||||
if let Some(first_item) = selected_item_ref.items_container.first() {
|
||||
ui.send(*first_item, MenuItemMessage::Select(true));
|
||||
}
|
||||
|
||||
@@ -339,6 +339,7 @@ impl Popup {
|
||||
|
||||
fn right_top_placement(&self, ui: &UserInterface, target: Handle<UiNode>) -> Vector2<f32> {
|
||||
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<UiNode>) -> Vector2<f32> {
|
||||
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<UiNode>) -> Vector2<f32> {
|
||||
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<UiNode>) -> Vector2<f32> {
|
||||
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())
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ impl ScrollPanel {
|
||||
children_size
|
||||
}
|
||||
fn bring_into_view(&self, ui: &UserInterface, handle: Handle<UiNode>) {
|
||||
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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ pub trait UserInterfaceTestingExtension {
|
||||
}
|
||||
|
||||
fn is_enabled(mut handle: Handle<UiNode>, 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:?}");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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::<Tree>(handle) {
|
||||
if let Ok(tree_ref) = ui.try_get_of_type::<Tree>(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::<Tree>())
|
||||
{
|
||||
if let Ok(item) = ui.try_get_of_type::<Tree>(*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::<Tree>())
|
||||
else {
|
||||
let Ok(item) = ui.try_get_of_type::<Tree>(*selected_item) else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
@@ -1197,7 +1197,7 @@ impl Widget {
|
||||
) -> Handle<UiNode> {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -703,7 +703,7 @@ impl Control for Window {
|
||||
font,
|
||||
font_size,
|
||||
} => {
|
||||
if ui.try_get_of_type::<Text>(self.title).is_some() {
|
||||
if ui.try_get_of_type::<Text>(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()));
|
||||
|
||||
Reference in New Issue
Block a user