Replay group and value side effects

This commit is contained in:
Laurenz 2022-05-27 09:36:51 +02:00
parent 806d9f0d9a
commit 9950a69d23
2 changed files with 25 additions and 14 deletions

View File

@ -221,18 +221,19 @@ impl Layout for LayoutNode {
regions: &Regions, regions: &Regions,
styles: StyleChain, styles: StyleChain,
) -> TypResult<Vec<Arc<Frame>>> { ) -> TypResult<Vec<Arc<Frame>>> {
let (result, cursor) = crate::memo::memoized( let (result, at, pins) = crate::memo::memoized(
(self, &mut *ctx, regions, styles), (self, &mut *ctx, regions, styles),
|(node, ctx, regions, styles)| { |(node, ctx, regions, styles)| {
let at = ctx.pins.cursor();
let entry = StyleEntry::Barrier(Barrier::new(node.id())); let entry = StyleEntry::Barrier(Barrier::new(node.id()));
let result = node.0.layout(ctx, regions, entry.chain(&styles)); 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 // Replay the side effect in case of caching. This should currently be
// more or less the only relevant side effect on the context. // more or less the only relevant side effect on the context.
ctx.pins.jump(cursor); ctx.pins.replay(at, pins);
result result
} }

View File

@ -169,15 +169,17 @@ impl PinBoard {
self.cursor self.cursor
} }
/// Set the current cursor. /// All pins from `prev` to the current cursor.
pub fn jump(&mut self, cursor: usize) { pub fn from(&self, prev: usize) -> Vec<Pin> {
if self.frozen > 0 { self.list[prev .. self.cursor].to_vec()
return; }
}
self.cursor = cursor; /// Add the given pins at the given location and set the cursor behind them.
if cursor >= self.list.len() { pub fn replay(&mut self, at: usize, pins: Vec<Pin>) {
self.list.resize(cursor, Pin::default()); 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; 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. /// Reset the cursor and remove all unused pins.
pub fn reset(&mut self) { pub fn reset(&mut self) {
self.list.truncate(self.cursor); self.list.truncate(self.cursor);
@ -218,12 +225,15 @@ impl PinBoard {
/// Access the next pin. /// Access the next pin.
fn next(&mut self, group: Option<Group>, value: Option<Value>) -> Pin { fn next(&mut self, group: Option<Group>, value: Option<Value>) -> Pin {
if self.frozen > 0 { if self.frozen() {
return Pin::default(); return Pin::default();
} }
let cursor = self.cursor; 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]; let pin = &mut self.list[cursor];
pin.group = group; pin.group = group;
@ -279,7 +289,7 @@ fn locate_in_frame(
/// A document pin. /// A document pin.
#[derive(Debug, Default, Clone, PartialEq, Hash)] #[derive(Debug, Default, Clone, PartialEq, Hash)]
struct Pin { pub struct Pin {
/// The physical location of the pin in the document. /// The physical location of the pin in the document.
loc: Location, loc: Location,
/// The flow index. /// The flow index.