From 9950a69d23a6415cdbea08bc770f4019344318a0 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Fri, 27 May 2022 09:36:51 +0200 Subject: [PATCH] Replay group and value side effects --- src/model/layout.rs | 7 ++++--- src/model/locate.rs | 32 +++++++++++++++++++++----------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/model/layout.rs b/src/model/layout.rs index 49720be4d..92d73977b 100644 --- a/src/model/layout.rs +++ b/src/model/layout.rs @@ -221,18 +221,19 @@ impl Layout for LayoutNode { regions: &Regions, styles: StyleChain, ) -> TypResult>> { - let (result, cursor) = crate::memo::memoized( + let (result, at, pins) = crate::memo::memoized( (self, &mut *ctx, regions, styles), |(node, ctx, regions, styles)| { + let at = ctx.pins.cursor(); let entry = StyleEntry::Barrier(Barrier::new(node.id())); let result = node.0.layout(ctx, regions, entry.chain(&styles)); - (result, ctx.pins.cursor()) + (result, at, ctx.pins.from(at)) }, ); // Replay the side effect in case of caching. This should currently be // more or less the only relevant side effect on the context. - ctx.pins.jump(cursor); + ctx.pins.replay(at, pins); result } diff --git a/src/model/locate.rs b/src/model/locate.rs index a4b25d1de..c73c03399 100644 --- a/src/model/locate.rs +++ b/src/model/locate.rs @@ -169,15 +169,17 @@ impl PinBoard { self.cursor } - /// Set the current cursor. - pub fn jump(&mut self, cursor: usize) { - if self.frozen > 0 { - return; - } + /// All pins from `prev` to the current cursor. + pub fn from(&self, prev: usize) -> Vec { + self.list[prev .. self.cursor].to_vec() + } - self.cursor = cursor; - if cursor >= self.list.len() { - self.list.resize(cursor, Pin::default()); + /// Add the given pins at the given location and set the cursor behind them. + pub fn replay(&mut self, at: usize, pins: Vec) { + if !self.frozen() { + self.cursor = at + pins.len(); + let end = self.cursor.min(self.list.len()); + self.list.splice(at .. end, pins); } } @@ -191,6 +193,11 @@ impl PinBoard { self.frozen -= 1; } + /// Whether the board is currently frozen. + pub fn frozen(&self) -> bool { + self.frozen > 0 + } + /// Reset the cursor and remove all unused pins. pub fn reset(&mut self) { self.list.truncate(self.cursor); @@ -218,12 +225,15 @@ impl PinBoard { /// Access the next pin. fn next(&mut self, group: Option, value: Option) -> Pin { - if self.frozen > 0 { + if self.frozen() { return Pin::default(); } let cursor = self.cursor; - self.jump(self.cursor + 1); + self.cursor += 1; + if self.cursor >= self.list.len() { + self.list.resize(self.cursor, Pin::default()); + } let pin = &mut self.list[cursor]; pin.group = group; @@ -279,7 +289,7 @@ fn locate_in_frame( /// A document pin. #[derive(Debug, Default, Clone, PartialEq, Hash)] -struct Pin { +pub struct Pin { /// The physical location of the pin in the document. loc: Location, /// The flow index.