summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-05-27 09:36:51 +0200
committerLaurenz <laurmaedje@gmail.com>2022-05-27 09:36:51 +0200
commit9950a69d23a6415cdbea08bc770f4019344318a0 (patch)
treed7834d0fc06cb29c8b998438c74f0bcc5671f716 /src
parent806d9f0d9ab381500318f3e106b9c20c5eabccb7 (diff)
Replay group and value side effects
Diffstat (limited to 'src')
-rw-r--r--src/model/layout.rs7
-rw-r--r--src/model/locate.rs32
2 files changed, 25 insertions, 14 deletions
diff --git a/src/model/layout.rs b/src/model/layout.rs
index 49720be4..92d73977 100644
--- a/src/model/layout.rs
+++ b/src/model/layout.rs
@@ -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
}
diff --git a/src/model/locate.rs b/src/model/locate.rs
index a4b25d1d..c73c0339 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<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.