Browse Source

ParamDefinition.DataRef

David Sehnal 4 years ago
parent
commit
c71f60a164

+ 2 - 1
src/cli/state-docs/pd-to-md.ts

@@ -26,7 +26,8 @@ function paramInfo(param: PD.Any, offset: number): string {
         case 'file': return `JavaScript File Handle`;
         case 'file-list': return `JavaScript FileList Handle`;
         case 'select': return `One of ${oToS(param.options)}`;
-        case 'value-ref': return `Reference to a state object.`;
+        case 'value-ref': return `Reference to a runtime defined value.`;
+        case 'data-ref': return `Reference to a computed data value.`;
         case 'text': return 'String';
         case 'interval': return `Interval [min, max]`;
         case 'group': return `Object with:\n${getParams(param.params, offset + 2)}`;

+ 1 - 0
src/mol-plugin-ui/controls/parameters.tsx

@@ -186,6 +186,7 @@ function controlFor(param: PD.Any): ParamControl | undefined {
         case 'file-list': return FileListControl;
         case 'select': return SelectControl;
         case 'value-ref': return ValueRefControl;
+        case 'data-ref': return void 0;
         case 'text': return TextControl;
         case 'interval': return typeof param.min !== 'undefined' && typeof param.max !== 'undefined'
             ? BoundedIntervalControl : IntervalControl;

+ 9 - 3
src/mol-state/state.ts

@@ -328,6 +328,8 @@ class State {
         const oldTree = this._tree;
         this._tree = _tree;
 
+        const cells = this.cells;
+
         const ctx: UpdateContext = {
             parent: this,
             editInfo: StateBuilder.is(tree) ? tree.editInfo : void 0,
@@ -346,7 +348,9 @@ class State {
             changed: false,
             hadError: false,
             wasAborted: false,
-            newCurrent: void 0
+            newCurrent: void 0,
+
+            getCellData: ref => cells.get(ref)!.obj?.data
         };
 
         this.errorFree = true;
@@ -454,7 +458,9 @@ interface UpdateContext {
     changed: boolean,
     hadError: boolean,
     wasAborted: boolean,
-    newCurrent?: Ref
+    newCurrent?: Ref,
+
+    getCellData: (ref: string) => any
 }
 
 async function update(ctx: UpdateContext) {
@@ -841,7 +847,7 @@ function resolveParams(ctx: UpdateContext, transform: StateTransform, src: State
     (transform.params as any) = transform.params
         ? assignIfUndefined(transform.params, defaultValues)
         : defaultValues;
-    ParamDefinition.resolveValueRefs(definition, transform.params);
+    ParamDefinition.resolveRefs(definition, transform.params, ctx.getCellData);
     return { definition, values: transform.params };
 }
 

+ 19 - 8
src/mol-util/param-definition.ts

@@ -296,6 +296,13 @@ export namespace ParamDefinition {
         return setInfo<ValueRef<T>>({ type: 'value-ref', defaultValue: { ref: info?.defaultRef ?? '', getValue: unsetGetValue as any }, getOptions, resolveRef }, info);
     }
 
+    export interface DataRef<T = any> extends Base<{ ref: string, getValue: () => T }> {
+        type: 'data-ref'
+    }
+    export function DataRef<T>(info?: Info & { defaultRef?: string }) {
+        return setInfo<DataRef<T>>({ type: 'data-ref', defaultValue: { ref: info?.defaultRef ?? '', getValue: unsetGetValue as any } }, info);
+    }
+
     export interface Converted<T, C> extends Base<T> {
         type: 'converted',
         converted: Any,
@@ -329,7 +336,7 @@ export namespace ParamDefinition {
 
     export type Any =
         | Value<any> | Select<any> | MultiSelect<any> | BooleanParam | Text | Color | Vec3 | Mat4 | Numeric | FileParam | UrlParam | FileListParam | Interval | LineGraph
-        | ColorList | Group<any> | Mapped<any> | Converted<any, any> | Conditioned<any, any, any> | Script | ObjectList | ValueRef
+        | ColorList | Group<any> | Mapped<any> | Converted<any, any> | Conditioned<any, any, any> | Script | ObjectList | ValueRef | DataRef
 
     export type Params = { [k: string]: Any }
     export type Values<T extends Params> = { [k in keyof T]: T[k]['defaultValue'] }
@@ -360,29 +367,33 @@ export namespace ParamDefinition {
         return () => resolve(ref);
     }
 
-    function resolveRefValue(p: Any, value: any) {
+    function resolveRefValue(p: Any, value: any, getData: (ref: string) => any) {
         if (!value) return;
 
         if (p.type === 'value-ref') {
             const v = value as ValueRef['defaultValue'];
             if (!v.ref) v.getValue = () => { throw new Error('Unset ref in ValueRef value.'); };
             else v.getValue = _resolveRef(p.resolveRef, v.ref);
+        } else if (p.type === 'data-ref') {
+            const v = value as ValueRef['defaultValue'];
+            if (!v.ref) v.getValue = () => { throw new Error('Unset ref in ValueRef value.'); };
+            else v.getValue = _resolveRef(getData, v.ref);
         } else if (p.type === 'group') {
-            resolveValueRefs(p.params, value);
+            resolveRefs(p.params, value, getData);
         } else if (p.type === 'mapped') {
             const v = value as NamedParams;
             const param = p.map(v.name);
-            resolveRefValue(param, v.params);
+            resolveRefValue(param, v.params, getData);
         } else if (p.type === 'object-list') {
             if (!hasValueRef(p.element)) return;
             for (const e of value) {
-                resolveValueRefs(p.element, e);
+                resolveRefs(p.element, e, getData);
             }
         }
     }
 
     function hasParamValueRef(p: Any) {
-        if (p.type === 'value-ref') {
+        if (p.type === 'value-ref' || p.type === 'data-ref') {
             return true;
         } else if (p.type === 'group') {
             if (hasValueRef(p.params)) return true;
@@ -403,9 +414,9 @@ export namespace ParamDefinition {
         return false;
     }
 
-    export function resolveValueRefs(params: Params, values: any) {
+    export function resolveRefs(params: Params, values: any, getData: (ref: string) => any) {
         for (const n of Object.keys(params)) {
-            resolveRefValue(params[n], values?.[n]);
+            resolveRefValue(params[n], values?.[n], getData);
         }
     }