ソースを参照

mol-plugin & state: fixes

David Sehnal 6 年 前
コミット
629f7c0cc8

+ 1 - 0
src/mol-plugin/behavior/built-in/state.ts

@@ -22,6 +22,7 @@ export function ApplyAction(ctx: PluginContext) {
 export function RemoveObject(ctx: PluginContext) {
     PluginCommands.State.RemoveObject.subscribe(ctx, ({ state, ref }) => {
         const tree = state.tree.build().delete(ref).getTree();
+        console.log('tree', tree);
         return ctx.runTask(state.update(tree));
     });
 }

+ 4 - 1
src/mol-plugin/context.ts

@@ -101,7 +101,10 @@ export class PluginContext {
     _test_initDataActions() {
         this.state.data.actions
             .add(CreateStructureFromPDBe)
-            .add(StateTransforms.Data.Download.toAction());
+            .add(StateTransforms.Data.Download)
+            .add(StateTransforms.Model.CreateStructureAssembly)
+            .add(StateTransforms.Model.CreateStructure)
+            .add(StateTransforms.Visuals.CreateStructureRepresentation);
     }
 
     applyTransform(state: State, a: Transform.Ref, transformer: Transformer, params: any) {

+ 1 - 3
src/mol-plugin/state/actions/basic.ts

@@ -42,7 +42,6 @@ export const CreateStructureFromPDBe = StateAction.create<PluginStateObject.Root
             .apply(StateTransforms.Data.ParseCif)
             .apply(StateTransforms.Model.ParseTrajectoryFromMmCif, {})
             .apply(StateTransforms.Model.CreateModelFromTrajectory, { modelIndex: 0 })
-            .apply(StateTransforms.Model.CreateStructureFromModel, { })
             .apply(StateTransforms.Model.CreateStructureAssembly)
             // .apply(StateTransforms.Model.CreateStructureSelection, { query, label: 'ALA residues' })
             .apply(StateTransforms.Visuals.CreateStructureRepresentation)
@@ -55,8 +54,7 @@ export const CreateStructureFromPDBe = StateAction.create<PluginStateObject.Root
 export const UpdateTrajectory = StateAction.create<PluginStateObject.Root, void, { action: 'advance' | 'reset', by?: number }>({
     from: [],
     display: {
-        name: 'Entry from PDBe',
-        description: 'Download a structure from PDBe and create its default Assembly and visual'
+        name: 'Update Trajectory'
     },
     params: {
         default: () => ({ action: 'reset', by: 1 })

+ 10 - 10
src/mol-plugin/state/transforms/model.ts

@@ -69,9 +69,9 @@ const CreateModelFromTrajectory = PluginStateTransform.Create<SO.Molecule.Trajec
     }
 });
 
-export { CreateStructureFromModel }
-namespace CreateStructureFromModel { export interface Params { transform3d?: Mat4 } }
-const CreateStructureFromModel = PluginStateTransform.Create<SO.Molecule.Model, SO.Molecule.Structure, CreateStructureFromModel.Params>({
+export { CreateStructure }
+namespace CreateStructure { export interface Params { transform3d?: Mat4 } }
+const CreateStructure = PluginStateTransform.Create<SO.Molecule.Model, SO.Molecule.Structure, CreateStructure.Params>({
     name: 'create-structure-from-model',
     display: {
         name: 'Structure from Model',
@@ -93,32 +93,32 @@ function structureDesc(s: Structure) {
 
 export { CreateStructureAssembly }
 namespace CreateStructureAssembly { export interface Params { /** if not specified, use the 1st */ id?: string } }
-const CreateStructureAssembly = PluginStateTransform.Create<SO.Molecule.Structure, SO.Molecule.Structure, CreateStructureAssembly.Params>({
+const CreateStructureAssembly = PluginStateTransform.Create<SO.Molecule.Model, SO.Molecule.Structure, CreateStructureAssembly.Params>({
     name: 'create-structure-assembly',
     display: {
         name: 'Structure Assembly',
         description: 'Create a molecular structure assembly.'
     },
-    from: [SO.Molecule.Structure],
+    from: [SO.Molecule.Model],
     to: [SO.Molecule.Structure],
     params: {
         default: () => ({ id: void 0 }),
         controls(a) {
-            const { model } = a.data;
+            const model = a.data;
             const ids = model.symmetry.assemblies.map(a => [a.id, a.id] as [string, string]);
             return { id: PD.Select('Asm Id', 'Assembly Id', ids.length ? ids[0][0] : '', ids) };
         }
     },
-    isApplicable: a => a.data.models.length === 1 && a.data.model.symmetry.assemblies.length > 0,
     apply({ a, params }) {
         return Task.create('Build Assembly', async ctx => {
             let id = params.id;
-            const model = a.data.model;
+            const model = a.data;
             if (!id && model.symmetry.assemblies.length) id = model.symmetry.assemblies[0].id;
-            const asm = ModelSymmetry.findAssembly(a.data.model, id || '');
+            const asm = ModelSymmetry.findAssembly(model, id || '');
             if (!asm) throw new Error(`Assembly '${id}' not found`);
 
-            const s = await StructureSymmetry.buildAssembly(a.data, id!).runInContext(ctx);
+            const base = Structure.ofModel(model);
+            const s = await StructureSymmetry.buildAssembly(base, id!).runInContext(ctx);
             const label = { label: `Assembly ${id}`, description: structureDesc(s) };
             return new SO.Molecule.Structure(s, label);
         })

+ 4 - 2
src/mol-plugin/ui/controls.tsx

@@ -100,11 +100,13 @@ export class _test_ApplyAction extends React.Component<{ plugin: PluginContext,
         const action = this.props.action;
 
         return <div key={`${this.props.nodeRef} ${this.props.action.id}`}>
-            <div style={{ borderBottom: '1px solid #999' }}><h3>{(action.definition.display && action.definition.display.name) || action.id}</h3></div>
+            <div style={{ borderBottom: '1px solid #999', marginBottom: '5px' }}><h3>{(action.definition.display && action.definition.display.name) || action.id}</h3></div>
             <ParametersComponent params={this.getParamDef()} values={this.state.params as any} onChange={(k, v) => {
                 this.setState({ params: { ...this.state.params, [k]: v } });
             }} />
-            <button onClick={() => this.create()} style={{ width: '100%' }}>Create</button>
+            <div style={{ textAlign: 'right' }}>
+                <button onClick={() => this.create()}>Create</button>
+            </div>
         </div>
     }
 }

+ 4 - 1
src/mol-state/action/manager.ts

@@ -6,6 +6,7 @@
 
 import { StateAction } from 'mol-state/action';
 import { StateObject } from '../object';
+import { Transformer } from 'mol-state/transformer';
 
 export { StateActionManager }
 
@@ -13,7 +14,9 @@ class StateActionManager {
     private actions: Map<StateAction['id'], StateAction> = new Map();
     private fromTypeIndex = new Map<StateObject.Type, StateAction[]>();
 
-    add(action: StateAction) {
+    add(actionOrTransformer: StateAction | Transformer) {
+        const action = Transformer.is(actionOrTransformer) ? actionOrTransformer.toAction() : actionOrTransformer;
+
         if (this.actions.has(action.id)) return this;
 
         this.actions.set(action.id, action);

+ 4 - 0
src/mol-state/transformer.ts

@@ -25,6 +25,10 @@ export namespace Transformer {
     export type To<T extends Transformer<any, any, any>> = T extends Transformer<any, infer B, any> ? B : unknown;
     export type ControlsFor<Props> = { [P in keyof Props]?: PD.Any }
 
+    export function is(obj: any): obj is Transformer {
+        return !!obj && typeof (obj as Transformer).toAction === 'function' && typeof (obj as Transformer).apply === 'function';
+    }
+
     export interface ApplyParams<A extends StateObject = StateObject, P = unknown> {
         a: A,
         params: P,

+ 4 - 0
src/mol-state/tree/transient.ts

@@ -71,6 +71,10 @@ class TransientTree implements StateTree {
         const parent = Transform.RootRef;
         if (this.children.get(parent).size === 0) return;
         const set = OrderedSet<Transform.Ref>();
+        if (!this.changedChildren) {
+            this.changedChildren = true;
+            this.children = this.children.asMutable();
+        }
         this.children.set(parent, set);
         this.mutations.set(parent, set);
     }