diff --git a/CHANGELOG.md b/CHANGELOG.md index 158c328111cf473c2c9e4fed40e8ec81ece021be..ecfc32d681d13c6ab64e2975fa890667966368b1 100644 --- a/CHANGELOG.md +++ b/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)) diff --git a/src/mol-state/state.ts b/src/mol-state/state.ts index 1602278c840eb9b0e07c5f901e3d6dc644cb9a91..83ed3fcbb661d7b304f93e5a5c7b05410da4a80c 100644 --- a/src/mol-state/state.ts +++ b/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}'`);