diff --git a/tests/focus.rs b/tests/focus.rs index b2bc8e8af..ac547046f 100644 --- a/tests/focus.rs +++ b/tests/focus.rs @@ -1218,7 +1218,6 @@ pub fn focus_goes_to_parent_after_remove() { assert_eq!(Some(child_id), app.focused()); app.take_focus_changed(); - println!("!!: JUST BEFORE INTERACTIVE BLOCKED"); app.set_vars(|vars| { interactive.set(vars, false); }); diff --git a/zero-ui-core/src/focus.rs b/zero-ui-core/src/focus.rs index 8154b75b4..f2b1ce7e1 100644 --- a/zero-ui-core/src/focus.rs +++ b/zero-ui-core/src/focus.rs @@ -1443,7 +1443,6 @@ trait EnabledNavWithFrameExt { impl<'a> EnabledNavWithFrameExt for WidgetFocusInfo<'a> { fn enabled_nav_with_frame(self) -> EnabledNavWithFrame { let stats = self.info.tree().stats(); - println!("!!: ENABLED_NAV, {:?}", stats.last_frame); EnabledNavWithFrame { nav: self.enabled_nav(), spatial_frame_id: stats.bounds_updated_frame, diff --git a/zero-ui-core/src/focus/focus_info.rs b/zero-ui-core/src/focus/focus_info.rs index 53d6bb001..69880f6ea 100644 --- a/zero-ui-core/src/focus/focus_info.rs +++ b/zero-ui-core/src/focus/focus_info.rs @@ -651,13 +651,13 @@ impl<'a> WidgetFocusInfo<'a> { } /// Iterator over the focusable widgets contained by this widget. - pub fn descendants(self) -> super::iter::FocusableDescendants<'a, iter::TreeIter<'a>> { - super::iter::FocusableDescendants::new(self.info.descendants(), self.focus_disabled_widgets()) + pub fn descendants(self) -> super::iter::FocusTreeIter<'a, iter::TreeIter<'a>> { + super::iter::FocusTreeIter::new(self.info.descendants(), self.focus_disabled_widgets()) } /// Iterator over self and the focusable widgets contained by it. - pub fn self_and_descendants(self) -> super::iter::FocusableDescendants<'a, iter::TreeIter<'a>> { - super::iter::FocusableDescendants::new(self.info.self_and_descendants(), self.focus_disabled_widgets()) + pub fn self_and_descendants(self) -> super::iter::FocusTreeIter<'a, iter::TreeIter<'a>> { + super::iter::FocusTreeIter::new(self.info.self_and_descendants(), self.focus_disabled_widgets()) } /// If the focusable has any focusable descendant that is not [`TabIndex::SKIP`] @@ -688,7 +688,7 @@ impl<'a> WidgetFocusInfo<'a> { pub fn last_tab_descendant(self) -> Option> { let mut best = (-1i64, self); - for d in self.descendants().tree_filter(Self::filter_tab_skip).rev() { + for d in self.descendants().tree_rev().tree_filter(Self::filter_tab_skip) { let idx = d.focus_info().tab_index().0 as i64; if idx > best.0 { @@ -704,12 +704,12 @@ impl<'a> WidgetFocusInfo<'a> { } /// Iterator over all focusable widgets in the same scope after this widget. - pub fn next_focusables(self) -> super::iter::FocusableDescendants<'a, iter::TreeIter<'a>> { + pub fn next_focusables(self) -> super::iter::FocusTreeIter<'a, iter::TreeIter<'a>> { if let Some(scope) = self.scope() { - super::iter::FocusableDescendants::new(self.info.next_siblings_in(scope.info), self.focus_disabled_widgets()) + super::iter::FocusTreeIter::new(self.info.next_siblings_in(scope.info), self.focus_disabled_widgets()) } else { // empty - super::iter::FocusableDescendants::new(self.info.next_siblings_in(self.info), self.focus_disabled_widgets()) + super::iter::FocusTreeIter::new(self.info.next_siblings_in(self.info), self.focus_disabled_widgets()) } } @@ -791,12 +791,12 @@ impl<'a> WidgetFocusInfo<'a> { } /// Iterator over all focusable widgets in the same scope before this widget in reverse. - pub fn prev_focusables(self) -> super::iter::FocusableDescendants<'a, iter::RevTreeIter<'a, iter::TreeIter<'a>>> { + pub fn prev_focusables(self) -> super::iter::FocusTreeIter<'a, iter::RevTreeIter<'a>> { if let Some(scope) = self.scope() { - super::iter::FocusableDescendants::new(self.info.prev_siblings_in(scope.info), self.focus_disabled_widgets()) + super::iter::FocusTreeIter::new(self.info.prev_siblings_in(scope.info), self.focus_disabled_widgets()) } else { // empty - super::iter::FocusableDescendants::new(self.info.prev_siblings_in(self.info), self.focus_disabled_widgets()) + super::iter::FocusTreeIter::new(self.info.prev_siblings_in(self.info), self.focus_disabled_widgets()) } } @@ -825,7 +825,7 @@ impl<'a> WidgetFocusInfo<'a> { let mut best = (-1i64, self); if !skip_self { - for d in self.descendants().tree_filter(Self::filter_tab_skip).rev() { + for d in self.descendants().tree_rev().tree_filter(Self::filter_tab_skip) { let idx = d.focus_info().tab_index().0 as i64; if idx == self_index { diff --git a/zero-ui-core/src/focus/iter.rs b/zero-ui-core/src/focus/iter.rs index 4c929e9a1..61c8f8645 100644 --- a/zero-ui-core/src/focus/iter.rs +++ b/zero-ui-core/src/focus/iter.rs @@ -74,7 +74,7 @@ where /// /// [`descendants`]: WidgetFocusInfo::descendants /// [`self_and_descendants`]: WidgetFocusInfo::self_and_descendants -pub struct FocusableDescendants<'a, I> +pub struct FocusTreeIter<'a, I> where I: TreeIterator<'a>, { @@ -82,7 +82,7 @@ where iter: I, focus_disabled_widgets: bool, } -impl<'a, I> FocusableDescendants<'a, I> +impl<'a, I> FocusTreeIter<'a, I> where I: TreeIterator<'a>, { @@ -99,11 +99,11 @@ where /// Note that you can convert `bool` into [`TreeFilter`] to use this method just like the iterator default. /// /// [`TreeFilter`]: w_iter::TreeFilter - pub fn tree_filter(self, mut filter: F) -> FocusableFilterDescendants<'a, I, impl FnMut(WidgetInfo<'a>) -> w_iter::TreeFilter> + pub fn tree_filter(self, mut filter: F) -> FocusTreeFilterIter<'a, I, impl FnMut(WidgetInfo<'a>) -> w_iter::TreeFilter> where F: FnMut(WidgetFocusInfo<'a>) -> w_iter::TreeFilter, { - FocusableFilterDescendants { + FocusTreeFilterIter { iter: self.iter.tree_filter(move |w| { if let Some(f) = w.as_focusable(self.focus_disabled_widgets) { filter(f) @@ -140,7 +140,14 @@ where self.tree_find(filter).is_some() } } -impl<'a, I> Iterator for FocusableDescendants<'a, I> +impl<'a> FocusTreeIter<'a, w_iter::TreeIter<'a>> { + /// Creates a reverse tree iterator. + pub fn tree_rev(self) -> FocusTreeIter<'a, w_iter::RevTreeIter<'a>> { + FocusTreeIter::new(self.iter.tree_rev(), self.focus_disabled_widgets) + } +} + +impl<'a, I> Iterator for FocusTreeIter<'a, I> where I: TreeIterator<'a>, { @@ -155,24 +162,11 @@ where None } } -impl<'a, I> DoubleEndedIterator for FocusableDescendants<'a, I> -where - I: TreeIterator<'a>, -{ - fn next_back(&mut self) -> Option { - while let Some(next) = self.iter.next_back() { - if let Some(next) = next.as_focusable(self.focus_disabled_widgets) { - return Some(next); - } - } - None - } -} /// An iterator that filters a focusable widget tree. /// -/// This `struct` is created by the [`FocusableDescendants::tree_filter`] method. See its documentation for more. -pub struct FocusableFilterDescendants<'a, I, F> +/// This `struct` is created by the [`FocusTreeIter::tree_filter`] method. See its documentation for more. +pub struct FocusTreeFilterIter<'a, I, F> where I: TreeIterator<'a>, F: FnMut(WidgetInfo<'a>) -> w_iter::TreeFilter, @@ -180,7 +174,7 @@ where iter: w_iter::TreeFilterIter<'a, I, F>, focus_disabled_widgets: bool, } -impl<'a, I, F> Iterator for FocusableFilterDescendants<'a, I, F> +impl<'a, I, F> Iterator for FocusTreeFilterIter<'a, I, F> where F: FnMut(WidgetInfo<'a>) -> w_iter::TreeFilter, I: TreeIterator<'a>, @@ -191,12 +185,3 @@ where self.iter.next().map(|w| w.as_focus_info(self.focus_disabled_widgets)) } } -impl<'a, I, F> DoubleEndedIterator for FocusableFilterDescendants<'a, I, F> -where - F: FnMut(WidgetInfo<'a>) -> w_iter::TreeFilter, - I: TreeIterator<'a>, -{ - fn next_back(&mut self) -> Option { - self.iter.next_back().map(|w| w.as_focus_info(self.focus_disabled_widgets)) - } -} diff --git a/zero-ui-core/src/widget_info.rs b/zero-ui-core/src/widget_info.rs index 71853f5b6..cbf133fdf 100644 --- a/zero-ui-core/src/widget_info.rs +++ b/zero-ui-core/src/widget_info.rs @@ -1400,7 +1400,6 @@ impl<'a> WidgetInfo<'a> { pub fn descendants(self) -> iter::TreeIter<'a> { let mut d = self.self_and_descendants(); d.next(); - d.next_back(); d } @@ -1473,7 +1472,7 @@ impl<'a> WidgetInfo<'a> { /// Iterator over all previous widgets within the same `ancestor`, including descendants of siblings. /// /// If `ancestor` is not actually an ancestor iterates to the root. - pub fn prev_siblings_in(self, ancestor: WidgetInfo<'a>) -> iter::RevTreeIter<'a, iter::TreeIter<'a>> { + pub fn prev_siblings_in(self, ancestor: WidgetInfo<'a>) -> iter::RevTreeIter<'a> { let mut r = self.self_and_prev_siblings_in(ancestor); r.next(); r @@ -1482,7 +1481,7 @@ impl<'a> WidgetInfo<'a> { /// Iterator over self, descendants and all previous widgets within the same `ancestor`. /// /// If `ancestor` is not actually an ancestor iterates to the root. - pub fn self_and_prev_siblings_in(self, ancestor: WidgetInfo<'a>) -> iter::RevTreeIter<'a, iter::TreeIter<'a>> { + pub fn self_and_prev_siblings_in(self, ancestor: WidgetInfo<'a>) -> iter::RevTreeIter<'a> { iter::TreeIter::self_and_prev_siblings_in(self, ancestor) } diff --git a/zero-ui-core/src/widget_info/iter.rs b/zero-ui-core/src/widget_info/iter.rs index 5a9c53085..0525867a0 100644 --- a/zero-ui-core/src/widget_info/iter.rs +++ b/zero-ui-core/src/widget_info/iter.rs @@ -179,25 +179,12 @@ impl<'a> Iterator for Ancestors<'a> { mod internal { pub trait InternalTreeIterator { - fn skip_all(&mut self, widget: super::WidgetInfo, rev: bool); + fn skip_all(&mut self, widget: super::WidgetInfo); } } /// Iterator that traverses the branches of a widget tree. -pub trait TreeIterator<'a>: internal::InternalTreeIterator + Iterator> + DoubleEndedIterator + FusedIterator { - /// Reverse tree iterator direction. - /// - /// Yields the same widgets as [`Iterator::rev`], but is also a [`TreeIterator`] so can be filtered. - fn tree_rev(self) -> RevTreeIter<'a, Self> - where - Self: Sized, - { - RevTreeIter { - _lt: PhantomData, - iter: self, - } - } - +pub trait TreeIterator<'a>: internal::InternalTreeIterator + Iterator> + FusedIterator { /// Creates an iterator which uses a closure to filter items or branches at a time. /// /// See [`TreeFilter`] for details. @@ -242,10 +229,12 @@ impl<'a> TreeIter<'a> { } } - pub(super) fn self_and_prev_siblings_in(wgt: WidgetInfo<'a>, ancestor: WidgetInfo<'a>) -> RevTreeIter<'a, Self> { - let mut iter = ancestor.node().self_and_descendants(); - iter.skip_back_to(wgt.node_id, &wgt.tree.0.tree); - Self { tree: wgt.tree(), iter }.tree_rev() + pub(super) fn self_and_prev_siblings_in(wgt: WidgetInfo<'a>, ancestor: WidgetInfo<'a>) -> RevTreeIter<'a> { + let tree = &wgt.tree.0.tree; + let mut iter = ancestor.node().self_and_descendants().rev(tree); + iter.skip_to(tree, wgt.node_id); + + RevTreeIter { tree: wgt.tree, iter } } pub(super) fn self_and_next_siblings_in(wgt: WidgetInfo<'a>, ancestor: WidgetInfo<'a>) -> Self { @@ -253,14 +242,28 @@ impl<'a> TreeIter<'a> { iter.skip_to(wgt.node_id); Self { tree: wgt.tree(), iter } } + + /// Creates a reverse tree iterator. + /// + /// Yields widgets in the `parent -> last_child -> prev_sibling` order. The reverse iterator is pre-advanced by the same count + /// of widgets already yielded by this iterator. In practice this is best used immediatly after getting the iterator from + /// [`self_descendants`] or [`descendants`], with the intention of skipping to the last child from the starting widget. + /// + /// [`self_descendants`]: WidgetInfo::self_descendants + /// [`descendants`]: WidgetInfo::descendants + pub fn tree_rev(self) -> RevTreeIter<'a> + where + Self: Sized, + { + RevTreeIter { + tree: self.tree, + iter: self.iter.rev(&self.tree.0.tree), + } + } } impl<'a> internal::InternalTreeIterator for TreeIter<'a> { - fn skip_all(&mut self, widget: WidgetInfo, rev: bool) { - if rev { - self.iter.close_back(&self.tree.0.tree, widget.node_id) - } else { - self.iter.close(&self.tree.0.tree, widget.node_id) - } + fn skip_all(&mut self, widget: WidgetInfo) { + self.iter.close(&self.tree.0.tree, widget.node_id) } } impl<'a> Iterator for TreeIter<'a> { @@ -275,11 +278,6 @@ impl<'a> Iterator for TreeIter<'a> { (len, Some(len)) } } -impl<'a> DoubleEndedIterator for TreeIter<'a> { - fn next_back(&mut self) -> Option { - self.iter.next_back(&self.tree.0.tree).map(|id| WidgetInfo::new(self.tree, id)) - } -} impl<'a> ExactSizeIterator for TreeIter<'a> { fn len(&self) -> usize { self.iter.len() @@ -291,50 +289,24 @@ impl<'a> TreeIterator<'a> for TreeIter<'a> {} /// Reversing tree iterator. /// /// This struct is created by the [`TreeIterator::tree_rev`] method. -pub struct RevTreeIter<'a, I: TreeIterator<'a>> { - _lt: PhantomData<&'a WidgetInfoTree>, - iter: I, +pub struct RevTreeIter<'a> { + tree: &'a WidgetInfoTree, + iter: tree::RevTreeIter, } -impl<'a, I> internal::InternalTreeIterator for RevTreeIter<'a, I> -where - I: TreeIterator<'a>, -{ - fn skip_all(&mut self, widget: WidgetInfo, rev: bool) { - self.iter.skip_all(widget, !rev) +impl<'a> internal::InternalTreeIterator for RevTreeIter<'a> { + fn skip_all(&mut self, widget: WidgetInfo) { + self.iter.close(&self.tree.0.tree, widget.node_id); } } -impl<'a, I> Iterator for RevTreeIter<'a, I> -where - I: TreeIterator<'a>, -{ +impl<'a> Iterator for RevTreeIter<'a> { type Item = WidgetInfo<'a>; fn next(&mut self) -> Option { - self.iter.next_back() - } - - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() + self.iter.next(&self.tree.0.tree).map(|id| WidgetInfo::new(self.tree, id)) } } -impl<'a, I> DoubleEndedIterator for RevTreeIter<'a, I> -where - I: TreeIterator<'a>, -{ - fn next_back(&mut self) -> Option { - self.iter.next() - } -} -impl<'a, I> ExactSizeIterator for RevTreeIter<'a, I> -where - I: TreeIterator<'a> + ExactSizeIterator, -{ - fn len(&self) -> usize { - self.iter.len() - } -} -impl<'a, I> FusedIterator for RevTreeIter<'a, I> where I: TreeIterator<'a> {} -impl<'a, I> TreeIterator<'a> for RevTreeIter<'a, I> where I: TreeIterator<'a> {} +impl<'a> FusedIterator for RevTreeIter<'a> {} +impl<'a> TreeIterator<'a> for RevTreeIter<'a> {} /// Filtering tree iterator. /// @@ -345,8 +317,8 @@ pub struct TreeFilterIter<'a, I: TreeIterator<'a>, F: FnMut(WidgetInfo<'a>) -> T filter: F, } impl<'a, I: TreeIterator<'a>, F: FnMut(WidgetInfo<'a>) -> TreeFilter> internal::InternalTreeIterator for TreeFilterIter<'a, I, F> { - fn skip_all(&mut self, widget: WidgetInfo, rev: bool) { - self.iter.skip_all(widget, rev) + fn skip_all(&mut self, widget: WidgetInfo) { + self.iter.skip_all(widget) } } impl<'a, I, F> Iterator for TreeFilterIter<'a, I, F> @@ -363,36 +335,11 @@ where TreeFilter::Include => return Some(wgt), TreeFilter::Skip => continue, TreeFilter::SkipAll => { - self.iter.skip_all(wgt, false); + self.iter.skip_all(wgt); continue; } TreeFilter::SkipDescendants => { - self.iter.skip_all(wgt, false); - return Some(wgt); - } - }, - None => return None, - } - } - } -} -impl<'a, I, F> DoubleEndedIterator for TreeFilterIter<'a, I, F> -where - I: TreeIterator<'a>, - F: FnMut(WidgetInfo<'a>) -> TreeFilter, -{ - fn next_back(&mut self) -> Option { - loop { - match self.iter.next_back() { - Some(wgt) => match (self.filter)(wgt) { - TreeFilter::Include => return Some(wgt), - TreeFilter::Skip => continue, - TreeFilter::SkipAll => { - self.iter.skip_all(wgt, true); - continue; - } - TreeFilter::SkipDescendants => { - self.iter.skip_all(wgt, true); + self.iter.skip_all(wgt); return Some(wgt); } }, @@ -500,8 +447,8 @@ mod tests { let result: Vec<_> = tree .root() .descendants() - .tree_filter(|_| TreeFilter::Include) .tree_rev() + .tree_filter(|_| TreeFilter::Include) .map(|w| w.test_name()) .collect(); @@ -547,8 +494,8 @@ mod tests { let result: Vec<_> = tree .root() .self_and_descendants() - .tree_filter(|_| TreeFilter::Include) .tree_rev() + .tree_filter(|_| TreeFilter::Include) .map(|w| w.test_name()) .collect(); @@ -564,19 +511,19 @@ mod tests { let result: Vec<_> = iter.tree_rev().map(|w| w.test_name()).collect(); - assert_eq!(result, vec!["c-2", "c-1"]); + assert_eq!(result, vec!["c-1", "c-0"]); } #[test] fn descendants_double_filter_noop() { let tree = data(); - let mut iter = tree.root().descendants().tree_filter(|_| TreeFilter::Include); + let mut iter = tree.root().descendants().tree_rev().tree_filter(|_| TreeFilter::Include); - assert_eq!(iter.next().map(|w| w.test_name()), Some("c-0")); + assert_eq!(iter.next().map(|w| w.test_name()), Some("c-2")); - let result: Vec<_> = iter.tree_rev().map(|w| w.test_name()).collect(); + let result: Vec<_> = iter.map(|w| w.test_name()).collect(); - assert_eq!(result, vec!["c-2", "c-1"]); + assert_eq!(result, vec!["c-1", "c-0"]); } fn data_nested() -> WidgetInfoTree { @@ -680,7 +627,7 @@ mod tests { assert_eq!( result, vec![ - "c-2", "c-2-2", "c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1", + "c-2-2", "c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1", "c-0-0", ] ); @@ -698,7 +645,7 @@ mod tests { assert_eq!( result, - vec!["c-2", "c-2-2", "c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1"] + vec!["c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1", "c-0-0"] ); } @@ -805,6 +752,7 @@ mod tests { let result: Vec<_> = tree .root() .descendants() + .tree_rev() .tree_filter(|w| { if w.widget_id() == WidgetId::named("c-1") { TreeFilter::Skip @@ -812,7 +760,6 @@ mod tests { TreeFilter::Include } }) - .tree_rev() .map(|w| w.test_name()) .collect(); @@ -858,6 +805,7 @@ mod tests { let result: Vec<_> = tree .root() .descendants() + .tree_rev() .tree_filter(|w| { if w.widget_id() == WidgetId::named("c-1") { TreeFilter::SkipAll @@ -865,7 +813,6 @@ mod tests { TreeFilter::Include } }) - .tree_rev() .map(|w| w.test_name()) .collect(); @@ -911,6 +858,7 @@ mod tests { let result: Vec<_> = tree .root() .descendants() + .tree_rev() .tree_filter(|w| { if w.widget_id() == WidgetId::named("c-1") { TreeFilter::SkipDescendants @@ -918,7 +866,6 @@ mod tests { TreeFilter::Include } }) - .tree_rev() .map(|w| w.test_name()) .collect(); diff --git a/zero-ui-core/src/widget_info/tree.rs b/zero-ui-core/src/widget_info/tree.rs index 64b64826a..9467c63cd 100644 --- a/zero-ui-core/src/widget_info/tree.rs +++ b/zero-ui-core/src/widget_info/tree.rs @@ -184,10 +184,9 @@ impl<'a, T> NodeRef<'a, T> { pub fn self_and_descendants(self) -> TreeIter { let node = self.id.get(); TreeIter { + node, next: node, - next_back: node, end: self.tree.nodes[self.id.get()].descendants_end as usize, - back_advance: 0, } } @@ -271,11 +270,10 @@ impl<'a, T> NodeMut<'a, T> { } pub(super) struct TreeIter { + node: usize, // used for creating reverse iterator. + next: usize, end: usize, - - next_back: usize, - back_advance: usize, // number of nodes back entered } impl TreeIter { /// for a tree (a(a.a, a.b, a.c), b) @@ -290,50 +288,6 @@ impl TreeIter { } } - /// for a tree (a(a.a, a.b, a.c), b) - /// yield [b, a, a.c, a.b, a.a] - pub fn next_back(&mut self, tree: &Tree) -> Option { - if self.next < self.end { - let next = NodeId::new(self.next_back); - - let node = &tree.nodes[self.next_back]; - if let Some(last_child) = node.last_child { - self.next_back = last_child.get(); - self.back_advance += 1; - } else if let Some(prev_sibling) = node.prev_sibling { - self.next_back = prev_sibling.get(); - self.end -= 1; - } else { - let mut node = node; - while self.next < self.end { - if let Some(parent) = node.parent { - self.end -= 1; - if self.end == self.next { - self.back_advance = 0; - break; - } - - self.back_advance -= 1; - node = &tree.nodes[parent.get()]; - if let Some(prev_sibling) = node.prev_sibling { - self.next_back = prev_sibling.get(); - self.end -= 1; - break; - } - } else { - self.end = self.next; - self.back_advance = 0; - break; - } - } - } - - Some(next) - } else { - None - } - } - /// Skip to the next sibling of the node last yielded by `next`. pub fn close(&mut self, tree: &Tree, yielded: NodeId) { let node = &tree.nodes[yielded.get()]; @@ -347,30 +301,6 @@ impl TreeIter { } } - /// Skip to the prev sibling of the node last yielded by `next_back`. - pub fn close_back(&mut self, tree: &Tree, yielded: NodeId) { - let node = &tree.nodes[yielded.get()]; - if let Some(prev_sibling) = node.prev_sibling { - self.next_back = prev_sibling.get(); - self.end = tree.nodes[self.next_back].descendants_end as usize; - } else { - let mut node = node; - while let Some(parent) = node.parent { - node = &tree.nodes[parent.get()]; - self.back_advance -= 1; - if let Some(prev_sibling) = node.prev_sibling { - self.next_back = self.next.max(prev_sibling.get() as usize); - self.end = tree.nodes[prev_sibling.get()].descendants_end as usize; - return; - } - } - - // else - self.end = self.next; - self.next_back = self.next; - } - } - pub fn skip_to(&mut self, node: NodeId) { let node = node.get() as usize; if node > self.next { @@ -382,32 +312,107 @@ impl TreeIter { } } - pub fn skip_back_to(&mut self, node: NodeId, tree: &Tree) { - let node = node.get() as usize; - if node > self.next { - if node > self.end { - self.end = self.next; - self.back_advance = 0; + pub fn len(&self) -> usize { + self.end - self.next + } + + pub fn rev(self, tree: &Tree) -> RevTreeIter { + let mut count = self.next - self.node; + + let mut iter = RevTreeIter { + next: self.node, + end: self.node, + started: false, + }; + + while count > 0 { + count -= 1; + iter.next(tree); + } + + iter + } +} + +pub(super) struct RevTreeIter { + next: usize, + end: usize, + started: bool, +} +impl RevTreeIter { + /// for a tree (a(a.a, a.b, a.c), b) + /// yield [b, a, a.c, a.b, a.a] + pub fn next(&mut self, tree: &Tree) -> Option { + if self.next != self.end || !self.started { + self.started = true; + + let next = NodeId::new(self.next); + let node = &tree.nodes[self.next]; + + if let Some(last_child) = node.last_child { + self.next = last_child.get(); + } else if let Some(prev) = node.prev_sibling { + self.next = prev.get(); } else { - let node_ref = &tree.nodes[node]; - let mut exit = node_ref; - self.back_advance = 0; - while let Some(p) = exit.parent { - self.back_advance += 1; - exit = &tree.nodes[p.get()]; - if exit.descendants_end as usize >= self.end { + let mut node = node; + while let Some(parent) = node.parent { + let parent = parent.get(); + if parent == self.end { + self.next = self.end; + break; + } + + node = &tree.nodes[parent]; + + if let Some(prev) = node.prev_sibling { + self.next = prev.get(); break; } } + } - self.end = node_ref.descendants_end as usize; - self.next_back = node; + Some(next) + } else { + None + } + } + + /// Skip to the next sibling of the node last yielded by `next`. + pub fn close(&mut self, tree: &Tree, yielded: NodeId) { + let mut node = &tree.nodes[yielded.get()]; + + if let Some(prev) = node.prev_sibling { + self.next = prev.get(); + } else { + while let Some(parent) = node.parent { + let parent = parent.get(); + + if parent == self.end { + self.next = self.end; + break; + } + + node = &tree.nodes[parent]; + + if let Some(prev) = node.prev_sibling { + self.next = prev.get(); + break; + } } } } - pub fn len(&self) -> usize { - self.end - self.next + self.back_advance + pub fn skip_to(&mut self, tree: &Tree, node: NodeId) { + let node = node.get(); + if node > self.end { + let root = &tree.nodes[self.end]; + if node >= root.descendants_end as usize { + self.next = self.end; + } else { + self.next = node; + self.started = true; + } + } } } @@ -445,12 +450,12 @@ mod tests { } #[test] - fn iter_prev() { + fn iter_rev() { let tree = iter_tree(); - let mut iter = tree.root().self_and_descendants(); + let mut iter = tree.root().self_and_descendants().rev(&tree); let mut r = vec![]; - while let Some(id) = iter.next_back(&tree) { + while let Some(id) = iter.next(&tree) { r.push(*tree.index(id).value()); } @@ -458,7 +463,7 @@ mod tests { } #[test] - fn iter_next_not_root() { + fn iter_not_root() { let tree = iter_tree(); let mut iter = tree.root().first_child().unwrap().self_and_descendants(); @@ -471,12 +476,12 @@ mod tests { } #[test] - fn iter_prev_not_root() { + fn iter_rev_not_root() { let tree = iter_tree(); - let mut iter = tree.root().first_child().unwrap().self_and_descendants(); + let mut iter = tree.root().first_child().unwrap().self_and_descendants().rev(&tree); let mut r = vec![]; - while let Some(id) = iter.next_back(&tree) { + while let Some(id) = iter.next(&tree) { r.push(*tree.index(id).value()); } @@ -484,11 +489,10 @@ mod tests { } #[test] - fn iter_next_descendants() { + fn iter_descendants() { let tree = iter_tree(); let mut iter = tree.root().first_child().unwrap().self_and_descendants(); iter.next(); - iter.next_back(&tree); let mut r = vec![]; while let Some(id) = iter.next() { @@ -499,14 +503,13 @@ mod tests { } #[test] - fn iter_prev_descendants() { + fn iter_rev_descendants() { let tree = iter_tree(); - let mut iter = tree.root().first_child().unwrap().self_and_descendants(); - iter.next(); - iter.next_back(&tree); + let mut iter = tree.root().first_child().unwrap().self_and_descendants().rev(&tree); + iter.next(&tree); let mut r = vec![]; - while let Some(id) = iter.next_back(&tree) { + while let Some(id) = iter.next(&tree) { r.push(*tree.index(id).value()); } @@ -532,17 +535,17 @@ mod tests { } #[test] - fn iter_close_back() { + fn iter_rev_close() { let tree = iter_tree(); - let mut iter = tree.root().self_and_descendants(); + let mut iter = tree.root().self_and_descendants().rev(&tree); - iter.next_back(&tree).unwrap(); // r - let b = iter.next_back(&tree).unwrap(); + iter.next(&tree).unwrap(); // r + let b = iter.next(&tree).unwrap(); - iter.close_back(&tree, b); + iter.close(&tree, b); let mut r = vec![]; - while let Some(id) = iter.next_back(&tree) { + while let Some(id) = iter.next(&tree) { r.push(*tree.index(id).value()); } @@ -550,66 +553,7 @@ mod tests { } #[test] - fn iter_both_ends() { - let tree = iter_tree(); - let mut iter = tree.root().self_and_descendants(); - let r_start = iter.next().unwrap(); - let r_end = iter.next_back(&tree).unwrap(); - - assert_eq!(tree.index(r_start).value(), tree.index(r_end).value()); - } - - #[test] - fn iter_both_ends_closed_back() { - let tree = iter_tree(); - let mut iter = tree.root().self_and_descendants(); - iter.next_back(&tree).unwrap(); // r - iter.next_back(&tree).unwrap(); // b - - let mut r = vec![]; - while let Some(id) = iter.next() { - r.push(*tree.index(id).value()); - } - - assert_eq!(r, vec!["r", "a", "a.a", "a.b", "a.b.a", "a.b.b", "a.c"]); - } - - #[test] - fn iter_both_ends_closed_front() { - let tree = iter_tree(); - - let mut iter = tree.root().self_and_descendants(); - for _ in 0..["r", "a", "a.a", "a.b", "a.b.a", "a.b.b", "a.c"].len() { - iter.next().unwrap(); - } - - let mut r = vec![]; - while let Some(id) = iter.next_back(&tree) { - r.push(*tree.index(id).value()); - } - - assert_eq!(r, vec!["r", "b"]); - } - - #[test] - fn iter_both_ends_closed_front2() { - let tree = iter_tree(); - - let mut iter = tree.root().self_and_descendants(); - for _ in 0..["r", "a", "a.a", "a.b", "a.b.a"].len() { - iter.next().unwrap(); - } - - let mut r = vec![]; - while let Some(id) = iter.next_back(&tree) { - r.push(*tree.index(id).value()); - } - - assert_eq!(r, vec!["r", "b", "a", "a.c", "a.b", "a.b.b"]); - } - - #[test] - fn skip_to() { + fn iter_skip_to() { let tree = iter_tree(); let mut iter = tree.root().self_and_descendants(); @@ -634,21 +578,21 @@ mod tests { } #[test] - fn skip_back_to() { + fn iter_rev_skip_to() { let tree = iter_tree(); - let mut iter = tree.root().self_and_descendants(); + let mut iter = tree.root().self_and_descendants().rev(&tree); let mut all = vec![]; - while let Some(id) = iter.next_back(&tree) { + while let Some(id) = iter.next(&tree) { all.push(id); } for (i, id) in all.iter().enumerate() { - let mut iter = tree.root().self_and_descendants(); - iter.skip_back_to(*id, &tree); + let mut iter = tree.root().self_and_descendants().rev(&tree); + iter.skip_to(&tree, *id); let mut result = vec![]; - while let Some(id) = iter.next_back(&tree) { + while let Some(id) = iter.next(&tree) { result.push(tree.nodes[id.get()].value); }