Browse Source

added StateSelection.rootOfType, PluginBehavior can now "auto update"

David Sehnal 6 years ago
parent
commit
21aae7ecbe

+ 3 - 1
src/mol-plugin/behavior/behavior.ts

@@ -32,6 +32,7 @@ namespace PluginBehavior {
     export interface CreateParams<P> {
         name: string,
         ctor: Ctor<P>,
+        canAutoUpdate?: Transformer.Definition<Root, Behavior, P>['canAutoUpdate'],
         label?: (params: P) => { label: string, description?: string },
         display: {
             name: string,
@@ -59,7 +60,8 @@ namespace PluginBehavior {
                     const updated = await b.data.update(newParams);
                     return updated ? Transformer.UpdateResult.Updated : Transformer.UpdateResult.Unchanged;
                 })
-            }
+            },
+            canAutoUpdate: params.canAutoUpdate
         });
     }
 

+ 2 - 12
src/mol-plugin/behavior/dynamic/animation.ts

@@ -31,6 +31,7 @@ type StructureAnimationProps = PD.Values<typeof StructureAnimationParams>
 export const StructureAnimation = PluginBehavior.create<StructureAnimationProps>({
     name: 'structure-animation',
     display: { name: 'Structure Animation', group: 'Animation' },
+    canAutoUpdate: () => true,
     ctor: class extends PluginBehavior.Handler<StructureAnimationProps> {
         private tmpMat = Mat4.identity()
         private rotMat = Mat4.identity()
@@ -186,16 +187,5 @@ export const StructureAnimation = PluginBehavior.create<StructureAnimationProps>
 //
 
 function getRootStructure(root: StateObjectCell, state: State) {
-    let parent: StateObjectCell | undefined
-    while (true) {
-        const _parent = StateSelection.findAncestorOfType(state.tree, state.cells, root.transform.ref, [PluginStateObject.Molecule.Structure])
-        if (_parent) {
-            parent = _parent
-            root = _parent
-        } else {
-            break
-        }
-    }
-    return parent ? parent :
-        SO.Molecule.Structure.is(root.obj) ? root : undefined
+    return state.query(StateSelection.Generators.byValue(root).rootOfType([PluginStateObject.Molecule.Structure]))[0];
 }

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

@@ -98,6 +98,15 @@ class State {
         return StateSelection.select(selector(StateSelection.Generators), this)
     }
 
+    /**
+     * Select Cells using the provided selector.
+     * @example state.select('test')
+     * @example state.select(q => q.byRef('test').subtree())
+     */
+    query(selector: StateSelection.Selector) {
+        return StateSelection.select(selector, this)
+    }
+
     /** If no ref is specified, apply to root */
     apply<A extends StateAction>(action: A, params: StateAction.Params<A>, ref: Transform.Ref = Transform.RootRef): Task<void> {
         return Task.create('Apply Action', ctx => {

+ 19 - 1
src/mol-state/state/selection.ts

@@ -52,7 +52,8 @@ namespace StateSelection {
         subtree(): Builder;
         children(): Builder;
         ofType(t: StateObject.Ctor): Builder;
-        ancestorOfType(t: StateObject.Ctor): Builder;
+        ancestorOfType(t: StateObject.Ctor[]): Builder;
+        rootOfType(t: StateObject.Ctor[]): Builder;
 
         select(state: State): CellSeq
     }
@@ -189,6 +190,9 @@ namespace StateSelection {
     registerModifier('ancestorOfType', ancestorOfType);
     export function ancestorOfType(b: Selector, types: StateObject.Ctor[]) { return unique(mapEntity(b, (n, s) => findAncestorOfType(s.tree, s.cells, n.transform.ref, types))); }
 
+    registerModifier('rootOfType', rootOfType);
+    export function rootOfType(b: Selector, types: StateObject.Ctor[]) { return unique(mapEntity(b, (n, s) => findRootOfType(s.tree, s.cells, n.transform.ref, types))); }
+
     registerModifier('parent', parent);
     export function parent(b: Selector) { return unique(mapEntity(b, (n, s) => s.cells.get(s.tree.transforms.get(n.transform.ref)!.parent))); }
 
@@ -207,6 +211,20 @@ namespace StateSelection {
             }
         }
     }
+
+    export function findRootOfType(tree: StateTree, cells: State.Cells, root: Transform.Ref, types: StateObject.Ctor[]): StateObjectCell | undefined {
+        let parent: StateObjectCell | undefined, _root = root;
+        while (true) {
+            const _parent = StateSelection.findAncestorOfType(tree, cells, _root, types);
+            if (_parent) {
+                parent = _parent;
+                _root = _parent.transform.ref;
+            } else {
+                break;
+            }
+        }
+        return parent;
+    }
 }
 
 export { StateSelection }