diff --git a/src/apps/viewer/extensions/cellpack/model.ts b/src/apps/viewer/extensions/cellpack/model.ts index 11d692bd373276a347204a4e27f0a568e5f49d11..e43e7e5144c8472d01c49cef7f6ef8b7d86d647a 100644 --- a/src/apps/viewer/extensions/cellpack/model.ts +++ b/src/apps/viewer/extensions/cellpack/model.ts @@ -321,19 +321,19 @@ async function handleHivRna(ctx: { runtime: RuntimeContext, fetch: AjaxTask }, p async function loadHivMembrane(plugin: PluginContext, runtime: RuntimeContext, state: State, params: LoadCellPackModelParams) { const url = `${params.baseUrl}/membranes/hiv_lipids.bcif` - const membrane = state.build().toRoot() + const membrane = await state.build().toRoot() .apply(StateTransforms.Data.Download, { label: 'hiv_lipids', url, isBinary: true }, { state: { isGhost: true } }) .apply(StateTransforms.Data.ParseCif, undefined, { state: { isGhost: true } }) .apply(StateTransforms.Model.TrajectoryFromMmCif, undefined, { state: { isGhost: true } }) .apply(StateTransforms.Model.ModelFromTrajectory, undefined, { state: { isGhost: true } }) .apply(StateTransforms.Model.StructureFromModel) - await membrane.commit() + .commit() const membraneParams = { representation: params.preset.representation, } - await CellpackMembranePreset.apply(membrane.selector, membraneParams, plugin) + await CellpackMembranePreset.apply(membrane, membraneParams, plugin) } async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, state: State, params: LoadCellPackModelParams) { @@ -364,10 +364,12 @@ async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, stat for (let i = 0, il = packings.length; i < il; ++i) { const p = { packing: i, baseUrl: params.baseUrl, ingredientFiles: params.ingredients.files } - const packing = state.build().to(cellPackBuilder.ref).apply(StructureFromCellpack, p) - await plugin.updateDataState(packing, { revertOnError: true }); + const packing = await state.build() + .to(cellPackBuilder.ref) + .apply(StructureFromCellpack, p) + .commit({ revertOnError: true }) - const structure = packing.selector.obj?.data + const structure = packing.obj?.data if (structure) { await CellPackInfoProvider.attach({ fetch: plugin.fetch, runtime }, structure, { info: { packingsCount: packings.length, packingIndex: i } @@ -378,7 +380,7 @@ async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, stat traceOnly: params.preset.traceOnly, representation: params.preset.representation, } - await CellpackPackingPreset.apply(packing.selector, packingParams, plugin) + await CellpackPackingPreset.apply(packing, packingParams, plugin) } } diff --git a/src/apps/viewer/extensions/cellpack/preset.ts b/src/apps/viewer/extensions/cellpack/preset.ts index fdb94b64f8dd8d31e7431ff557e11b9b48c37ecf..fd6a2361da6931152d0ea1d692906d1a454e9f1e 100644 --- a/src/apps/viewer/extensions/cellpack/preset.ts +++ b/src/apps/viewer/extensions/cellpack/preset.ts @@ -46,7 +46,7 @@ export const CellpackPackingPreset = StructureRepresentationPresetProvider({ polymer: builder.buildRepresentation<any>(update, components.polymer, { type: params.representation, typeParams: { ...typeParams, ...reprProps }, color }, { tag: 'polymer' }) }; - await plugin.updateDataState(update, { revertOnError: true }); + await update.commit({ revertOnError: true }) return { components, representations }; } }); @@ -84,7 +84,7 @@ export const CellpackMembranePreset = StructureRepresentationPresetProvider({ membrane: builder.buildRepresentation(update, components.membrane, { type: 'gaussian-surface', typeParams: { ...typeParams, ...reprProps }, color: 'uniform', colorParams: { value: ColorNames.lightgrey } }, { tag: 'all' }) }; - await plugin.updateDataState(update, { revertOnError: true }); + await update.commit({ revertOnError: true }) return { components, representations }; } }); \ No newline at end of file diff --git a/src/mol-plugin-state/animation/built-in.ts b/src/mol-plugin-state/animation/built-in.ts index f804def83bf3acc7c89461d0527636d1c8653c1b..f3fde2bb93d40f71e35ef8a1dac3943eeb0dfae2 100644 --- a/src/mol-plugin-state/animation/built-in.ts +++ b/src/mol-plugin-state/animation/built-in.ts @@ -105,7 +105,7 @@ export const AnimateAssemblyUnwind = PluginStateAnimation.create({ }; }, initialState: () => ({ t: 0 }), - async setup(params, plugin) { + setup(params, plugin) { const state = plugin.state.data; const root = !params.target || params.target === 'all' ? StateTransform.RootRef : params.target; const reprs = state.select(StateSelection.Generators.ofType(PluginStateObject.Molecule.Structure.Representation3D, root)); @@ -123,9 +123,9 @@ export const AnimateAssemblyUnwind = PluginStateAnimation.create({ if (!changed) return; - return plugin.updateDataState(update, { doNotUpdateCurrent: true }); + return update.commit({ doNotUpdateCurrent: true }); }, - async teardown(_, plugin) { + teardown(_, plugin) { const state = plugin.state.data; const reprs = state.select(StateSelection.Generators.ofType(PluginStateObject.Molecule.Structure.Representation3DState) .withTag('animate-assembly-unwind')); @@ -133,7 +133,7 @@ export const AnimateAssemblyUnwind = PluginStateAnimation.create({ const update = state.build(); for (const r of reprs) update.delete(r.transform.ref); - return plugin.updateDataState(update); + return update.commit(); }, async apply(animState, t, ctx) { const state = ctx.plugin.state.data; @@ -190,9 +190,9 @@ export const AnimateUnitsExplode = PluginStateAnimation.create({ if (!changed) return; - return plugin.updateDataState(update, { doNotUpdateCurrent: true }); + return update.commit({ doNotUpdateCurrent: true }); }, - async teardown(_, plugin) { + teardown(_, plugin) { const state = plugin.state.data; const reprs = state.select(StateSelection.Generators.ofType(PluginStateObject.Molecule.Structure.Representation3DState) .withTag('animate-units-explode')); @@ -200,7 +200,7 @@ export const AnimateUnitsExplode = PluginStateAnimation.create({ const update = state.build(); for (const r of reprs) update.delete(r.transform.ref); - return plugin.updateDataState(update); + return update.commit(); }, async apply(animState, t, ctx) { const state = ctx.plugin.state.data; diff --git a/src/mol-plugin-state/builder/data.ts b/src/mol-plugin-state/builder/data.ts index 51f22723db043596283e0f628e2efdd225d3642c..e628bf7aa9be06d73c001a60a36d4b4aead3349a 100644 --- a/src/mol-plugin-state/builder/data.ts +++ b/src/mol-plugin-state/builder/data.ts @@ -14,29 +14,25 @@ export class DataBuilder { return this.plugin.state.data; } - async rawData(params: StateTransformer.Params<RawData>, options?: Partial<StateTransform.Options>) { + rawData(params: StateTransformer.Params<RawData>, options?: Partial<StateTransform.Options>) { const data = this.dataState.build().toRoot().apply(RawData, params, options); - await this.plugin.updateDataState(data, { revertOnError: true }); - return data.selector; + return data.commit({ revertOnError: true }); } - async download(params: StateTransformer.Params<Download>, options?: Partial<StateTransform.Options>) { + download(params: StateTransformer.Params<Download>, options?: Partial<StateTransform.Options>) { const data = this.dataState.build().toRoot().apply(Download, params, options); - await this.plugin.updateDataState(data, { revertOnError: true }); - return data.selector; + return data.commit({ revertOnError: true }); } - async downloadBlob(params: StateTransformer.Params<DownloadBlob>, options?: Partial<StateTransform.Options>) { + downloadBlob(params: StateTransformer.Params<DownloadBlob>, options?: Partial<StateTransform.Options>) { const data = this.dataState.build().toRoot().apply(DownloadBlob, params, options); - await this.plugin.updateDataState(data, { revertOnError: true }); - return data.selector; + return data.commit({ revertOnError: true }); } async readFile(params: StateTransformer.Params<ReadFile>, options?: Partial<StateTransform.Options>) { - const data = this.dataState.build().toRoot().apply(ReadFile, params, options); + const data = await this.dataState.build().toRoot().apply(ReadFile, params, options).commit({ revertOnError: true }); const fileInfo = getFileInfo(params.file || ''); - await this.plugin.updateDataState(data, { revertOnError: true }); - return { data: data.selector, fileInfo }; + return { data: data, fileInfo }; } constructor(public plugin: PluginContext) { diff --git a/src/mol-plugin-state/builder/structure.ts b/src/mol-plugin-state/builder/structure.ts index 30c08c283926041a203ce93fb719cc24c2834ac0..001312e7aafc6de9dd299605d8be2fd0eb769467 100644 --- a/src/mol-plugin-state/builder/structure.ts +++ b/src/mol-plugin-state/builder/structure.ts @@ -32,21 +32,20 @@ export class StructureBuilder { return trajectory; } - private async parseTrajectoryBlob(data: StateObjectRef<SO.Data.Blob>, params: StateTransformer.Params<StateTransforms['Data']['ParseBlob']>) { + private parseTrajectoryBlob(data: StateObjectRef<SO.Data.Blob>, params: StateTransformer.Params<StateTransforms['Data']['ParseBlob']>) { const state = this.dataState; const trajectory = state.build().to(data) .apply(StateTransforms.Data.ParseBlob, params, { state: { isGhost: true } }) .apply(StateTransforms.Model.TrajectoryFromBlob, void 0); - await this.plugin.updateDataState(trajectory, { revertOnError: true }); - return trajectory.selector; + return trajectory.commit({ revertOnError: true }); } readonly hierarchy = new TrajectoryHierarchyBuilder(this.plugin); readonly representation = new StructureRepresentationBuilder(this.plugin); - async parseTrajectory(data: StateObjectRef<SO.Data.Binary | SO.Data.String>, format: BuiltInTrajectoryFormat | TrajectoryFormatProvider): Promise<StateObjectSelector<SO.Molecule.Trajectory>> - async parseTrajectory(blob: StateObjectRef<SO.Data.Blob>, params: StateTransformer.Params<StateTransforms['Data']['ParseBlob']>): Promise<StateObjectSelector<SO.Molecule.Trajectory>> - async parseTrajectory(data: StateObjectRef, params: any) { + parseTrajectory(data: StateObjectRef<SO.Data.Binary | SO.Data.String>, format: BuiltInTrajectoryFormat | TrajectoryFormatProvider): Promise<StateObjectSelector<SO.Molecule.Trajectory>> + parseTrajectory(blob: StateObjectRef<SO.Data.Blob>, params: StateTransformer.Params<StateTransforms['Data']['ParseBlob']>): Promise<StateObjectSelector<SO.Molecule.Trajectory>> + parseTrajectory(data: StateObjectRef, params: any) { const cell = StateObjectRef.resolveAndCheck(this.dataState, data as StateObjectRef); if (!cell) throw new Error('Invalid data cell.'); @@ -57,24 +56,22 @@ export class StructureBuilder { } } - async createModel(trajectory: StateObjectRef<SO.Molecule.Trajectory>, params?: StateTransformer.Params<StateTransforms['Model']['ModelFromTrajectory']>, initialState?: Partial<StateTransform.State>) { + createModel(trajectory: StateObjectRef<SO.Molecule.Trajectory>, params?: StateTransformer.Params<StateTransforms['Model']['ModelFromTrajectory']>, initialState?: Partial<StateTransform.State>) { const state = this.dataState; const model = state.build().to(trajectory) .apply(StateTransforms.Model.ModelFromTrajectory, params || { modelIndex: 0 }, { state: initialState }); - await this.plugin.updateDataState(model, { revertOnError: true }); - return model.selector; + return model.commit({ revertOnError: true }); } - async insertModelProperties(model: StateObjectRef<SO.Molecule.Model>, params?: StateTransformer.Params<StateTransforms['Model']['CustomModelProperties']>, initialState?: Partial<StateTransform.State>) { + insertModelProperties(model: StateObjectRef<SO.Molecule.Model>, params?: StateTransformer.Params<StateTransforms['Model']['CustomModelProperties']>, initialState?: Partial<StateTransform.State>) { const state = this.dataState; const props = state.build().to(model) .apply(StateTransforms.Model.CustomModelProperties, params, { state: initialState }); - await this.plugin.updateDataState(props, { revertOnError: true }); - return props.selector; + return props.commit({ revertOnError: true }); } - async tryCreateUnitcell(model: StateObjectRef<SO.Molecule.Model>, params?: StateTransformer.Params<StateTransforms['Representation']['ModelUnitcell3D']>, initialState?: Partial<StateTransform.State>) { + tryCreateUnitcell(model: StateObjectRef<SO.Molecule.Model>, params?: StateTransformer.Params<StateTransforms['Representation']['ModelUnitcell3D']>, initialState?: Partial<StateTransform.State>) { const state = this.dataState; const m = StateObjectRef.resolveAndCheck(state, model)?.obj?.data; if (!m) return; @@ -83,11 +80,10 @@ export class StructureBuilder { const unitcell = state.build().to(model) .apply(StateTransforms.Representation.ModelUnitcell3D, params, { state: initialState }); - await this.plugin.updateDataState(unitcell, { revertOnError: true }); - return unitcell.selector; + return unitcell.commit({ revertOnError: true }); } - async createStructure(modelRef: StateObjectRef<SO.Molecule.Model>, params?: RootStructureDefinition.Params, initialState?: Partial<StateTransform.State>) { + createStructure(modelRef: StateObjectRef<SO.Molecule.Model>, params?: RootStructureDefinition.Params, initialState?: Partial<StateTransform.State>) { const state = this.dataState; if (!params) { @@ -101,16 +97,14 @@ export class StructureBuilder { const structure = state.build().to(modelRef) .apply(StateTransforms.Model.StructureFromModel, { type: params || { name: 'assembly', params: { } } }, { state: initialState }); - await this.plugin.updateDataState(structure, { revertOnError: true }); - return structure.selector; + return structure.commit({ revertOnError: true }); } - async insertStructureProperties(structure: StateObjectRef<SO.Molecule.Structure>, params?: StateTransformer.Params<StateTransforms['Model']['CustomStructureProperties']>) { + insertStructureProperties(structure: StateObjectRef<SO.Molecule.Structure>, params?: StateTransformer.Params<StateTransforms['Model']['CustomStructureProperties']>) { const state = this.dataState; const props = state.build().to(structure) .apply(StateTransforms.Model.CustomStructureProperties, params); - await this.plugin.updateDataState(props, { revertOnError: true }); - return props.selector; + return props.commit({ revertOnError: true }); } isComponentTransform(cell: StateObjectCell) { @@ -128,13 +122,12 @@ export class StructureBuilder { tags: tags ? [...tags, keyTag] : [keyTag] }); - await this.plugin.updateDataState(component); + await component.commit(); const selector = component.selector; if (!selector.isOk || selector.cell?.obj?.data.elementCount === 0) { - const del = state.build().delete(selector.ref); - await this.plugin.updateDataState(del); + await state.build().delete(selector.ref).commit(); return; } diff --git a/src/mol-plugin-state/builder/structure/representation-preset.ts b/src/mol-plugin-state/builder/structure/representation-preset.ts index 4c9535d53e4b7bc5f73bc16dcbec3f0f5d1f6eb0..2def1be284f8fc8a97c5051888fe6dc1fd972428 100644 --- a/src/mol-plugin-state/builder/structure/representation-preset.ts +++ b/src/mol-plugin-state/builder/structure/representation-preset.ts @@ -149,7 +149,7 @@ const proteinAndNucleic = StructureRepresentationPresetProvider({ nucleic: builder.buildRepresentation(update, components.nucleic, { type: 'gaussian-surface', typeParams, color }, { tag: 'nucleic' }) }; - await plugin.updateDataState(update, { revertOnError: true }); + await update.commit({ revertOnError: true }); return { components, representations }; } }); @@ -190,7 +190,7 @@ const coarseSurface = StructureRepresentationPresetProvider({ polymer: builder.buildRepresentation(update, components.polymer, { type: 'gaussian-surface', typeParams: { ...typeParams, ...gaussianProps }, color }, { tag: 'polymer' }) }; - await plugin.updateDataState(update, { revertOnError: true }); + await update.commit({ revertOnError: true }); return { components, representations }; } }); @@ -215,7 +215,7 @@ const polymerCartoon = StructureRepresentationPresetProvider({ polymer: builder.buildRepresentation(update, components.polymer, { type: 'cartoon', typeParams, color }, { tag: 'polymer' }) }; - await plugin.updateDataState(update, { revertOnError: true }); + await update.commit({ revertOnError: true }); return { components, representations }; } }); @@ -240,7 +240,7 @@ const atomicDetail = StructureRepresentationPresetProvider({ all: builder.buildRepresentation(update, components.all, { type: 'ball-and-stick', typeParams, color }, { tag: 'all' }) }; - await plugin.updateDataState(update, { revertOnError: true }); + await update.commit({ revertOnError: true }); return { components, representations }; } }); diff --git a/src/mol-plugin-state/builder/structure/representation.ts b/src/mol-plugin-state/builder/structure/representation.ts index 7bde496a8f0d5c61a776c63ef2904313185a3782..ef15aaa5b492920f6fb77501c398f5b5b0c9e2d4 100644 --- a/src/mol-plugin-state/builder/structure/representation.ts +++ b/src/mol-plugin-state/builder/structure/representation.ts @@ -117,7 +117,7 @@ export class StructureRepresentationBuilder { const selector = this.buildRepresentation(repr, structure, props, options); if (!selector) return; - await this.plugin.updateDataState(repr); + await repr.commit(); return selector; } diff --git a/src/mol-plugin-state/formats/shape.ts b/src/mol-plugin-state/formats/shape.ts index da3cca1d26fa42530feb7e75db01a4e5a57d87a7..cc02ee10c1a667708a130af62246f3b7174e25fc 100644 --- a/src/mol-plugin-state/formats/shape.ts +++ b/src/mol-plugin-state/formats/shape.ts @@ -22,7 +22,7 @@ export const PlyProvider = DataFormatProvider({ const shape = format.apply(StateTransforms.Model.ShapeFromPly); - await plugin.updateDataState(format); + await format.commit(); return { format: format.selector, shape: shape.selector }; } diff --git a/src/mol-plugin-state/formats/structure.ts b/src/mol-plugin-state/formats/structure.ts index 2456c0d30d48e2c3f1e5da53a0f4c2fa100722f5..f534e20da4c09f68de15c62cc0ad558fd2c7fb8e 100644 --- a/src/mol-plugin-state/formats/structure.ts +++ b/src/mol-plugin-state/formats/structure.ts @@ -21,7 +21,7 @@ export const PsfProvider = DataFormatProvider({ .apply(StateTransforms.Data.ParsePsf, {}, { state: { isGhost: true } }); const topology = format.apply(StateTransforms.Model.TopologyFromPsf); - await plugin.updateDataState(format); + await format.commit(); return { format: format.selector, topology: topology.selector }; } @@ -32,14 +32,12 @@ export const DcdProvider = DataFormatProvider({ description: 'DCD', category: Category, binaryExtensions: ['dcd'], - parse: async (plugin, data) => { + parse: (plugin, data) => { const coordinates = plugin.state.data.build() .to(data) .apply(StateTransforms.Model.CoordinatesFromDcd); - await plugin.updateDataState(coordinates); - - return { coordinates: coordinates.selector }; + return coordinates.commit(); } }); diff --git a/src/mol-plugin-state/formats/trajectory.ts b/src/mol-plugin-state/formats/trajectory.ts index 1fe36df8c05ed24356b5cd40228eb534469a7f6f..c888550f2c1808fefb31880dd10b630bb5d32141 100644 --- a/src/mol-plugin-state/formats/trajectory.ts +++ b/src/mol-plugin-state/formats/trajectory.ts @@ -37,12 +37,15 @@ export const MmcifProvider: TrajectoryFormatProvider = { const state = plugin.state.data; const cif = state.build().to(data) .apply(StateTransforms.Data.ParseCif, void 0, { state: { isGhost: true } }) - const trajectory = cif.apply(StateTransforms.Model.TrajectoryFromMmCif, void 0, { tags: params?.trajectoryTags }) - await plugin.updateDataState(trajectory, { revertOnError: true }); + const trajectory = await cif + .apply(StateTransforms.Model.TrajectoryFromMmCif, void 0, { tags: params?.trajectoryTags }) + .commit({ revertOnError: true }); + if ((cif.selector.cell?.obj?.data.blocks.length || 0) > 1) { plugin.state.data.updateCellState(cif.ref, { isGhost: false }); } - return { trajectory: trajectory.selector }; + + return { trajectory }; }, visuals: defaultVisuals } @@ -60,12 +63,14 @@ export const CifCoreProvider: TrajectoryFormatProvider = { const state = plugin.state.data; const cif = state.build().to(data) .apply(StateTransforms.Data.ParseCif, void 0, { state: { isGhost: true } }) - const trajectory = cif.apply(StateTransforms.Model.TrajectoryFromCifCore, void 0, { tags: params?.trajectoryTags }) - await plugin.updateDataState(trajectory, { revertOnError: true }); + const trajectory = await cif + .apply(StateTransforms.Model.TrajectoryFromCifCore, void 0, { tags: params?.trajectoryTags }) + .commit({ revertOnError: true }); + if ((cif.selector.cell?.obj?.data.blocks.length || 0) > 1) { plugin.state.data.updateCellState(cif.ref, { isGhost: false }); } - return { trajectory: trajectory.selector }; + return { trajectory }; }, visuals: defaultVisuals } @@ -73,10 +78,10 @@ export const CifCoreProvider: TrajectoryFormatProvider = { function directTrajectory(transformer: StateTransformer<PluginStateObject.Data.String | PluginStateObject.Data.Binary, PluginStateObject.Molecule.Trajectory>): TrajectoryFormatProvider['parse'] { return async (plugin, data, params) => { const state = plugin.state.data; - const trajectory = state.build().to(data) + const trajectory = await state.build().to(data) .apply(transformer, void 0, { tags: params?.trajectoryTags }) - await plugin.updateDataState(trajectory, { revertOnError: true }); - return { trajectory: trajectory.selector }; + .commit({ revertOnError: true }); + return { trajectory }; } } diff --git a/src/mol-plugin-state/formats/volume.ts b/src/mol-plugin-state/formats/volume.ts index 6057ba4d7658a764e0f80b2297d1add90b04decc..a70f3d285264b1dbba6dd5858e6530bda9a0e5f6 100644 --- a/src/mol-plugin-state/formats/volume.ts +++ b/src/mol-plugin-state/formats/volume.ts @@ -18,8 +18,7 @@ const Category = 'Volume'; async function defaultVisuals(plugin: PluginContext, data: { volume: StateObjectSelector<PluginStateObject.Volume.Data> }) { const visual = plugin.build().to(data.volume).apply(StateTransforms.Representation.VolumeRepresentation3D); - await visual.commit(); - return [visual]; + return [await visual.commit()]; } export const Ccp4Provider = DataFormatProvider({ diff --git a/src/mol-plugin-state/helpers/structure-overpaint.ts b/src/mol-plugin-state/helpers/structure-overpaint.ts index cc977e3972750639d86c9099c2cfdeebaaa7e355..2049ee21756b5c77938ec8354bc772e4e4ee637f 100644 --- a/src/mol-plugin-state/helpers/structure-overpaint.ts +++ b/src/mol-plugin-state/helpers/structure-overpaint.ts @@ -55,7 +55,7 @@ export async function clearStructureOverpaint(plugin: PluginContext, components: }); } -async function eachRepr(plugin: PluginContext, components: StructureComponentRef[], callback: OverpaintEachReprCallback) { +function eachRepr(plugin: PluginContext, components: StructureComponentRef[], callback: OverpaintEachReprCallback) { const state = plugin.state.data; const update = state.build(); for (const c of components) { @@ -65,7 +65,7 @@ async function eachRepr(plugin: PluginContext, components: StructureComponentRef } } - await plugin.updateDataState(update, { doNotUpdateCurrent: true }); + return update.commit({ doNotUpdateCurrent: true }); } /** filter overpaint layers for given structure */ diff --git a/src/mol-plugin-state/manager/structure/component.ts b/src/mol-plugin-state/manager/structure/component.ts index db35609f037e472d6d2ae6e2fa18277405c85d72..87868522ada71f7ed7dd75f41dffc5de39e8d00c 100644 --- a/src/mol-plugin-state/manager/structure/component.ts +++ b/src/mol-plugin-state/manager/structure/component.ts @@ -60,7 +60,7 @@ class StructureComponentManager extends StatefulPluginComponent<StructureCompone } return this.plugin.dataTransaction(async () => { - await this.plugin.updateDataState(update); + await update.commit(); if (interactionChanged) await this.updateInterationProps(); }); } @@ -89,11 +89,11 @@ class StructureComponentManager extends StatefulPluginComponent<StructureCompone const oldParams = s.properties.cell.transform.params?.properties[InteractionsProvider.descriptor.name]; if (PD.areEqual(interactionParams, oldParams, this.state.options.interactions)) continue; - const b = this.dataState.build(); - b.to(s.properties.cell).update(old => { - old.properties[InteractionsProvider.descriptor.name] = this.state.options.interactions; - }); - await this.plugin.updateDataState(b); + await this.dataState.build().to(s.properties.cell) + .update(old => { + old.properties[InteractionsProvider.descriptor.name] = this.state.options.interactions; + }) + .commit(); } else { const pd = this.plugin.customStructureProperties.getParams(s.cell.obj?.data); const params = PD.getDefaultValues(pd); @@ -113,7 +113,7 @@ class StructureComponentManager extends StatefulPluginComponent<StructureCompone }, { canUndo: 'Preset' }); } - private async syncPreset(root: StructureRef, preset?: StructureRepresentationPresetProvider.Result) { + private syncPreset(root: StructureRef, preset?: StructureRepresentationPresetProvider.Result) { if (!preset || !preset.components) return this.clearComponents([root]); const keptRefs = new Set<string>(); @@ -153,7 +153,7 @@ class StructureComponentManager extends StatefulPluginComponent<StructureCompone } } - if (changed) return this.plugin.updateDataState(update); + if (changed) return update.commit(); } clear(structures: ReadonlyArray<StructureRef>) { @@ -247,7 +247,7 @@ class StructureComponentManager extends StatefulPluginComponent<StructureCompone update.to(repr.cell).update(params); } - return this.plugin.updateDataState(update, { canUndo: 'Update Representation' }); + return update.commit({ canUndo: 'Update Representation' }); } /** @@ -288,7 +288,7 @@ class StructureComponentManager extends StatefulPluginComponent<StructureCompone } } - return this.plugin.updateDataState(update, { canUndo: 'Update Theme' }); + return update.commit({ canUndo: 'Update Theme' }); } addRepresentation(components: ReadonlyArray<StructureComponentRef>, type: string) { @@ -384,7 +384,7 @@ class StructureComponentManager extends StatefulPluginComponent<StructureCompone deletes.delete(c.cell.transform.ref); } } - return this.plugin.updateDataState(deletes, { canUndo: 'Clear Selections' }); + return deletes.commit({ canUndo: 'Clear Selections' }); } constructor(public plugin: PluginContext) { diff --git a/src/mol-plugin-state/manager/structure/hierarchy.ts b/src/mol-plugin-state/manager/structure/hierarchy.ts index 4eef242c5336979492db34327c679b2f57fff19f..51d78520263f4bf60ed01dc8f027313d380a4c82 100644 --- a/src/mol-plugin-state/manager/structure/hierarchy.ts +++ b/src/mol-plugin-state/manager/structure/hierarchy.ts @@ -155,7 +155,7 @@ export class StructureHierarchyManager extends PluginComponent { if (refs.length === 0) return; const deletes = this.plugin.state.data.build(); for (const r of refs) deletes.delete(typeof r === 'string' ? r : r.cell.transform.ref); - return this.plugin.updateDataState(deletes, { canUndo: canUndo ? 'Remove' : false }); + return deletes.commit({ canUndo: canUndo ? 'Remove' : false }); } toggleVisibility(refs: ReadonlyArray<HierarchyRef>, action?: 'show' | 'hide') { @@ -196,7 +196,7 @@ export class StructureHierarchyManager extends PluginComponent { for (const m of trajectory.models) { builder.delete(m.cell); } - return this.plugin.updateDataState(builder); + return builder.commit(); } constructor(private plugin: PluginContext) { diff --git a/src/mol-plugin/behavior/dynamic/custom-props/rcsb/assembly-symmetry.ts b/src/mol-plugin/behavior/dynamic/custom-props/rcsb/assembly-symmetry.ts index 3d2cad2628ee2dce12dc17ea9a840b6c5efb7c3b..34aafbe151d4c7a34d7883f4faf11226a3a787dd 100644 --- a/src/mol-plugin/behavior/dynamic/custom-props/rcsb/assembly-symmetry.ts +++ b/src/mol-plugin/behavior/dynamic/custom-props/rcsb/assembly-symmetry.ts @@ -188,10 +188,9 @@ export const AssemblySymmetryPreset = StructureRepresentationPresetProvider({ } }); -export async function tryCreateAssemblySymmetry(plugin: PluginContext, structure: StateObjectRef<PluginStateObject.Molecule.Structure>, params?: StateTransformer.Params<AssemblySymmetry3D>, initialState?: Partial<StateTransform.State>) { +export function tryCreateAssemblySymmetry(plugin: PluginContext, structure: StateObjectRef<PluginStateObject.Molecule.Structure>, params?: StateTransformer.Params<AssemblySymmetry3D>, initialState?: Partial<StateTransform.State>) { const state = plugin.state.data; const assemblySymmetry = state.build().to(structure) .applyOrUpdateTagged(AssemblySymmetry.Tag.Representation, AssemblySymmetry3D, params, { state: initialState }); - await plugin.updateDataState(assemblySymmetry, { revertOnError: true }); - return assemblySymmetry.selector + return assemblySymmetry.commit({ revertOnError: true }); } \ No newline at end of file diff --git a/src/mol-plugin/behavior/dynamic/custom-props/rcsb/ui/assembly-symmetry.tsx b/src/mol-plugin/behavior/dynamic/custom-props/rcsb/ui/assembly-symmetry.tsx index df69ba8f7e6fe0d301267ae809cc644716a92775..8931de1f6c53b9bc7a4d652d1eda63779d32689d 100644 --- a/src/mol-plugin/behavior/dynamic/custom-props/rcsb/ui/assembly-symmetry.tsx +++ b/src/mol-plugin/behavior/dynamic/custom-props/rcsb/ui/assembly-symmetry.tsx @@ -96,7 +96,7 @@ export class AssemblySymmetryControls extends CollapsableControls<{}, AssemblySy b.to(s.properties.cell).update(old => { old.properties[AssemblySymmetryProvider.descriptor.name] = values; }); - await this.plugin.updateDataState(b); + await b.commit(); } else { const pd = this.plugin.customStructureProperties.getParams(s.cell.obj?.data); const params = PD.getDefaultValues(pd); diff --git a/src/mol-plugin/behavior/dynamic/custom-props/rcsb/validation-report.ts b/src/mol-plugin/behavior/dynamic/custom-props/rcsb/validation-report.ts index f5d23feae4bb21ab7aa3fbc43a0d6f4162fc352f..da8ff9dfb3c4f73134fe62bded4ba98fb2f03f81 100644 --- a/src/mol-plugin/behavior/dynamic/custom-props/rcsb/validation-report.ts +++ b/src/mol-plugin/behavior/dynamic/custom-props/rcsb/validation-report.ts @@ -329,7 +329,7 @@ export const ValidationReportGeometryQualityPreset = StructureRepresentationPres clashesSnfg3d = builder.buildRepresentation<any>(update, clashes, { type: ClashesRepresentationProvider.name, typeParams, color }, { tag: 'clashes-snfg-3d' }); } - await plugin.updateDataState(update, { revertOnError: false }); + await update.commit({ revertOnError: true }); return { components: { ...components, clashes }, representations: { ...representations, clashesBallAndStick, clashesSnfg3d } }; } }); diff --git a/src/mol-plugin/behavior/dynamic/volume-streaming/transformers.ts b/src/mol-plugin/behavior/dynamic/volume-streaming/transformers.ts index 9b9bd36e33be45b4256b415f0d68d8b10a83e137..c4a44118c52c170a42ccfb5e7f4b7b2fa9c6bc2c 100644 --- a/src/mol-plugin/behavior/dynamic/volume-streaming/transformers.ts +++ b/src/mol-plugin/behavior/dynamic/volume-streaming/transformers.ts @@ -99,7 +99,7 @@ export const InitVolumeStreaming = StateAction.build({ entries }); - await plugin.updateDataState(infoTree); + await infoTree.commit(); const info = infoTree.selector; if (!info.isOk) return; diff --git a/src/mol-plugin/context.ts b/src/mol-plugin/context.ts index 2a1fcf9c7650b5c6a1683b9dfcf5a674b0315fc7..0009f66874e40495ae93ab646f07c7b593c8fe6b 100644 --- a/src/mol-plugin/context.ts +++ b/src/mol-plugin/context.ts @@ -13,6 +13,7 @@ import { CustomProperty } from '../mol-model-props/common/custom-property'; import { Model, Structure } from '../mol-model/structure'; import { DataBuilder } from '../mol-plugin-state/builder/data'; import { StructureBuilder } from '../mol-plugin-state/builder/structure'; +import { DataFormatRegistry } from '../mol-plugin-state/formats/registry'; import { StructureSelectionQueryRegistry } from '../mol-plugin-state/helpers/structure-selection-query'; import { CameraManager } from '../mol-plugin-state/manager/camera'; import { InteractivityManager } from '../mol-plugin-state/manager/interactivity'; @@ -28,7 +29,7 @@ import { StateTransformParameters } from '../mol-plugin-ui/state/common'; import { Representation } from '../mol-repr/representation'; import { StructureRepresentationRegistry } from '../mol-repr/structure/registry'; import { VolumeRepresentationRegistry } from '../mol-repr/volume/registry'; -import { State, StateBuilder, StateTree, StateTransform } from '../mol-state'; +import { StateTransform } from '../mol-state'; import { Progress, Task } from '../mol-task'; import { ColorTheme } from '../mol-theme/color'; import { SizeTheme } from '../mol-theme/size'; @@ -43,7 +44,7 @@ import { BuiltInPluginBehaviors } from './behavior'; import { PluginBehavior } from './behavior/behavior'; import { PluginCommandManager } from './command'; import { PluginCommands } from './commands'; -import { PluginConfigManager, PluginConfig } from './config'; +import { PluginConfig, PluginConfigManager } from './config'; import { LeftPanelTabName, PluginLayout } from './layout'; import { PluginSpec } from './spec'; import { PluginState } from './state'; @@ -52,7 +53,6 @@ import { TaskManager } from './util/task-manager'; import { PluginToastManager } from './util/toast'; import { ViewportScreenshotHelper } from './util/viewport-screenshot'; import { PLUGIN_VERSION, PLUGIN_VERSION_DATE } from './version'; -import { DataFormatRegistry } from '../mol-plugin-state/formats/registry'; export class PluginContext { runTask = <T>(task: Task<T>) => this.tasks.run(task); @@ -223,10 +223,6 @@ export class PluginContext { return this.runTask(this.state.data.transaction(f, options)); } - updateDataState(tree: StateTree | StateBuilder, options?: Partial<State.UpdateOptions>) { - return this.runTask(this.state.data.updateTree(tree, options)); - } - requestTaskAbort(progress: Progress, reason?: string) { this.tasks.requestAbort(progress, reason); } diff --git a/src/mol-state/state.ts b/src/mol-state/state.ts index 5d128b842e21a5bf1abb1b311eb6ea1455e83a22..a6cd627ccddf7fb361c180bc55ed05ec2b1c591a 100644 --- a/src/mol-state/state.ts +++ b/src/mol-state/state.ts @@ -4,7 +4,7 @@ * @author David Sehnal <david.sehnal@gmail.com> */ -import { StateObject, StateObjectCell } from './object'; +import { StateObject, StateObjectCell, StateObjectSelector } from './object'; import { StateTree } from './tree'; import { StateTransform } from './transform'; import { StateTransformer } from './transformer'; @@ -234,7 +234,7 @@ class State { * @param tree Tree instance or a tree builder instance * @param doNotReportTiming Indicates whether to log timing of the individual transforms */ - updateTree<T extends StateObject>(tree: StateBuilder.To<T, any>, options?: Partial<State.UpdateOptions>): Task<StateObjectCell<T>> + updateTree<T extends StateObject>(tree: StateBuilder.To<T, any>, options?: Partial<State.UpdateOptions>): Task<StateObjectSelector<T>> updateTree(tree: StateTree | StateBuilder, options?: Partial<State.UpdateOptions>): Task<void> updateTree(tree: StateTree | StateBuilder, options?: Partial<State.UpdateOptions>): Task<any> { const params: UpdateParams = { tree, options }; @@ -257,7 +257,9 @@ class State { if (ret.ctx.hadError) this.inTransactionError = true; - return ret.cell; + if (!ret.cell) return; + + return new StateObjectSelector(ret.cell.transform.ref, this); } finally { this._inUpdate = false; this.updateQueue.handled(params); diff --git a/src/mol-state/state/builder.ts b/src/mol-state/state/builder.ts index f0a0449ca5a5162c343c9ba7fd6ca9efbade502b..c1fd8cbaf38c55168ace43485b634ef2002cb7b2 100644 --- a/src/mol-state/state/builder.ts +++ b/src/mol-state/state/builder.ts @@ -258,7 +258,8 @@ namespace StateBuilder { getTree(): StateTree { return buildTree(this.state); } - commit(options?: Partial<State.UpdateOptions>): Promise<StateObjectCell<A>> { + /** Returns selector to this node. */ + commit(options?: Partial<State.UpdateOptions>): Promise<StateObjectSelector<A>> { if (!this.state.state) throw new Error('Cannot commit template tree'); return this.state.state.runTask(this.state.state.updateTree(this, options)); }