diff options
| author | Martin <mhaug@live.de> | 2021-06-17 14:18:43 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-17 14:18:43 +0200 |
| commit | e14e8047890afad5896c9f38ccdd8551f869be64 (patch) | |
| tree | e65a448e88c0de84ae0790a92a00fd903ba197da /src/layout/mod.rs | |
| parent | e2cdda67dc0e16b9a482aa3a4bfd5991db06d143 (diff) | |
Constraints (#31)
Diffstat (limited to 'src/layout/mod.rs')
| -rw-r--r-- | src/layout/mod.rs | 83 |
1 files changed, 37 insertions, 46 deletions
diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 9c4222c8..15c80017 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -4,6 +4,7 @@ mod background; mod fixed; mod frame; mod grid; +mod incremental; mod pad; mod par; mod shaping; @@ -13,16 +14,18 @@ pub use background::*; pub use fixed::*; pub use frame::*; pub use grid::*; +pub use incremental::*; pub use pad::*; pub use par::*; pub use shaping::*; pub use stack::*; use std::any::Any; -use std::collections::HashMap; use std::fmt::{self, Debug, Formatter}; use std::hash::{Hash, Hasher}; +use fxhash::FxHasher64; + use crate::cache::Cache; use crate::geom::*; use crate::loading::Loader; @@ -64,7 +67,7 @@ impl PageRun { let Size { width, height } = self.size; let expand = Spec::new(width.is_finite(), height.is_finite()); let regions = Regions::repeat(self.size, expand); - self.child.layout(ctx, ®ions) + self.child.layout(ctx, ®ions).into_iter().map(|c| c.item).collect() } } @@ -80,26 +83,34 @@ impl AnyNode { where T: Layout + Debug + Clone + PartialEq + Hash + 'static, { - let hash = fxhash::hash64(&node); + let mut state = FxHasher64::default(); + node.type_id().hash(&mut state); + node.hash(&mut state); + let hash = state.finish(); + Self { node: Box::new(node), hash } } } impl Layout for AnyNode { - fn layout(&self, ctx: &mut LayoutContext, regions: &Regions) -> Vec<Frame> { - if let Some(hit) = ctx.cache.layout.frames.get(&self.hash) { - if &hit.regions == regions { - return hit.frames.clone(); - } - } - - let frames = self.node.layout(ctx, regions); - ctx.cache.layout.frames.insert(self.hash, FramesEntry { - regions: regions.clone(), - frames: frames.clone(), - }); - - frames + fn layout( + &self, + ctx: &mut LayoutContext, + regions: &Regions, + ) -> Vec<Constrained<Frame>> { + ctx.cache + .layout + .frames + .get(&self.hash) + .and_then(|x| x.check(regions.clone())) + .unwrap_or_else(|| { + let frames = self.node.layout(ctx, regions); + ctx.cache + .layout + .frames + .insert(self.hash, FramesEntry { frames: frames.clone() }); + frames + }) } } @@ -160,7 +171,11 @@ where /// Layout a node. pub trait Layout { /// Layout the node into the given regions. - fn layout(&self, ctx: &mut LayoutContext, regions: &Regions) -> Vec<Frame>; + fn layout( + &self, + ctx: &mut LayoutContext, + regions: &Regions, + ) -> Vec<Constrained<Frame>>; } /// The context for layouting. @@ -171,33 +186,6 @@ pub struct LayoutContext<'a> { pub cache: &'a mut Cache, } -/// Caches layouting artifacts. -pub struct LayoutCache { - /// Maps from node hashes to the resulting frames and regions in which the - /// frames are valid. - pub frames: HashMap<u64, FramesEntry>, -} - -impl LayoutCache { - /// Create a new, empty layout cache. - pub fn new() -> Self { - Self { frames: HashMap::new() } - } - - /// Clear the cache. - pub fn clear(&mut self) { - self.frames.clear(); - } -} - -/// Cached frames from past layouting. -pub struct FramesEntry { - /// The regions in which these frames are valid. - pub regions: Regions, - /// The cached frames for a node. - pub frames: Vec<Frame>, -} - /// A sequence of regions to layout into. #[derive(Debug, Clone, PartialEq)] pub struct Regions { @@ -261,10 +249,13 @@ impl Regions { } /// Advance to the next region if there is any. - pub fn next(&mut self) { + pub fn next(&mut self) -> bool { if let Some(size) = self.backlog.pop().or(self.last) { self.current = size; self.base = size; + true + } else { + false } } |
