mirror of
https://github.com/storytold/gridcraft.git
synced 2026-11-03 08:51:30 -06:00
Engine: macro.check and the footprint: where a macro writes, worked out before it runs
Split from the pull request below at the review's request; the code is the runner's footprint as reviewed there, unchanged. - `macro.run` first runs the macro in dry-run mode on the real workbook (unless the rule is `overwrite`) and puts everything back: the workbook, its selection and history through the dry run's undo group, and the session state a dry run may touch (`Saved`: the active workbook, open documents, the saved mark, selections, unlocked ranges, trust, clipboard, preferences, mode, journal and recording, queued requests, format painter, find, ruler, hidden windows, drawing tool and the comment panes). - Cells it would write outside its inputs that hold data, and sheets and objects it would delete, are conflicts: `ask` asks before anything runs, `fail` fails, and `shiftDown` and `shiftRight` insert cells over the block of every written cell and check again. A shift is refused when it would move an input, when the macro deletes sheets or objects, or when the touch log is full. - A dry run stops before a file step and before Solver; the footprint is then partial, and the run checks each step as it goes. - The dry runs and the run share one clock, one time limit and one step budget. - `macro.check` reports the inputs, the output anchor, approval needed and the footprint. - Tests: the footprint tests that moved with this code.
This commit is contained in:
@@ -206,6 +206,9 @@ pub struct DocState {
|
||||
/// workbook is opened from a file, carried by content pasted from such a workbook, and never
|
||||
/// changed by a trust decision.
|
||||
pub trust: Trust,
|
||||
/// While a macro's footprint is measured: every cell a command wrote, by sheet name, even
|
||||
/// where it wrote what was already there.
|
||||
pub touched: Option<Vec<(String, CellRef)>>,
|
||||
/// The references `edit.goTo` with `record: true` went to in this document, newest first,
|
||||
/// without names, each area written with its sheet (`Sheet1!B14:C22,Sheet1!F19:G30`).
|
||||
pub go_to_recent: Vec<String>,
|
||||
@@ -299,6 +302,7 @@ impl DocState {
|
||||
content_kind: None,
|
||||
scripts_trusted,
|
||||
trust,
|
||||
touched: None,
|
||||
go_to_recent: vec![],
|
||||
}
|
||||
}
|
||||
@@ -434,6 +438,9 @@ pub struct Session {
|
||||
/// Serialized size of each journal entry, measured once when it is pushed, and their sum.
|
||||
journal_sizes: Vec<usize>,
|
||||
journal_bytes: usize,
|
||||
/// Entries the journal has dropped from its front to stay within its limits, ever; a dry run
|
||||
/// that puts the journal back needs to know how many went while it ran.
|
||||
journal_dropped: u64,
|
||||
pub ui_requests: Vec<UiRequest>,
|
||||
/// Format painter source style (sticky when double-clicked).
|
||||
pub format_painter: Option<(Arc<Workbook>, usize, RangeRef, bool)>,
|
||||
@@ -558,10 +565,26 @@ impl Session {
|
||||
self.journal.drain(..n);
|
||||
self.journal_sizes.drain(..n);
|
||||
self.journal_bytes = kept;
|
||||
self.journal_dropped = self.journal_dropped.saturating_add(n as u64);
|
||||
self.recording = self.recording.map(|r| r.saturating_sub(n));
|
||||
}
|
||||
}
|
||||
|
||||
/// Entries dropped from the journal's front so far, for a caller that puts the journal back.
|
||||
pub(crate) fn journal_dropped(&self) -> u64 {
|
||||
self.journal_dropped
|
||||
}
|
||||
|
||||
/// Cuts the journal back to its first `keep` entries, with its size bookkeeping.
|
||||
pub(crate) fn truncate_journal(&mut self, keep: usize) {
|
||||
if self.journal_sizes.len() == self.journal.len() {
|
||||
self.journal_sizes.truncate(keep);
|
||||
self.journal_bytes = self.journal_sizes.iter().sum();
|
||||
}
|
||||
self.journal.truncate(keep);
|
||||
self.recording = self.recording.map(|r| r.min(self.journal.len()));
|
||||
}
|
||||
|
||||
pub fn commands(&self) -> Vec<CommandInfo> {
|
||||
command_specs().iter().map(|c| c.info(self)).collect()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user