Browse Source

fix Mat4Control in Firefox, track Transform in StructureHierarchy, fix findUpdateRoots when there is error

David Sehnal 5 years ago
parent
commit
c592b8a53f

+ 34 - 2
src/mol-plugin-state/manager/structure/hierarchy-state.ts

@@ -22,6 +22,8 @@ export interface StructureHierarchy {
     models: ModelRef[],
     structures: StructureRef[],
     refs: Map<StateTransform.Ref, HierarchyRef>
+    // TODO: might be needed in the future
+    // decorators: Map<StateTransform.Ref, StateTransform>,
 }
 
 export function StructureHierarchy(): StructureHierarchy {
@@ -37,7 +39,7 @@ interface RefBase<K extends string = string, O extends StateObject = StateObject
 export type HierarchyRef =
     | TrajectoryRef
     | ModelRef | ModelPropertiesRef | ModelUnitcellRef
-    | StructureRef | StructurePropertiesRef | StructureVolumeStreamingRef | StructureComponentRef | StructureRepresentationRef
+    | StructureRef | StructurePropertiesRef | StructureTransformRef | StructureVolumeStreamingRef | StructureComponentRef | StructureRepresentationRef
     | GenericRepresentationRef
 
 export interface TrajectoryRef extends RefBase<'trajectory', SO.Molecule.Trajectory> {
@@ -79,6 +81,7 @@ function ModelUnitcellRef(cell: StateObjectCell<SO.Shape.Representation3D>, mode
 export interface StructureRef extends RefBase<'structure', SO.Molecule.Structure> {
     model?: ModelRef,
     properties?: StructurePropertiesRef,
+    transform?: StructureTransformRef,
     components: StructureComponentRef[],
     genericRepresentations?: GenericRepresentationRef[],
     volumeStreaming?: StructureVolumeStreamingRef
@@ -96,6 +99,14 @@ function StructurePropertiesRef(cell: StateObjectCell<SO.Molecule.Structure>, st
     return { kind: 'structure-properties', cell, version: cell.transform.version, structure };
 }
 
+export interface StructureTransformRef extends RefBase<'structure-transform', SO.Molecule.Structure, StateTransforms['Model']['TransformStructureConformation']> {
+    structure: StructureRef
+}
+
+function StructureTransformRef(cell: StateObjectCell<SO.Molecule.Structure>, structure: StructureRef): StructureTransformRef {
+    return { kind: 'structure-transform', cell, version: cell.transform.version, structure };
+}
+
 export interface StructureVolumeStreamingRef extends RefBase<'structure-volume-streaming', VolumeStreaming, CreateVolumeStreamingBehavior> {
     structure: StructureRef
 }
@@ -237,6 +248,10 @@ const Mapping: [TestCell, ApplyRef, LeaveRef][] = [
         if (!state.currentStructure) return false;
         state.currentStructure.properties = createOrUpdateRef(state, cell, StructurePropertiesRef, cell, state.currentStructure);
     }, noop],
+    [isTransformer(StateTransforms.Model.TransformStructureConformation), (state, cell) => {
+        if (!state.currentStructure) return false;
+        state.currentStructure.transform = createOrUpdateRef(state, cell, StructureTransformRef, cell, state.currentStructure);
+    }, noop],
 
     // Volume Streaming
     [isType(VolumeStreaming), (state, cell) => {
@@ -300,17 +315,34 @@ function _doPreOrder(ctx: VisitorCtx, root: StateTransform) {
     if (!isValidCell(cell)) return;
 
     let onLeave: undefined | ((state: BuildState) => any) = void 0;
+    let end = false;
     for (const [test, f, l] of Mapping) {
         if (test(cell, state)) {
             const cont = f(state, cell);
             if (cont === false) {
-                return;
+                end = true;
+                break;
             }
             onLeave = l;
             break;
         }
     }
 
+    // TODO: might be needed in the future
+    // const { currentComponent, currentModel, currentStructure, currentTrajectory } = ctx.state;
+    // const inTrackedSubtree = currentComponent || currentModel || currentStructure || currentTrajectory;
+
+    // if (inTrackedSubtree && cell.transform.transformer.definition.isDecorator) {
+    //     const ref = cell.transform.ref;
+    //     const old = ctx.state.oldHierarchy.decorators.get(ref);
+    //     if (old && old.version !== cell.transform.version) {
+    //         ctx.state.changed = true;
+    //     }
+    //     ctx.state.hierarchy.decorators.set(cell.transform.ref, cell.transform);
+    // }
+
+    if (end) return;
+
     const children = ctx.tree.children.get(root.ref);
     if (children && children.size) {
         children.forEach(_preOrderFunc, ctx);

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

@@ -416,8 +416,8 @@ const TransformStructureConformation = PluginStateTransform.BuiltIn({
         }, { label: 'Kind' })
     }
 })({
-    canAutoUpdate() {
-        return true;
+    canAutoUpdate({ newParams }) {
+        return newParams.transform.name !== 'matrix';
     },
     apply({ a, params }) {
         // TODO: optimze

+ 2 - 0
src/mol-plugin-ui/controls/common.tsx

@@ -97,6 +97,8 @@ export class TextInput<T = string> extends React.PureComponent<TextInputProps<T>
     }
 
     raiseOnChange = () => {
+        if (this.pendingValue === void 0) return;
+
         this.props.onChange(this.pendingValue!);
         this.pendingValue = void 0;
     }

+ 1 - 0
src/mol-plugin-ui/skin/base/components/misc.scss

@@ -534,6 +534,7 @@
 .msp-parameter-matrix {
     input {
         flex: 1 1 auto;
+        min-width: 0;
     }
 }
 

+ 1 - 0
src/mol-plugin-ui/structure/source.tsx

@@ -254,6 +254,7 @@ export class StructureSourceControls extends CollapsableControls<{}, StructureSo
         const pivot = selection.structures[0];
         const t = StateSelection.tryFindDecorator(this.plugin.state.data, pivot.cell.transform.ref, StateTransforms.Model.TransformStructureConformation);
         if (!t) return;
+
         return <ExpandGroup header={`Conformation Transform`}>
             <UpdateTransformControl state={t.parent!} transform={t.transform} customHeader='none' noMargin autoHideApply />
         </ExpandGroup>;

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

@@ -449,8 +449,7 @@ interface UpdateContext {
 
 async function update(ctx: UpdateContext) {
     // if only a single node was added/updated, we can skip potentially expensive diffing
-    const fastTrack = !!(ctx.errorFree && ctx.editInfo && ctx.editInfo.count === 1 && ctx.editInfo.lastUpdate && ctx.editInfo.sourceTree === ctx.oldTree);
-
+    const fastTrack = !!(ctx.editInfo && ctx.editInfo.count === 1 && ctx.editInfo.lastUpdate && ctx.editInfo.sourceTree === ctx.oldTree);
     let deletes: StateTransform.Ref[], deletedObjects: (StateObject | undefined)[] = [], roots: StateTransform.Ref[];
 
     if (fastTrack) {
@@ -572,10 +571,12 @@ function findUpdateRoots(cells: Map<StateTransform.Ref, StateObjectCell>, tree:
 
 function findUpdateRootsVisitor(n: StateTransform, _: any, s: { roots: Ref[], cells: Map<Ref, StateObjectCell> }) {
     const cell = s.cells.get(n.ref);
-    if (!cell || cell.transform.version !== n.version || cell.status === 'error') {
-        if (cell?.status !== 'error') s.roots.push(n.ref);
+    if (!cell || cell.transform.version !== n.version) {
+        s.roots.push(n.ref);
         return false;
     }
+    if (cell.status === 'error') return false;
+
     // nothing below a Null object can be an update root
     if (cell && cell.obj === StateObject.Null) return false;
     return true;