From 29113b58e0cb79d81cd897658b1aa8d74bad0001 Mon Sep 17 00:00:00 2001 From: Dmitry Stepanov Date: Fri, 1 Nov 2024 11:50:29 +0300 Subject: [PATCH] changed `traverse_iter` to return a pair of handle and ref - much more convenient when there's a need to handle a handle with a reference at the same time, no need to do re-borrow which is double work anyway --- editor/src/camera/mod.rs | 2 +- editor/src/highlight.rs | 9 +++--- editor/src/scene/dialog.rs | 3 +- editor/src/scene/mod.rs | 9 +++--- fyrox-graph/src/lib.rs | 41 ++++---------------------- fyrox-impl/src/scene/animation/absm.rs | 7 ++++- fyrox-impl/src/scene/graph/mod.rs | 4 +-- fyrox-impl/src/scene/mesh/mod.rs | 3 +- fyrox-ui/src/inspector/mod.rs | 5 ++-- fyrox-ui/src/navigation.rs | 8 ++--- 10 files changed, 31 insertions(+), 60 deletions(-) diff --git a/editor/src/camera/mod.rs b/editor/src/camera/mod.rs index ae835ceac..405cafa2c 100644 --- a/editor/src/camera/mod.rs +++ b/editor/src/camera/mod.rs @@ -245,7 +245,7 @@ impl CameraController { pub fn fit_object(&mut self, scene: &mut Scene, handle: Handle) { // Combine AABBs from the descendants. let mut aabb = AxisAlignedBoundingBox::default(); - for descendant in scene.graph.traverse_iter(handle) { + for (_, descendant) in scene.graph.traverse_iter(handle) { let descendant_aabb = descendant.local_bounding_box(); if !descendant_aabb.is_invalid_or_degenerate() { aabb.add_box(descendant_aabb.transform(&descendant.global_transform())) diff --git a/editor/src/highlight.rs b/editor/src/highlight.rs index 97e774973..6b7301303 100644 --- a/editor/src/highlight.rs +++ b/editor/src/highlight.rs @@ -22,7 +22,7 @@ use crate::{ fyrox::{ core::{color::Color, pool::Handle, sstorage::ImmutableString}, fxhash::FxHashSet, - graph::{BaseSceneGraph, SceneGraph}, + graph::BaseSceneGraph, renderer::{ bundle::{BundleRenderContext, ObserverInfo, RenderContext, RenderDataBundleStorage}, framework::{ @@ -46,6 +46,7 @@ use crate::{ }, Editor, }; +use fyrox::graph::SceneGraph; use std::{any::TypeId, cell::RefCell, rc::Rc}; struct EdgeDetectShader { @@ -213,10 +214,8 @@ impl SceneRenderPass for HighlightRenderPass { for &root_node_handle in self.nodes_to_highlight.iter() { if ctx.scene.graph.is_valid_handle(root_node_handle) { - for node_handle in ctx.scene.graph.traverse_handle_iter(root_node_handle) { - if let Some(node) = ctx.scene.graph.try_get(node_handle) { - node.collect_render_data(&mut render_context); - } + for (_, node) in ctx.scene.graph.traverse_iter(root_node_handle) { + node.collect_render_data(&mut render_context); } } } diff --git a/editor/src/scene/dialog.rs b/editor/src/scene/dialog.rs index c91a9eb3e..3b34f3ffc 100644 --- a/editor/src/scene/dialog.rs +++ b/editor/src/scene/dialog.rs @@ -159,8 +159,7 @@ impl NodeRemovalDialog { let selection = selection_to_delete(editor_selection, game_scene); for root in selection.nodes.iter() { - for node_handle in graph.traverse_handle_iter(*root) { - let node = &graph[node_handle]; + for (node_handle, node) in graph.traverse_iter(*root) { for reference_handle in graph.find_references_to(node_handle) { let reference = &graph[reference_handle]; text += &format!( diff --git a/editor/src/scene/mod.rs b/editor/src/scene/mod.rs index 7c686dc92..638834723 100644 --- a/editor/src/scene/mod.rs +++ b/editor/src/scene/mod.rs @@ -420,8 +420,8 @@ impl GameScene { ) -> bool { if let Some(selection) = editor_selection.as_graph() { for node in selection.nodes() { - for descendant in graph.traverse_handle_iter(*node) { - for reference in graph.find_references_to(descendant) { + for (descendant_handle, _) in graph.traverse_iter(*node) { + for reference in graph.find_references_to(descendant_handle) { if !selection.contains(reference) { return true; } @@ -611,7 +611,8 @@ impl SceneController for GameScene { let nodes = scene .graph - .traverse_handle_iter(instance) + .traverse_iter(instance) + .map(|(handle, _)| handle) .collect::>>(); self.preview_instance = Some(PreviewInstance { instance, nodes }); @@ -912,7 +913,7 @@ impl SceneController for GameScene { } let node_overrides = self.graph_switches.node_overrides.as_mut().unwrap(); - for handle in scene.graph.traverse_handle_iter(self.editor_objects_root) { + for (handle, _) in scene.graph.traverse_iter(self.editor_objects_root) { node_overrides.insert(handle); } diff --git a/fyrox-graph/src/lib.rs b/fyrox-graph/src/lib.rs index b9d3a0f42..d6e19dea3 100644 --- a/fyrox-graph/src/lib.rs +++ b/fyrox-graph/src/lib.rs @@ -981,7 +981,7 @@ pub trait SceneGraph: BaseSceneGraph { fn traverse_iter( &self, from: Handle, - ) -> GraphTraverseIterator<'_, Self, Self::Node> { + ) -> impl Iterator, &Self::Node)> { GraphTraverseIterator { graph: self, stack: vec![from], @@ -993,11 +993,8 @@ pub trait SceneGraph: BaseSceneGraph { fn traverse_handle_iter( &self, from: Handle, - ) -> GraphHandleTraverseIterator<'_, Self, Self::Node> { - GraphHandleTraverseIterator { - graph: self, - stack: vec![from], - } + ) -> impl Iterator> { + self.traverse_iter(from).map(|(handle, _)| handle) } /// This method checks integrity of the graph and restores it if needed. For example, if a node @@ -1034,7 +1031,7 @@ pub trait SceneGraph: BaseSceneGraph { for (instance_root, resource) in instances.iter().cloned() { // Step 1. Find and remove orphaned nodes. let mut nodes_to_delete = Vec::new(); - for node in self.traverse_iter(instance_root) { + for (_, node) in self.traverse_iter(instance_root) { if let Some(resource) = node.resource() { let kind = resource.kind().clone(); if let Some(model) = resource.state().data() { @@ -1318,7 +1315,7 @@ where G: SceneGraph, N: SceneGraphNode, { - type Item = &'a N; + type Item = (Handle, &'a N); #[inline] fn next(&mut self) -> Option { @@ -1329,39 +1326,13 @@ where self.stack.push(*child_handle); } - return Some(node); + return Some((handle, node)); } None } } -/// Iterator that traverses tree in depth and returns handles to nodes. -pub struct GraphHandleTraverseIterator<'a, G: ?Sized, N> { - graph: &'a G, - stack: Vec>, -} - -impl<'a, G, N> Iterator for GraphHandleTraverseIterator<'a, G, N> -where - G: SceneGraph, - N: SceneGraphNode, -{ - type Item = Handle; - - #[inline] - fn next(&mut self) -> Option { - if let Some(handle) = self.stack.pop() { - for child_handle in self.graph.node(handle).children() { - self.stack.push(*child_handle); - } - - return Some(handle); - } - None - } -} - #[cfg(test)] mod test { use crate::{ diff --git a/fyrox-impl/src/scene/animation/absm.rs b/fyrox-impl/src/scene/animation/absm.rs index e57b93df6..e281142af 100644 --- a/fyrox-impl/src/scene/animation/absm.rs +++ b/fyrox-impl/src/scene/animation/absm.rs @@ -125,7 +125,12 @@ pub trait LayerMaskExt { impl LayerMaskExt for LayerMask { fn from_hierarchy(graph: &Graph, root: Handle) -> Self { - Self::from(graph.traverse_handle_iter(root).collect::>()) + Self::from( + graph + .traverse_iter(root) + .map(|(handle, _)| handle) + .collect::>(), + ) } } diff --git a/fyrox-impl/src/scene/graph/mod.rs b/fyrox-impl/src/scene/graph/mod.rs index 8a54d5d3e..498c9f2f2 100644 --- a/fyrox-impl/src/scene/graph/mod.rs +++ b/fyrox-impl/src/scene/graph/mod.rs @@ -556,8 +556,8 @@ impl Graph { let mut old_new_mapping = NodeHandleMap::default(); let to_copy = self - .traverse_handle_iter(node_handle) - .map(|node| (node, self.pool[node].children.clone())) + .traverse_iter(node_handle) + .map(|(descendant_handle, descendant)| (descendant_handle, descendant.children.clone())) .collect::>(); let mut root_handle = Handle::NONE; diff --git a/fyrox-impl/src/scene/mesh/mod.rs b/fyrox-impl/src/scene/mesh/mod.rs index 30d15c822..06ee7448c 100644 --- a/fyrox-impl/src/scene/mesh/mod.rs +++ b/fyrox-impl/src/scene/mesh/mod.rs @@ -165,12 +165,11 @@ struct BatchContainer { impl BatchContainer { fn fill(&mut self, from: Handle, ctx: &mut RenderContext) { - for descendant_handle in ctx.graph.traverse_handle_iter(from) { + for (descendant_handle, descendant) in ctx.graph.traverse_iter(from) { if descendant_handle == from { continue; } - let descendant = &ctx.graph[descendant_handle]; descendant.collect_render_data(&mut RenderContext { observer_info: ctx.observer_info, frustum: None, diff --git a/fyrox-ui/src/inspector/mod.rs b/fyrox-ui/src/inspector/mod.rs index d12d03401..6da7f5f85 100644 --- a/fyrox-ui/src/inspector/mod.rs +++ b/fyrox-ui/src/inspector/mod.rs @@ -783,10 +783,9 @@ impl PropertyFilter { fn assign_tab_indices(container: Handle, ui: &mut UserInterface) { let mut counter = 0; let mut widgets_list = Vec::new(); - for descendant in ui.traverse_handle_iter(container) { - let descendant_ref = ui.node(descendant); + for (descendant_handle, descendant_ref) in ui.traverse_iter(container) { if descendant_ref.accepts_input { - widgets_list.push((descendant, counter)); + widgets_list.push((descendant_handle, counter)); counter += 1; } } diff --git a/fyrox-ui/src/navigation.rs b/fyrox-ui/src/navigation.rs index d6554d6f6..2078e1c4b 100644 --- a/fyrox-ui/src/navigation.rs +++ b/fyrox-ui/src/navigation.rs @@ -33,7 +33,7 @@ use crate::{ widget::{Widget, WidgetBuilder, WidgetMessage}, BuildContext, Control, UiNode, UserInterface, }; -use fyrox_graph::{BaseSceneGraph, SceneGraph}; +use fyrox_graph::SceneGraph; use std::ops::{Deref, DerefMut}; /// A widget, that handles keyboard navigation on its descendant widgets using Tab key. It should @@ -104,14 +104,12 @@ impl Control for NavigationLayer { // Collect all descendant widgets, that supports Tab navigation. let mut tab_list = Vec::new(); for &child in self.children() { - for descendant in ui.traverse_handle_iter(child) { - let descendant_ref = ui.node(descendant); - + for (descendant_handle, descendant_ref) in ui.traverse_iter(child) { if !*descendant_ref.tab_stop && descendant_ref.is_globally_visible() { if let Some(tab_index) = *descendant_ref.tab_index { tab_list.push(OrderedHandle { tab_index, - handle: descendant, + handle: descendant_handle, }); } }