From 5904bcf1c20638d63b244a1b2b038ec9a664ba1c Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 8 Jan 2024 13:51:38 +0100 Subject: [PATCH] Use taffy to retrieve the parent for a given layout node --- Cargo.lock | 7 +++--- crates/gpui/Cargo.toml | 2 +- crates/gpui/src/taffy.rs | 46 ++++++++++++++++------------------------ 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54e2f483d8a655f3d5e5c6e200b918275f968a34..ca55567cbb2a78661cb3c91b3e31c89b281bb9b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3091,9 +3091,9 @@ dependencies = [ [[package]] name = "grid" -version = "0.11.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df00eed8d1f0db937f6be10e46e8072b0671accb504cf0f959c5c52c679f5b9" +checksum = "d196ffc1627db18a531359249b2bf8416178d84b729f3cebeb278f285fb9b58c" [[package]] name = "h2" @@ -7665,11 +7665,12 @@ dependencies = [ [[package]] name = "taffy" version = "0.3.11" -source = "git+https://github.com/DioxusLabs/taffy?rev=1876f72bee5e376023eaa518aa7b8a34c769bd1b#1876f72bee5e376023eaa518aa7b8a34c769bd1b" +source = "git+https://github.com/zed-industries/taffy?rev=5e6c2d23e70e9f2156911d11050cb686362ba277#5e6c2d23e70e9f2156911d11050cb686362ba277" dependencies = [ "arrayvec 0.7.4", "grid", "num-traits", + "serde", "slotmap", ] diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index 6ea3524fcc4eb2a60ae2411f7eed6a2ef05a17a8..118753aafea5981e0dd2119f9b4203c70b85695d 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -46,7 +46,7 @@ serde_derive.workspace = true serde_json.workspace = true smallvec.workspace = true smol.workspace = true -taffy = { git = "https://github.com/DioxusLabs/taffy", rev = "1876f72bee5e376023eaa518aa7b8a34c769bd1b" } +taffy = { git = "https://github.com/zed-industries/taffy", rev = "5e6c2d23e70e9f2156911d11050cb686362ba277" } thiserror.workspace = true time.workspace = true tiny-skia = "0.5" diff --git a/crates/gpui/src/taffy.rs b/crates/gpui/src/taffy.rs index 0ebd394217ae06c6a2256281f389ab506bfca934..a77127e80176f6f74ca5f789a2570d0a630f9a33 100644 --- a/crates/gpui/src/taffy.rs +++ b/crates/gpui/src/taffy.rs @@ -6,15 +6,12 @@ use collections::{FxHashMap, FxHashSet}; use smallvec::SmallVec; use std::fmt::Debug; use taffy::{ - geometry::{Point as TaffyPoint, Rect as TaffyRect, Size as TaffySize}, - style::AvailableSpace as TaffyAvailableSpace, - tree::NodeId, - Taffy, + AvailableSpace as TaffyAvailableSpace, NodeId, Point as TaffyPoint, Rect as TaffyRect, + Size as TaffySize, TaffyTree, TraversePartialTree, }; pub struct TaffyLayoutEngine { - taffy: Taffy, - children_to_parents: FxHashMap, + tree: TaffyTree, absolute_layout_bounds: FxHashMap>, computed_layouts: FxHashSet, nodes_to_measure: FxHashMap< @@ -34,8 +31,7 @@ static EXPECT_MESSAGE: &str = "we should avoid taffy layout errors by constructi impl TaffyLayoutEngine { pub fn new() -> Self { TaffyLayoutEngine { - taffy: Taffy::new(), - children_to_parents: FxHashMap::default(), + tree: TaffyTree::new(), absolute_layout_bounds: FxHashMap::default(), computed_layouts: FxHashSet::default(), nodes_to_measure: FxHashMap::default(), @@ -43,8 +39,7 @@ impl TaffyLayoutEngine { } pub fn clear(&mut self) { - self.taffy.clear(); - self.children_to_parents.clear(); + self.tree.clear(); self.absolute_layout_bounds.clear(); self.computed_layouts.clear(); self.nodes_to_measure.clear(); @@ -58,18 +53,13 @@ impl TaffyLayoutEngine { ) -> LayoutId { let style = style.to_taffy(rem_size); if children.is_empty() { - self.taffy.new_leaf(style).expect(EXPECT_MESSAGE).into() + self.tree.new_leaf(style).expect(EXPECT_MESSAGE).into() } else { - let parent_id = self - .taffy + self.tree // This is safe because LayoutId is repr(transparent) to taffy::tree::NodeId. .new_with_children(style, unsafe { std::mem::transmute(children) }) .expect(EXPECT_MESSAGE) - .into(); - for child_id in children { - self.children_to_parents.insert(*child_id, parent_id); - } - parent_id + .into() } } @@ -83,7 +73,7 @@ impl TaffyLayoutEngine { let style = style.to_taffy(rem_size); let layout_id = self - .taffy + .tree .new_leaf_with_context(style, ()) .expect(EXPECT_MESSAGE) .into(); @@ -96,7 +86,7 @@ impl TaffyLayoutEngine { fn count_all_children(&self, parent: LayoutId) -> anyhow::Result { let mut count = 0; - for child in self.taffy.children(parent.0)? { + for child in self.tree.children(parent.0)? { // Count this child. count += 1; @@ -112,12 +102,12 @@ impl TaffyLayoutEngine { fn max_depth(&self, depth: u32, parent: LayoutId) -> anyhow::Result { println!( "{parent:?} at depth {depth} has {} children", - self.taffy.child_count(parent.0)? + self.tree.child_count(parent.0) ); let mut max_child_depth = 0; - for child in self.taffy.children(parent.0)? { + for child in self.tree.children(parent.0)? { max_child_depth = std::cmp::max(max_child_depth, self.max_depth(0, LayoutId(child))?); } @@ -129,7 +119,7 @@ impl TaffyLayoutEngine { fn get_edges(&self, parent: LayoutId) -> anyhow::Result> { let mut edges = Vec::new(); - for child in self.taffy.children(parent.0)? { + for child in self.tree.children(parent.0)? { edges.push((parent, LayoutId(child))); edges.extend(self.get_edges(LayoutId(child))?); @@ -162,7 +152,7 @@ impl TaffyLayoutEngine { while let Some(id) = stack.pop() { self.absolute_layout_bounds.remove(&id); stack.extend( - self.taffy + self.tree .children(id.into()) .expect(EXPECT_MESSAGE) .into_iter() @@ -172,7 +162,7 @@ impl TaffyLayoutEngine { } // let started_at = std::time::Instant::now(); - self.taffy + self.tree .compute_layout_with_measure( id.into(), available_space.into(), @@ -199,14 +189,14 @@ impl TaffyLayoutEngine { return layout; } - let layout = self.taffy.layout(id.into()).expect(EXPECT_MESSAGE); + let layout = self.tree.layout(id.into()).expect(EXPECT_MESSAGE); let mut bounds = Bounds { origin: layout.location.into(), size: layout.size.into(), }; - if let Some(parent_id) = self.children_to_parents.get(&id).copied() { - let parent_bounds = self.layout_bounds(parent_id); + if let Some(parent_id) = self.tree.parent(id.0) { + let parent_bounds = self.layout_bounds(parent_id.into()); bounds.origin += parent_bounds.origin; } self.absolute_layout_bounds.insert(id, bounds);