mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-10 12:21:54 +00:00
Scripts: a document a script opens counts toward the run's growth limit
A document that document.open or file.new adds during a run counts whole toward the growth allowance: every object in its layers, symbols and patterns, opacity masks included, and its document data.
This commit is contained in:
@@ -520,6 +520,14 @@ fn raise_ids(s: &mut Session) {
|
||||
s.script_high_water = marks;
|
||||
}
|
||||
|
||||
/// Every object in `d`: the art of its layers, its symbols and its patterns, opacity masks included.
|
||||
fn all_objects(d: &crate::Document) -> u64 {
|
||||
let layers = d.layers.iter().map(|n| n.count_with_masks());
|
||||
let symbols = d.symbols.iter().map(|s| s.art.count_with_masks());
|
||||
let patterns = d.patterns.iter().flat_map(|p| &p.art).map(|n| n.count_with_masks());
|
||||
layers.chain(symbols).chain(patterns).map(|n| n as u64).sum()
|
||||
}
|
||||
|
||||
fn note_ids(s: &mut Session) {
|
||||
for st in &s.docs {
|
||||
let mark = s.script_high_water.entry(st.uid).or_insert(0);
|
||||
@@ -551,11 +559,18 @@ fn step(s: &mut Session, host: &Host, id: &str, params: &Value) -> Result<(Value
|
||||
note_ids(s);
|
||||
let (mut objects, mut bytes) = (0, 0);
|
||||
for st in &s.docs {
|
||||
if let Some((_, d, ids)) = before.iter().find(|(uid, ..)| *uid == st.uid)
|
||||
&& !Arc::ptr_eq(d, &st.doc)
|
||||
{
|
||||
objects += st.doc.peek_next_id().saturating_sub(*ids);
|
||||
bytes += d.retained_bytes_each(&st.doc).1 as u64;
|
||||
match before.iter().find(|(uid, ..)| *uid == st.uid) {
|
||||
Some((_, d, ids)) if !Arc::ptr_eq(d, &st.doc) => {
|
||||
objects += st.doc.peek_next_id().saturating_sub(*ids);
|
||||
bytes += d.retained_bytes_each(&st.doc).1 as u64;
|
||||
}
|
||||
Some(_) => {}
|
||||
// A document the command opened or made counts whole.
|
||||
None if mutating => {
|
||||
objects += all_objects(&st.doc);
|
||||
bytes += crate::Document::new(1.0, 1.0).retained_bytes_each(&st.doc).1 as u64;
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
Ok((v, objects, bytes, save))
|
||||
|
||||
@@ -601,6 +601,37 @@ fn a_run_with_nobody_to_ask_ends_at_its_growth_allowance() {
|
||||
assert_eq!(state(&s), before);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_document_a_run_opens_counts_toward_its_growth_allowance() {
|
||||
TEST_GROWTH.with(|g| g.set(Some(20)));
|
||||
let rects: String = (0..30).map(|i| format!(r#"<rect x="{i}" y="0" width="1" height="1"/>"#)).collect();
|
||||
let svg = format!(r#"<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">{rects}</svg>"#);
|
||||
let data = vectorcraft_format::base64_encode(svg.as_bytes());
|
||||
let mut s = two_docs();
|
||||
let before = state(&s);
|
||||
let source = format!("try {{ vc.run('document.open', {{name: 'a.svg', dataBase64: '{data}'}}); }} catch (e) {{}}");
|
||||
let e = run(&mut s, &source).unwrap_err().to_string();
|
||||
assert!(e.contains("objects and data"), "{e}");
|
||||
assert_eq!(state(&s), before);
|
||||
|
||||
// A document whose art is all in a symbol counts it too.
|
||||
let mut maker = Session::new();
|
||||
maker.execute("file.new", &json!({})).unwrap();
|
||||
for x in 0..30 {
|
||||
maker.execute("shape.rectangle", &rect(x)).unwrap();
|
||||
}
|
||||
maker.execute("select.all", &json!({})).unwrap();
|
||||
let instance = maker.execute("symbol.new", &json!({"name": "Many"})).unwrap()["id"].as_u64().unwrap();
|
||||
maker.execute("edit.clear", &json!({"ids": [instance]})).unwrap();
|
||||
assert_eq!(objects(&maker, 0), 0);
|
||||
let data = maker.execute("document.serialize", &json!({})).unwrap()["dataBase64"].as_str().unwrap().to_string();
|
||||
let source = format!("vc.run('document.open', {{name: 'b.vectorcraft', dataBase64: '{data}'}});");
|
||||
let e = run(&mut s, &source).unwrap_err().to_string();
|
||||
TEST_GROWTH.with(|g| g.set(None));
|
||||
assert!(e.contains("objects and data"), "{e}");
|
||||
assert_eq!(state(&s), before);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_person_can_let_a_growing_run_go_on_or_stop_it() {
|
||||
TEST_GROWTH.with(|g| g.set(Some(20)));
|
||||
|
||||
Reference in New Issue
Block a user