Browse Source

State.updateNode fix for Null parents (#807)

David Sehnal 1 year ago
parent
commit
eb749a2a16
2 changed files with 27 additions and 3 deletions
  1. 1 0
      CHANGELOG.md
  2. 26 3
      src/mol-state/state.ts

+ 1 - 0
CHANGELOG.md

@@ -9,6 +9,7 @@ Note that since we don't clearly distinguish between a public and private interf
 - Add a uniform color theme for NtC tube that still paints residue and segment dividers in a different color
 - Fix bond assignments `struct_conn` records referencing waters
 - Fix `PluginState.setSnapshot` triggering unnecessary state updates
+- Fix an edge case in the `mol-state`'s `State` when trying to apply a transform to an existing Null object
 - Add `SbNcbrPartialCharges` extension for coloring and labeling atoms and residues by partial atomic charges
   - uses custom mmcif categories `_sb_ncbr_partial_atomic_charges_meta` and `_sb_ncbr_partial_atomic_charges` (more info in [README.md](./src/extensions/sb-ncbr/README.md))
 

+ 26 - 3
src/mol-state/state.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  */
@@ -868,13 +868,36 @@ async function updateNode(ctx: UpdateContext, currentRef: Ref): Promise<UpdateNo
     const current = ctx.cells.get(currentRef)!;
     const transform = current.transform;
 
-    // special case for Root
+    // Special case for Root
     if (current.transform.ref === StateTransform.RootRef) {
         return { action: 'none' };
     }
 
+    const treeParent = ctx.cells.get(current.transform.parent);
+    const isParentNull = treeParent?.obj === StateObject.Null;
+
+    // Special case for when the immediate parent is null
+    // This could happen then manually applying transforms to
+    // already existing null nudes
+    if (isParentNull) {
+        current.sourceRef = treeParent.transform.ref;
+
+        if (oldTree.transforms.has(currentRef) && current.params) {
+            const oldParams = current.params.values;
+            const oldCache = current.cache;
+            dispose(transform, current.obj, oldParams, oldCache, ctx.parent.globalContext);
+
+            current.params = undefined;
+            current.obj = StateObject.Null;
+            return { ref: currentRef, action: 'updated', obj: current.obj! };
+        } else {
+            current.params = undefined;
+            return { ref: currentRef, action: 'created', obj: StateObject.Null };
+        }
+    }
+
     const parentCell = transform.transformer.definition.from.length === 0
-        ? ctx.cells.get(current.transform.parent)
+        ? treeParent
         : StateSelection.findAncestorOfType(tree, ctx.cells, currentRef, transform.transformer.definition.from);
     if (!parentCell) {
         throw new Error(`No suitable parent found for '${currentRef}'`);