aboutsummaryrefslogtreecommitdiff
path: root/src/new_fields/ScriptField.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/new_fields/ScriptField.ts')
-rw-r--r--src/new_fields/ScriptField.ts93
1 files changed, 93 insertions, 0 deletions
diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts
new file mode 100644
index 000000000..0839a823d
--- /dev/null
+++ b/src/new_fields/ScriptField.ts
@@ -0,0 +1,93 @@
+import { ObjectField } from "./ObjectField";
+import { CompiledScript, CompileScript } from "../client/util/Scripting";
+import { Copy, ToScriptString, Parent, SelfProxy } from "./FieldSymbols";
+import { serializable, createSimpleSchema, map, primitive, object, deserialize, PropSchema, custom, SKIP } from "serializr";
+import { Deserializable } from "../client/util/SerializationHelper";
+import { computed } from "mobx";
+
+function optional(propSchema: PropSchema) {
+ return custom(value => {
+ if (value !== undefined) {
+ return propSchema.serializer(value);
+ }
+ return SKIP;
+ }, (jsonValue: any, context: any, oldValue: any, callback: (err: any, result: any) => void) => {
+ if (jsonValue !== undefined) {
+ return propSchema.deserializer(jsonValue, callback, context, oldValue);
+ }
+ return SKIP;
+ });
+}
+
+const optionsSchema = createSimpleSchema({
+ requiredType: true,
+ addReturn: true,
+ typecheck: true,
+ params: optional(map(primitive()))
+});
+
+const scriptSchema = createSimpleSchema({
+ options: object(optionsSchema),
+ originalScript: true
+});
+
+function deserializeScript(script: ScriptField) {
+ const comp = CompileScript(script.script.originalScript, script.script.options);
+ if (!comp.compiled) {
+ throw new Error("Couldn't compile loaded script");
+ }
+ (script as any).script = comp;
+}
+
+@Deserializable("script", deserializeScript)
+export class ScriptField extends ObjectField {
+ @serializable(object(scriptSchema))
+ readonly script: CompiledScript;
+
+ constructor(script: CompiledScript) {
+ super();
+
+ this.script = script;
+ }
+
+ // init(callback: (res: Field) => any) {
+ // const options = this.options!;
+ // const keys = Object.keys(options.options.capturedIds);
+ // Server.GetFields(keys).then(fields => {
+ // let captured: { [name: string]: Field } = {};
+ // keys.forEach(key => captured[options.options.capturedIds[key]] = fields[key]);
+ // const opts: ScriptOptions = {
+ // addReturn: options.options.addReturn,
+ // params: options.options.params,
+ // requiredType: options.options.requiredType,
+ // capturedVariables: captured
+ // };
+ // const script = CompileScript(options.script, opts);
+ // if (!script.compiled) {
+ // throw new Error("Can't compile script");
+ // }
+ // this._script = script;
+ // callback(this);
+ // });
+ // }
+
+ [Copy](): ObjectField {
+ return new ScriptField(this.script);
+ }
+
+ [ToScriptString]() {
+ return "script field";
+ }
+}
+
+@Deserializable("computed", deserializeScript)
+export class ComputedField extends ScriptField {
+ @computed
+ get value() {
+ const val = this.script.run({ this: this[Parent] });
+ if (val.success) {
+ return val.result;
+ }
+ return undefined;
+ }
+} \ No newline at end of file