Browse Source

mol-state: resolve params (automatically use default params if none are specified)

David Sehnal 6 years ago
parent
commit
42b240f207

+ 7 - 5
src/mol-plugin/ui/state/common.tsx

@@ -4,7 +4,7 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { State, Transform, StateObjectCell, Transformer } from 'mol-state';
+import { State, Transform, Transformer } from 'mol-state';
 import * as React from 'react';
 import { PurePluginComponent } from '../base';
 import { ParameterControls, ParamOnChange } from '../controls/parameters';
@@ -74,11 +74,13 @@ namespace StateTransformParameters {
 
     export function infoFromTransform(plugin: PluginContext, state: State, transform: Transform): Props['info'] {
         const cell = state.cells.get(transform.ref)!;
-        const source: StateObjectCell | undefined = (cell.sourceRef && state.cells.get(cell.sourceRef)!) || void 0;
-        const create = transform.transformer.definition.params;
-        const params = create ? create((source && source.obj) as any, plugin) : { };
+        // const source: StateObjectCell | undefined = (cell.sourceRef && state.cells.get(cell.sourceRef)!) || void 0;
+        // const create = transform.transformer.definition.params;
+        // const params = create ? create((source && source.obj) as any, plugin) : { };
+        const params = (cell.params && cell.params.definition) || { };
+        const initialValues = (cell.params && cell.params.values) || { };
         return {
-            initialValues: transform.params,
+            initialValues,
             params,
             isEmpty: areParamsEmpty(params)
         }

+ 1 - 1
src/mol-plugin/ui/state/update-transform.tsx

@@ -42,7 +42,7 @@ class UpdateTransformContol extends TransformContolBase<UpdateTransformContol.Pr
         if (!cell || !cell.sourceRef || cell.status !== 'ok') return false;
         const parentCell = state.cells.get(cell.sourceRef)!;
 
-        return autoUpdate({ a: cell.obj!, b: parentCell.obj!, oldParams: this.props.transform.params, newParams }, this.plugin);
+        return autoUpdate({ a: cell.obj!, b: parentCell.obj!, oldParams: this.getInfo().initialValues, newParams }, this.plugin);
     }
 
     private _getInfo = memoizeOne((t: Transform) => StateTransformParameters.infoFromTransform(this.plugin, this.props.state, this.props.transform));

+ 6 - 0
src/mol-state/object.ts

@@ -6,6 +6,7 @@
 
 import { UUID } from 'mol-util';
 import { Transform } from './transform';
+import { ParamDefinition } from 'mol-util/param-definition';
 
 export { StateObject, StateObjectCell }
 
@@ -59,6 +60,11 @@ interface StateObjectCell {
     version: string
     status: StateObjectCell.Status,
 
+    params: {
+        definition: ParamDefinition.Params,
+        values: any
+    } | undefined;
+
     errorText?: string,
     obj?: StateObject
 }

+ 25 - 19
src/mol-state/state.ts

@@ -154,7 +154,11 @@ class State {
             obj: rootObject,
             status: 'ok',
             version: root.version,
-            errorText: void 0
+            errorText: void 0,
+            params: {
+                definition: { },
+                values: { }
+            }
         });
 
         this.globalContext = params && params.globalContext;
@@ -369,7 +373,8 @@ function initCellsVisitor(transform: Transform, _: any, { ctx, added }: InitCell
         sourceRef: void 0,
         status: 'pending',
         version: UUID.create22(),
-        errorText: void 0
+        errorText: void 0,
+        params: void 0
     };
     ctx.cells.set(transform.ref, cell);
     added.push(cell);
@@ -430,12 +435,15 @@ function doError(ctx: UpdateContext, ref: Ref, errorText: string | undefined, si
         (ctx.parent as any as { errorFree: boolean }).errorFree = false;
     }
 
+    const cell = ctx.cells.get(ref)!;
+
     if (errorText) {
         setCellStatus(ctx, ref, 'error', errorText);
         if (!silent) ctx.parent.events.log.next({ type: 'error', timestamp: new Date(), message: errorText });
+    } else {
+        cell.params = void 0;
     }
 
-    const cell = ctx.cells.get(ref)!;
     if (cell.obj) {
         const obj = cell.obj;
         cell.obj = void 0;
@@ -494,19 +502,16 @@ async function updateSubtree(ctx: UpdateContext, root: Ref) {
     while (true) {
         const next = children.next();
         if (next.done) return;
-        if (isNull) doError(ctx, next.value, ParentNullErrorText, true);
+        if (isNull) doError(ctx, next.value, void 0, true);
         else await updateSubtree(ctx, next.value);
     }
 }
 
-function resolveDefaultParams(ctx: UpdateContext, transform: Transform, src: StateObject) {
+function resolveParams(ctx: UpdateContext, transform: Transform, src: StateObject) {
     const prms = transform.transformer.definition.params;
-    const defaults = prms
-        ? ParamDefinition.getDefaultValues(prms(src, ctx.parent.globalContext))
-        : { };
-    // TODO: this should probably be resolved each time separately the transform is applied.
-    // the params should be cached in the cell?
-    (transform.params as any) = defaults;
+    const definition = prms ? prms(src, ctx.parent.globalContext) : { };
+    const values = transform.params ? transform.params : ParamDefinition.getDefaultValues(definition);
+    return { definition, values };
 }
 
 async function updateNode(ctx: UpdateContext, currentRef: Ref): Promise<UpdateNodeResult> {
@@ -525,27 +530,28 @@ async function updateNode(ctx: UpdateContext, currentRef: Ref): Promise<UpdateNo
     const parent = parentCell.obj!;
     current.sourceRef = parentCell.transform.ref;
 
-    if (!transform.params) {
-        resolveDefaultParams(ctx, transform, parent);
-    }
+    const params = resolveParams(ctx, transform, parent);
 
-    if (!oldTree.transforms.has(currentRef)) {
-        const obj = await createObject(ctx, currentRef, transform.transformer, parent, transform.params);
+    if (!oldTree.transforms.has(currentRef) || !current.params) {
+        current.params = params;
+        const obj = await createObject(ctx, currentRef, transform.transformer, parent, params.values);
         current.obj = obj;
         current.version = transform.version;
 
         return { ref: currentRef, action: 'created', obj };
     } else {
-        const oldParams = oldTree.transforms.get(currentRef)!.params;
+        const oldParams = current.params.values;
+        const newParams = params.values;
+        current.params = params;
 
         const updateKind = !!current.obj && current.obj !== StateObject.Null
-            ? await updateObject(ctx, currentRef, transform.transformer, parent, current.obj!, oldParams, transform.params)
+            ? await updateObject(ctx, currentRef, transform.transformer, parent, current.obj!, oldParams, newParams)
             : Transformer.UpdateResult.Recreate;
 
         switch (updateKind) {
             case Transformer.UpdateResult.Recreate: {
                 const oldObj = current.obj;
-                const newObj = await createObject(ctx, currentRef, transform.transformer, parent, transform.params);
+                const newObj = await createObject(ctx, currentRef, transform.transformer, parent, newParams);
                 current.obj = newObj;
                 current.version = transform.version;
                 return { ref: currentRef, action: 'replaced', oldObj, obj: newObj };

+ 4 - 4
src/mol-state/transform.ts

@@ -13,7 +13,7 @@ export interface Transform<A extends StateObject = StateObject, B extends StateO
     readonly transformer: Transformer<A, B, P>,
     readonly props: Transform.Props,
     readonly ref: Transform.Ref,
-    readonly params: P,
+    readonly params?: P,
     readonly version: string
 }
 
@@ -40,7 +40,7 @@ export namespace Transform {
             transformer,
             props: (options && options.props) || { },
             ref,
-            params: params as any,
+            params,
             version: UUID.create22()
         }
     }
@@ -70,7 +70,7 @@ export namespace Transform {
         return {
             parent: t.parent,
             transformer: t.transformer.id,
-            params: pToJson(t.params),
+            params: t.params ? pToJson(t.params) : void 0,
             props: t.props,
             ref: t.ref,
             version: t.version
@@ -85,7 +85,7 @@ export namespace Transform {
         return {
             parent: t.parent as Ref,
             transformer,
-            params: pFromJson(t.params),
+            params: t.params ? pFromJson(t.params) : void 0,
             props: t.props,
             ref: t.ref as Ref,
             version: t.version