From 6343c75953f6612acf9881da841c1e98c61ebaf4 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Mon, 23 Aug 2021 10:01:43 -0500 Subject: [PATCH] scripting: io.mutable(), $ vs $$ --- src/common/script/env.ts | 28 +++++++++++++++------------- src/common/script/lib/io.ts | 18 +++++++++++++----- src/common/script/lib/scriptui.ts | 1 + 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/common/script/env.ts b/src/common/script/env.ts index c339cebd..8d3051a5 100644 --- a/src/common/script/env.ts +++ b/src/common/script/env.ts @@ -51,6 +51,13 @@ class RuntimeError extends Error { } } +function setConstructorName(o: object) : void { + let name = Object.getPrototypeOf(o)?.constructor?.name; + if (name != null && name != 'Object') { + o[PROP_CONSTRUCTOR_NAME] = name; + } +} + export class Environment { preamble: string; postamble: string; @@ -82,7 +89,7 @@ export class Environment { } print(args: any[]) { if (args && args.length > 0 && args[0] != null) { - this.obj[`$$print__${this.seq++}`] = args.length == 1 ? args[0] : args; + this.obj[`$print__${this.seq++}`] = args.length == 1 ? args[0] : args; } } preprocess(code: string): string { @@ -111,7 +118,7 @@ export class Environment { } const convertTopToPrint = () => { if (isTopLevel()) { - let printkey = `$$print__${this.seq++}`; + let printkey = `$print__${this.seq++}`; update(`this.${printkey} = io.data.load(${source()}, ${JSON.stringify(printkey)})`); //update(`print(${source()});`) } @@ -153,7 +160,7 @@ export class Environment { // literal comments case 'Literal': if (typeof node['value'] === 'string' && isTopLevel()) { - update(`this.$$doc__${this.seq++} = { literaltext: ${source()} };`); + update(`this.$doc__${this.seq++} = { literaltext: ${source()} };`); } else { convertTopToPrint(); } @@ -177,7 +184,8 @@ export class Environment { if (o == null) return; if (checked.has(o)) return; if (typeof o === 'object') { - o[PROP_CONSTRUCTOR_NAME] = Object.getPrototypeOf(o).constructor.name; + setConstructorName(o); + delete o.$$callback; // clear callbacks (TODO? put somewhere else?) if (o.length > 100) return; // big array, don't bother if (o.BYTES_PER_ELEMENT > 0) return; // typed array, don't bother checked.add(o); // so we don't recurse if cycle @@ -263,17 +271,11 @@ export class Environment { return errors; } getLoadableState() { - let updated = null; - // TODO: use Loadable // TODO: visit children? - // TODO: doesn't work for (let [key, value] of Object.entries(this.obj)) { - if (typeof value['$$getstate'] === 'function') { - let loadable = value as io.Loadable; - if (updated == null) updated = {}; - updated[key] = loadable.$$getstate(); - } + let loadable = value as io.Loadable; + io.data.save(loadable, key); } - return updated; + return io.$$getData(); } } diff --git a/src/common/script/lib/io.ts b/src/common/script/lib/io.ts index 11e846be..c756236a 100644 --- a/src/common/script/lib/io.ts +++ b/src/common/script/lib/io.ts @@ -7,8 +7,6 @@ var $$cache: WeakMap = new WeakMap(); var $$store: WorkingStore; // backing store for data var $$data: {} = {}; -// events -var $$seq = 0; export function $$setupFS(store: WorkingStore) { $$store = store; @@ -36,8 +34,6 @@ export namespace data { object.$$setstate(override); } else if (override) { Object.assign(object, override); - } else if (object.$$getstate) { - save(object, key); // $$reset not needed } return object; } @@ -149,5 +145,17 @@ export class Mutable implements Loadable { } export function mutable(obj: object) : object { - return new Mutable(obj); + Object.defineProperty(obj, '$$setstate', { + value: function(newstate) { + Object.assign(this, newstate); + }, + enumerable: false + }); + Object.defineProperty(obj, '$$getstate', { + value: function() { + return this; + }, + enumerable: false + }); + return obj; } diff --git a/src/common/script/lib/scriptui.ts b/src/common/script/lib/scriptui.ts index 08d990b1..6d256b09 100644 --- a/src/common/script/lib/scriptui.ts +++ b/src/common/script/lib/scriptui.ts @@ -44,6 +44,7 @@ export class InteractionRecord implements io.Loadable { } $$getstate() { //TODO: this isn't always cleared before we serialize (e.g. if exception or move element) + //and we do it in checkResult() too this.$$callback = null; return this; }