mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
Replay group and value side effects
This commit is contained in:
parent
806d9f0d9a
commit
9950a69d23
@ -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
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user