From 05b8abc2ae48ea3fa0706b98e8aa36108538a378 Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Sat, 10 Nov 2018 12:48:31 +0100 Subject: [PATCH] mol-state: added Transform.tag, refactoring --- src/mol-plugin/ui/controls.tsx | 28 +++++++++++--------- src/mol-state/object.ts | 8 +++--- src/mol-state/state.ts | 44 +++++++++++++++++++------------- src/mol-state/state/selection.ts | 12 ++++----- src/mol-state/transform.ts | 17 +++++++----- 5 files changed, 64 insertions(+), 45 deletions(-) diff --git a/src/mol-plugin/ui/controls.tsx b/src/mol-plugin/ui/controls.tsx index 42d6dc0ff..1e6e881ad 100644 --- a/src/mol-plugin/ui/controls.tsx +++ b/src/mol-plugin/ui/controls.tsx @@ -91,21 +91,24 @@ export class _test_CreateTransform extends React.Component<{ plugin: PluginConte } export class _test_UpdateTransform extends React.Component<{ plugin: PluginContext, state: State, nodeRef: Transform.Ref }, { params: any }> { - private getTransform() { - return this.props.state.tree.nodes.get(this.props.nodeRef)!; + private getCell(ref?: string) { + return this.props.state.cells.get(ref || this.props.nodeRef)!; } - private getParamDef() { - const def = this.getTransform().transformer.definition; - if (!def.params || !def.params.controls) return void 0; - - const src = this.props.state.select(q => q.byRef(this.props.nodeRef).ancestorOfType(def.from))[0]; - - // StateSelection.ancestorOfType(this.props.nodeRef, def.from).select(this.props.plugin.state.data)[0]; + private getDefParams() { + const cell = this.getCell(); + if (!cell) return { }; + return cell.transform.params; + } - console.log(src, def.from); + private getParamDef() { + const cell = this.getCell(); + const def = cell.transform.transformer.definition; + if (!cell.sourceRef || !def.params || !def.params.controls) return void 0; + const src = this.getCell(cell.sourceRef); if (!src || !src.obj) return void 0; + return def.params.controls(src.obj, this.props.plugin); } @@ -119,10 +122,11 @@ export class _test_UpdateTransform extends React.Component<{ plugin: PluginConte // if (t) this.setState({ params: t.value.params }); // } - state = { params: this.getTransform() ? this.getTransform().params : { } }; + state = { params: this.getDefParams() }; render() { - const transform = this.getTransform(); + const cell = this.getCell(); + const transform = cell.transform; if (!transform || transform.ref === Transform.RootRef) { return <div />; } diff --git a/src/mol-state/object.ts b/src/mol-state/object.ts index 831885b05..a7d3bbc85 100644 --- a/src/mol-state/object.ts +++ b/src/mol-state/object.ts @@ -36,12 +36,14 @@ namespace StateObject { } interface StateObjectCell { - ref: Transform.Ref, + transform: Transform, + + // Which object was used as a parent to create data in this cell + sourceRef: Transform.Ref | undefined, + version: string status: StateObjectCell.Status, - state: unknown, - errorText?: string, obj?: StateObject } diff --git a/src/mol-state/state.ts b/src/mol-state/state.ts index 57693439e..f8a54885b 100644 --- a/src/mol-state/state.ts +++ b/src/mol-state/state.ts @@ -109,11 +109,11 @@ class State { const root = tree.root; (this.cells as Map<Transform.Ref, StateObjectCell>).set(root.ref, { - ref: root.ref, + transform: root, + sourceRef: void 0, obj: rootObject, status: 'ok', - version: root.version, - state: { ...StateObjectCell.DefaultState } + version: root.version }); this.globalContext = params && params.globalContext; @@ -216,11 +216,11 @@ function _initCellsVisitor(transform: Transform, _: any, ctx: UpdateContext) { if (ctx.cells.has(transform.ref)) return; const obj: StateObjectCell = { - ref: transform.ref, + transform, + sourceRef: void 0, status: 'pending', version: UUID.create(), - errorText: void 0, - state: { ...StateObjectCell.DefaultState, ...transform.cellState } + errorText: void 0 }; ctx.cells.set(transform.ref, obj); @@ -250,15 +250,16 @@ function doError(ctx: UpdateContext, ref: Ref, errorText: string) { } } -function findAncestor(tree: StateTree, cells: State.Cells, root: Ref, types: { type: StateObject.Type }[]): StateObject { +function findAncestor(tree: StateTree, cells: State.Cells, root: Ref, types: { type: StateObject.Type }[]): StateObjectCell | undefined { let current = tree.nodes.get(root)!; while (true) { current = tree.nodes.get(current.parent)!; + const cell = cells.get(current.ref)!; + if (!cell.obj) return void 0; + for (const t of types) if (cell.obj.type === t.type) return cells.get(current.ref)!; if (current.ref === Transform.RootRef) { - return cells.get(Transform.RootRef)!.obj!; + return void 0; } - const obj = cells.get(current.ref)!.obj!; - for (const t of types) if (obj.type === t.type) return cells.get(current.ref)!.obj!; } } @@ -289,23 +290,30 @@ async function updateSubtree(ctx: UpdateContext, root: Ref) { } async function updateNode(ctx: UpdateContext, currentRef: Ref) { - const { oldTree, tree, cells } = ctx; + const { oldTree, tree } = ctx; const transform = tree.nodes.get(currentRef); - const parent = findAncestor(tree, cells, currentRef, transform.transformer.definition.from); + const parentCell = findAncestor(tree, ctx.cells, currentRef, transform.transformer.definition.from); + + if (!parentCell) { + throw new Error(`No suitable parent found for '${currentRef}'`); + } + + const parent = parentCell.obj!; + const current = ctx.cells.get(currentRef)!; + current.sourceRef = parentCell.transform.ref; + // console.log('parent', transform.transformer.id, transform.transformer.definition.from[0].type, parent ? parent.ref : 'undefined') - if (!oldTree.nodes.has(currentRef) || !cells.has(currentRef)) { + if (!oldTree.nodes.has(currentRef)) { // console.log('creating...', transform.transformer.id, oldTree.nodes.has(currentRef), objects.has(currentRef)); const obj = await createObject(ctx, currentRef, transform.transformer, parent, transform.params); - const cell = cells.get(currentRef)!; - cell.obj = obj; - cell.version = transform.version; + current.obj = obj; + current.version = transform.version; return { action: 'created', obj }; } else { - const current = cells.get(currentRef)!; const oldParams = oldTree.nodes.get(currentRef)!.params; - const updateKind = current.status === 'ok' || current.ref === Transform.RootRef + const updateKind = current.status === 'ok' || current.transform.ref === Transform.RootRef ? await updateObject(ctx, currentRef, transform.transformer, parent, current.obj!, oldParams, transform.params) : Transformer.UpdateResult.Recreate; diff --git a/src/mol-state/state/selection.ts b/src/mol-state/state/selection.ts index 9bbacebc3..6a045890d 100644 --- a/src/mol-state/state/selection.ts +++ b/src/mol-state/state/selection.ts @@ -123,8 +123,8 @@ namespace StateSelection { const set = new Set<string>(); const ret: StateObjectCell[] = []; for (const n of q(state)) { - if (!set.has(n.ref)) { - set.add(n.ref); + if (!set.has(n.transform.ref)) { + set.add(n.transform.ref); ret.push(n); } } @@ -151,7 +151,7 @@ namespace StateSelection { export function subtree(b: Selector) { return flatMap(b, (n, s) => { const nodes = [] as string[]; - StateTree.doPreOrder(s.tree, s.tree.nodes.get(n.ref), nodes, (x, _, ctx) => { ctx.push(x.ref) }); + StateTree.doPreOrder(s.tree, s.tree.nodes.get(n.transform.ref), nodes, (x, _, ctx) => { ctx.push(x.ref) }); return nodes.map(x => s.cells.get(x)!); }); } @@ -160,7 +160,7 @@ namespace StateSelection { export function children(b: Selector) { return flatMap(b, (n, s) => { const nodes: StateObjectCell[] = []; - s.tree.children.get(n.ref).forEach(c => nodes.push(s.cells.get(c!)!)); + s.tree.children.get(n.transform.ref).forEach(c => nodes.push(s.cells.get(c!)!)); return nodes; }); } @@ -169,10 +169,10 @@ namespace StateSelection { export function ofType(b: Selector, t: StateObject.Type) { return filter(b, n => n.obj ? n.obj.type === t : false); } registerModifier('ancestorOfType', ancestorOfType); - export function ancestorOfType(b: Selector, types: StateObject.Ctor[]) { return unique(mapEntity(b, (n, s) => findAncestorOfType(s, n.ref, types))); } + export function ancestorOfType(b: Selector, types: StateObject.Ctor[]) { return unique(mapEntity(b, (n, s) => findAncestorOfType(s, n.transform.ref, types))); } registerModifier('parent', parent); - export function parent(b: Selector) { return unique(mapEntity(b, (n, s) => s.cells.get(s.tree.nodes.get(n.ref)!.parent))); } + export function parent(b: Selector) { return unique(mapEntity(b, (n, s) => s.cells.get(s.tree.nodes.get(n.transform.ref)!.parent))); } function findAncestorOfType({ tree, cells }: State, root: string, types: StateObject.Ctor[]): StateObjectCell | undefined { let current = tree.nodes.get(root)!, len = types.length; diff --git a/src/mol-state/transform.ts b/src/mol-state/transform.ts index 791eaf3a2..c0203be3d 100644 --- a/src/mol-state/transform.ts +++ b/src/mol-state/transform.ts @@ -14,7 +14,8 @@ export interface Transform<A extends StateObject = StateObject, B extends StateO readonly params: P, readonly ref: Transform.Ref, readonly version: string, - readonly cellState?: Partial<StateObjectCell.State> + readonly cellState?: Partial<StateObjectCell.State>, + readonly tag?: string } export namespace Transform { @@ -22,7 +23,7 @@ export namespace Transform { export const RootRef = '-=root=-' as Ref; - export interface Options { ref?: Ref, cellState?: Partial<StateObjectCell.State> } + export interface Options { ref?: Ref, tag?: string, cellState?: Partial<StateObjectCell.State> } export function create<A extends StateObject, B extends StateObject, P>(parent: Ref, transformer: Transformer<A, B, P>, params?: P, options?: Options): Transform<A, B, P> { const ref = options && options.ref ? options.ref : UUID.create() as string as Ref; @@ -32,7 +33,8 @@ export namespace Transform { params: params || {} as any, ref, version: UUID.create(), - cellState: options && options.cellState + cellState: options && options.cellState, + tag: options && options.tag } } @@ -50,7 +52,8 @@ export namespace Transform { params: any, ref: string, version: string, - cellState?: Partial<StateObjectCell.State> + cellState?: Partial<StateObjectCell.State>, + tag?: string } function _id(x: any) { return x; } @@ -64,7 +67,8 @@ export namespace Transform { params: pToJson(t.params), ref: t.ref, version: t.version, - cellState: t.cellState + cellState: t.cellState, + tag: t.tag }; } @@ -79,7 +83,8 @@ export namespace Transform { params: pFromJson(t.params), ref: t.ref as Ref, version: t.version, - cellState: t.cellState + cellState: t.cellState, + tag: t.tag }; } } \ No newline at end of file -- GitLab