summaryrefslogtreecommitdiff
path: root/src/layout/mod.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-12-15 11:11:57 +0100
committerLaurenz <laurmaedje@gmail.com>2021-12-15 11:11:57 +0100
commitae38be9097bbb32142ef776e77e627ac12379000 (patch)
treef365a348d4c77d2d607d37fee3bc65a601d00a64 /src/layout/mod.rs
parentfe21c4d399d291e75165b664762f0aa8bdc4724a (diff)
Set Rules Episode IV: A New Fold
Diffstat (limited to 'src/layout/mod.rs')
-rw-r--r--src/layout/mod.rs46
1 files changed, 36 insertions, 10 deletions
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 5da0ad9a..4ede39b2 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -91,14 +91,19 @@ pub trait Layout {
pub struct PackedNode {
/// The type-erased node.
node: Rc<dyn Bounds>,
- /// The node's styles.
- pub styles: Styles,
+ /// A precomputed hash for the node.
#[cfg(feature = "layout-cache")]
- /// A precomputed hash.
hash: u64,
+ /// The node's styles.
+ pub styles: Styles,
}
impl PackedNode {
+ /// Check whether the contained node is a specific layout node.
+ pub fn is<T: 'static>(&self) -> bool {
+ self.node.as_any().is::<T>()
+ }
+
/// Try to downcast to a specific layout node.
pub fn downcast<T>(&self) -> Option<&T>
where
@@ -173,7 +178,15 @@ impl Layout for PackedNode {
return self.layout_impl(ctx, regions);
#[cfg(feature = "layout-cache")]
- ctx.layouts.get(self.hash, regions).unwrap_or_else(|| {
+ let hash = {
+ let mut state = fxhash::FxHasher64::default();
+ self.hash(&mut state);
+ ctx.styles.hash(&mut state);
+ state.finish()
+ };
+
+ #[cfg(feature = "layout-cache")]
+ ctx.layouts.get(hash, regions).unwrap_or_else(|| {
ctx.level += 1;
let frames = self.layout_impl(ctx, regions);
ctx.level -= 1;
@@ -191,7 +204,7 @@ impl Layout for PackedNode {
panic!("constraints did not match regions they were created for");
}
- ctx.layouts.insert(self.hash, entry);
+ ctx.layouts.insert(hash, entry);
frames
})
}
@@ -219,18 +232,31 @@ impl PackedNode {
}
}
+impl Debug for PackedNode {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ if f.alternate() {
+ self.styles.fmt(f)?;
+ }
+ self.node.fmt(f)
+ }
+}
+
+impl PartialEq for PackedNode {
+ fn eq(&self, other: &Self) -> bool {
+ Rc::as_ptr(&self.node) as *const () == Rc::as_ptr(&other.node) as *const ()
+ }
+}
+
impl Hash for PackedNode {
fn hash<H: Hasher>(&self, state: &mut H) {
+ // Hash the node.
#[cfg(feature = "layout-cache")]
state.write_u64(self.hash);
#[cfg(not(feature = "layout-cache"))]
state.write_u64(self.hash64());
- }
-}
-impl Debug for PackedNode {
- fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- self.node.fmt(f)
+ // Hash the styles.
+ self.styles.hash(state);
}
}