diff --git a/src/mol-plugin/ui/state/common.tsx b/src/mol-plugin/ui/state/common.tsx index 13c1127003fa784628283831752b528d5c7e9bf2..a56615a85ba7e4579d5eb6626b204189726539f5 100644 --- a/src/mol-plugin/ui/state/common.tsx +++ b/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) } diff --git a/src/mol-plugin/ui/state/update-transform.tsx b/src/mol-plugin/ui/state/update-transform.tsx index c0fa6982706453424f3a1e9fac036975d9edc1c4..1ac950fdc09f2fb021e4a108863cd9149e23e3c4 100644 --- a/src/mol-plugin/ui/state/update-transform.tsx +++ b/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)); diff --git a/src/mol-state/object.ts b/src/mol-state/object.ts index 70917c833285e631724179cfbcaae71b7a18cca9..a2cdfbb0f5a5df67f6df1f191e915dfa3f23d668 100644 --- a/src/mol-state/object.ts +++ b/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 } diff --git a/src/mol-state/state.ts b/src/mol-state/state.ts index a08f5f0d0d2aa20b28f22e99243c1e65e48becc6..4a0dfcb42e811ef2048ff5db6d7a9ae513c735bc 100644 --- a/src/mol-state/state.ts +++ b/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 }; diff --git a/src/mol-state/transform.ts b/src/mol-state/transform.ts index 6637949f202f7260a609bfecbb42153606eed6f6..86edad5a9e06d2fd28e0ed74c76b1a4085c046a6 100644 --- a/src/mol-state/transform.ts +++ b/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