Skip to content

Commit

Permalink
Add methods for iterating over children with linear instead of quadra…
Browse files Browse the repository at this point in the history
…tic behavior
  • Loading branch information
Philipp-M committed Nov 24, 2024
1 parent ac29ec0 commit 14d1e6e
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 2 deletions.
23 changes: 23 additions & 0 deletions masonry/src/contexts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,29 @@ impl<'w> QueryCtx<'w> {
widget: child.item,
}
}

// TODO temporary until arena is more efficient (I think this might not always return the correct order of the children)?
/// To avoid quadratic behavior with manually iterating over children with [`Widget::children_ids`] by accessing these with [`Self::get`], this method allows to linearly iterate over all children.
pub fn children_iter(
self,
) -> impl DoubleEndedIterator<Item = WidgetRef<'w, dyn Widget>> + ExactSizeIterator {
self.widget_children
.iter()
.zip(self.widget_state_children.iter())
.map(|(child, child_state)| {
let ctx = QueryCtx {
global_state: self.global_state,
widget_state_children: child_state.children,
widget_children: child.children,
widget_state: child_state.item,
};

WidgetRef {
ctx,
widget: child.item.as_dyn(),
}
})
}
}

// --- MARK: UPDATE FLAGS ---
Expand Down
6 changes: 6 additions & 0 deletions masonry/src/tree_arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,12 @@ impl<'a, Item> ArenaRefChildren<'a, Item> {
.map(|child| child.arena_ref(self.id, self.parents_map.parents_map))
}

pub fn iter(self) -> impl DoubleEndedIterator<Item = ArenaRef<'a, Item>> + ExactSizeIterator {
self.children
.iter()
.map(move |child| child.arena_ref(self.id, self.parents_map.parents_map))
}

/// Get the child of the item this handle is associated with, which has the given id.
///
/// This is the same as [`get_child`](Self::get_child), except it consumes the
Expand Down
5 changes: 3 additions & 2 deletions masonry/src/widget/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,9 @@ pub(crate) fn find_widget_at_pos<'c>(

// Assumes `Self::children_ids` is in increasing "z-order", picking the last child in case
// of overlapping children.
for child_id in widget.children_ids().iter().rev() {
let child_ref = widget.ctx.get(*child_id);
// for child_id in widget.children_ids().iter().rev() {
// let child_ref = widget.ctx.get(*child_id);
for child_ref in widget.ctx.children_iter().rev() {
if let Some(child) = child_ref.widget.find_widget_at_pos(child_ref.ctx, pos) {
return Some(child);
}
Expand Down

0 comments on commit 14d1e6e

Please sign in to comment.