Refactored `tree_rev` to not be a DoubledEndedIterator, this allows splitting the implementation in two and changing the API expectations of where the iterators start and stop.
This commit is contained in:
parent
b6370c8216
commit
a97bb6c2ae
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<WidgetFocusInfo<'a>> {
|
||||
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 {
|
||||
|
|
|
@ -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<F>(self, mut filter: F) -> FocusableFilterDescendants<'a, I, impl FnMut(WidgetInfo<'a>) -> w_iter::TreeFilter>
|
||||
pub fn tree_filter<F>(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<Self::Item> {
|
||||
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::Item> {
|
||||
self.iter.next_back().map(|w| w.as_focus_info(self.focus_disabled_widgets))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Item = WidgetInfo<'a>> + 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<Item = WidgetInfo<'a>> + 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::Item> {
|
||||
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::Item> {
|
||||
self.iter.next_back()
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
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::Item> {
|
||||
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<Self::Item> {
|
||||
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();
|
||||
|
||||
|
|
|
@ -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<T>(&mut self, tree: &Tree<T>) -> Option<NodeId> {
|
||||
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<T>(&mut self, tree: &Tree<T>, 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<T>(&mut self, tree: &Tree<T>, 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<T>(&mut self, node: NodeId, tree: &Tree<T>) {
|
||||
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<T>(self, tree: &Tree<T>) -> 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<T>(&mut self, tree: &Tree<T>) -> Option<NodeId> {
|
||||
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<T>(&mut self, tree: &Tree<T>, 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<T>(&mut self, tree: &Tree<T>, 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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue