Skip to content
Snippets Groups Projects
Commit 70de73a9 authored by David Sehnal's avatar David Sehnal
Browse files

mol-state: call StateTransformer.dispose when recreating object

parent af263b8c
No related branches found
No related tags found
No related merge requests found
...@@ -141,12 +141,13 @@ const StructureRepresentation3D = PluginStateTransform.BuiltIn({ ...@@ -141,12 +141,13 @@ const StructureRepresentation3D = PluginStateTransform.BuiltIn({
}, },
update({ a, b, oldParams, newParams, cache }, plugin: PluginContext) { update({ a, b, oldParams, newParams, cache }, plugin: PluginContext) {
return Task.create('Structure Representation', async ctx => { return Task.create('Structure Representation', async ctx => {
if (newParams.type.name !== oldParams.type.name) return StateTransformer.UpdateResult.Recreate;
// dispose isn't called on update so we need to handle it manually
const oldProvider = plugin.representation.structure.registry.get(oldParams.type.name); const oldProvider = plugin.representation.structure.registry.get(oldParams.type.name);
if (oldProvider.ensureCustomProperties) oldProvider.ensureCustomProperties.detach(a.data); if (oldProvider.ensureCustomProperties) oldProvider.ensureCustomProperties.detach(a.data);
Theme.releaseDependencies(plugin.representation.structure.themes, { structure: a.data }, oldParams); Theme.releaseDependencies(plugin.representation.structure.themes, { structure: a.data }, oldParams);
if (newParams.type.name !== oldParams.type.name) return StateTransformer.UpdateResult.Recreate;
const provider = plugin.representation.structure.registry.get(newParams.type.name); const provider = plugin.representation.structure.registry.get(newParams.type.name);
const propertyCtx = { runtime: ctx, fetch: plugin.fetch }; const propertyCtx = { runtime: ctx, fetch: plugin.fetch };
if (provider.ensureCustomProperties) await provider.ensureCustomProperties.attach(propertyCtx, a.data); if (provider.ensureCustomProperties) await provider.ensureCustomProperties.attach(propertyCtx, a.data);
......
...@@ -477,7 +477,9 @@ async function update(ctx: UpdateContext) { ...@@ -477,7 +477,9 @@ async function update(ctx: UpdateContext) {
for (let i = deletes.length - 1; i >= 0; i--) { for (let i = deletes.length - 1; i >= 0; i--) {
const cell = ctx.cells.get(deletes[i]); const cell = ctx.cells.get(deletes[i]);
cell?.transform.transformer.definition.dispose?.({ b: cell.obj, params: cell.transform.params, cache: cell.cache }, ctx.parent.globalContext); if (cell) {
dispose(cell.transform, cell.obj, cell?.transform.params, cell.cache, ctx.parent.globalContext);
}
} }
for (const d of deletes) { for (const d of deletes) {
...@@ -866,9 +868,11 @@ async function updateNode(ctx: UpdateContext, currentRef: Ref): Promise<UpdateNo ...@@ -866,9 +868,11 @@ async function updateNode(ctx: UpdateContext, currentRef: Ref): Promise<UpdateNo
return { ref: currentRef, action: 'created', obj }; return { ref: currentRef, action: 'created', obj };
} else { } else {
const oldParams = current.params.values; const oldParams = current.params.values;
const oldCache = current.cache;
const newParams = params.values; const newParams = params.values;
current.params = params; current.params = params;
const updateKind = !!current.obj && current.obj !== StateObject.Null const updateKind = !!current.obj && current.obj !== StateObject.Null
? await updateObject(ctx, current, transform.transformer, parent, current.obj!, oldParams, newParams) ? await updateObject(ctx, current, transform.transformer, parent, current.obj!, oldParams, newParams)
: StateTransformer.UpdateResult.Recreate; : StateTransformer.UpdateResult.Recreate;
...@@ -876,7 +880,10 @@ async function updateNode(ctx: UpdateContext, currentRef: Ref): Promise<UpdateNo ...@@ -876,7 +880,10 @@ async function updateNode(ctx: UpdateContext, currentRef: Ref): Promise<UpdateNo
switch (updateKind) { switch (updateKind) {
case StateTransformer.UpdateResult.Recreate: { case StateTransformer.UpdateResult.Recreate: {
const oldObj = current.obj; const oldObj = current.obj;
dispose(transform, oldObj, oldParams, oldCache, ctx.parent.globalContext);
const newObj = await createObject(ctx, current, transform.transformer, parent, newParams); const newObj = await createObject(ctx, current, transform.transformer, parent, newParams);
updateTag(newObj, transform); updateTag(newObj, transform);
current.obj = newObj; current.obj = newObj;
return { ref: currentRef, action: 'replaced', oldObj, obj: newObj }; return { ref: currentRef, action: 'replaced', oldObj, obj: newObj };
...@@ -885,6 +892,8 @@ async function updateNode(ctx: UpdateContext, currentRef: Ref): Promise<UpdateNo ...@@ -885,6 +892,8 @@ async function updateNode(ctx: UpdateContext, currentRef: Ref): Promise<UpdateNo
updateTag(current.obj, transform); updateTag(current.obj, transform);
return { ref: currentRef, action: 'updated', obj: current.obj! }; return { ref: currentRef, action: 'updated', obj: current.obj! };
case StateTransformer.UpdateResult.Null: { case StateTransformer.UpdateResult.Null: {
dispose(transform, current.obj, oldParams, oldCache, ctx.parent.globalContext);
current.obj = StateObject.Null; current.obj = StateObject.Null;
return { ref: currentRef, action: 'updated', obj: current.obj! }; return { ref: currentRef, action: 'updated', obj: current.obj! };
} }
...@@ -894,6 +903,14 @@ async function updateNode(ctx: UpdateContext, currentRef: Ref): Promise<UpdateNo ...@@ -894,6 +903,14 @@ async function updateNode(ctx: UpdateContext, currentRef: Ref): Promise<UpdateNo
} }
} }
function dispose(transform: StateTransform, b: StateObject | undefined, params: any, cache: any, globalContext: any) {
transform.transformer.definition.dispose?.({
b: b !== StateObject.Null ? b : void 0,
params,
cache
}, globalContext);
}
function updateTag(obj: StateObject | undefined, transform: StateTransform) { function updateTag(obj: StateObject | undefined, transform: StateTransform) {
if (!obj || obj === StateObject.Null) return; if (!obj || obj === StateObject.Null) return;
(obj.tags as string[] | undefined) = transform.tags; (obj.tags as string[] | undefined) = transform.tags;
......
...@@ -103,7 +103,16 @@ namespace Transformer { ...@@ -103,7 +103,16 @@ namespace Transformer {
/** Parameter interpolation */ /** Parameter interpolation */
interpolate?(src: P, target: P, t: number, globalCtx: unknown): P interpolate?(src: P, target: P, t: number, globalCtx: unknown): P
/** Cleanup resources */ /**
* Cleanup resources
*
* Automatically called on deleting an object and on recreating it
* (i.e. when update returns UpdateResult.Recreate or UpdateResult.Null)
*
* Not called on UpdateResult.Updated because the resources might not
* have been invalidated. In this case, the possible cleanup has to be handled
* manually.
*/
dispose?(params: DisposeParams<B, P>, globalCtx: unknown): void dispose?(params: DisposeParams<B, P>, globalCtx: unknown): void
/** Custom conversion to and from JSON */ /** Custom conversion to and from JSON */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment