tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 583HTML 275Markdown 8TOML 41586 Definiciones

Flexbox: fix O(n^2) order lookup (#537)

498a7470fb63477a772a37a9706904bbc46c5e41 · por Nico Burns · (hace 3 años) · padre c6902929e · ver el árbol en este commit

Delta semántico · 6

src/compute/flexbox.rs

1 archivos · +12 −15

diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs
index 27cc53cc6..3fff92e12 100644
--- a/src/compute/flexbox.rs
+++ b/src/compute/flexbox.rs
@@ -55,6 +55,9 @@ struct FlexItem {
     /// The identifier for the associated node
     node: NodeId,
 
+    /// The order of the node relative to it's siblings
+    order: u32,
+
     /// The base size of this item
     size: Size<Option<f32>>,
     /// The minimum allowable size of this item
@@ -381,7 +384,7 @@ fn compute_preliminary(
     // Do a final layout pass and gather the resulting layouts
     #[cfg(feature = "debug")]
     NODE_LOGGER.log("final_layout_pass");
-    final_layout_pass(tree, node, &mut flex_lines, &constants);
+    final_layout_pass(tree, &mut flex_lines, &constants);
 
     // Before returning we perform absolute layout on all absolutely positioned children
     #[cfg(feature = "debug")]
@@ -499,13 +502,15 @@ fn compute_constants(
 #[inline]
 fn generate_anonymous_flex_items(tree: &impl LayoutTree, node: NodeId, constants: &AlgoConstants) -> Vec<FlexItem> {
     tree.children(node)
-        .map(|child| (child, tree.style(child)))
-        .filter(|(_, style)| style.position != Position::Absolute)
-        .filter(|(_, style)| style.display != Display::None)
-        .map(|(child, child_style)| {
+        .enumerate()
+        .map(|(index, child)| (index, child, tree.style(child)))
+        .filter(|(_, _, style)| style.position != Position::Absolute)
+        .filter(|(_, _, style)| style.display != Display::None)
+        .map(|(index, child, child_style)| {
             let aspect_ratio = child_style.aspect_ratio;
             FlexItem {
                 node: child,
+                order: index as u32,
                 size: child_style.size.maybe_resolve(constants.node_inner_size).maybe_apply_aspect_ratio(aspect_ratio),
                 min_size: child_style
                     .min_size
@@ -1767,7 +1772,6 @@ fn align_flex_lines_per_align_content(flex_lines: &mut [FlexLine], constants: &A
 #[allow(clippy::too_many_arguments)]
 fn calculate_flex_item(
     tree: &mut impl LayoutTree,
-    node: NodeId,
     item: &mut FlexItem,
     total_offset_main: &mut f32,
     total_offset_cross: f32,
@@ -1807,10 +1811,8 @@ fn calculate_flex_item(
         item.baseline = baseline_offset_main + inner_baseline;
     }
 
-    let order = tree.children(node).position(|n| n == item.node).unwrap() as u32;
-
     *tree.layout_mut(item.node) = Layout {
-        order,
+        order: item.order,
         size: preliminary_size_and_baselines.size,
         location: Point {
             x: if direction.is_row() { offset_main } else { offset_cross },
@@ -1825,7 +1827,6 @@ fn calculate_flex_item(
 #[allow(clippy::too_many_arguments)]
 fn calculate_layout_line(
     tree: &mut impl LayoutTree,
-    node: NodeId,
     line: &mut FlexLine,
     total_offset_cross: &mut f32,
     container_size: Size<f32>,
@@ -1840,7 +1841,6 @@ fn calculate_layout_line(
         for item in line.items.iter_mut().rev() {
             calculate_flex_item(
                 tree,
-                node,
                 item,
                 &mut total_offset_main,
                 *total_offset_cross,
@@ -1854,7 +1854,6 @@ fn calculate_layout_line(
         for item in line.items.iter_mut() {
             calculate_flex_item(
                 tree,
-                node,
                 item,
                 &mut total_offset_main,
                 *total_offset_cross,
@@ -1871,14 +1870,13 @@ fn calculate_layout_line(
 
 /// Do a final layout pass and collect the resulting layouts.
 #[inline]
-fn final_layout_pass(tree: &mut impl LayoutTree, node: NodeId, flex_lines: &mut [FlexLine], constants: &AlgoConstants) {
+fn final_layout_pass(tree: &mut impl LayoutTree, flex_lines: &mut [FlexLine], constants: &AlgoConstants) {
     let mut total_offset_cross = constants.content_box_inset.cross_start(constants.dir);
 
     if constants.is_wrap_reverse {
         for line in flex_lines.iter_mut().rev() {
             calculate_layout_line(
                 tree,
-                node,
                 line,
                 &mut total_offset_cross,
                 constants.container_size,
@@ -1891,7 +1889,6 @@ fn final_layout_pass(tree: &mut impl LayoutTree, node: NodeId, flex_lines: &mut
         for line in flex_lines.iter_mut() {
             calculate_layout_line(
                 tree,
-                node,
                 line,
                 &mut total_offset_cross,
                 constants.container_size,