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,
styles: StyleChain,
) -> TypResult<Vec<Arc<Frame>>> {
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
}

View File

@ -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<Pin> {
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<Pin>) {
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<Group>, value: Option<Value>) -> 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.