Browse Source

custom property reference counting

David Sehnal 5 years ago
parent
commit
4bbe078230

+ 3 - 2
src/mol-model-props/computed/representations/interactions.ts

@@ -46,7 +46,8 @@ export const InteractionsRepresentationProvider: StructureRepresentationProvider
     defaultColorTheme: { name: 'interaction-type' },
     defaultSizeTheme: { name: 'uniform' },
     isApplicable: (structure: Structure) => structure.elementCount > 0,
-    ensureCustomProperties: (ctx: CustomProperty.Context, structure: Structure) => {
-        return InteractionsProvider.attach(ctx, structure)
+    ensureCustomProperties: {
+        attach: (ctx: CustomProperty.Context, structure: Structure) => InteractionsProvider.attach(ctx, structure, void 0, true),
+        detach: (_, data) => InteractionsProvider.ref(data, false)
     }
 }

+ 3 - 2
src/mol-model-props/integrative/cross-link-restraint/representation.ts

@@ -143,7 +143,8 @@ export const CrossLinkRestraintRepresentationProvider: StructureRepresentationPr
     defaultColorTheme: { name: CrossLinkRestraint.Tag.CrossLinkRestraint },
     defaultSizeTheme: { name: 'uniform' },
     isApplicable: (structure: Structure) => CrossLinkRestraint.isApplicable(structure),
-    ensureCustomProperties: (ctx: CustomProperty.Context, structure: Structure) => {
-        return CrossLinkRestraintProvider.attach(ctx, structure)
+    ensureCustomProperties: {
+        attach: (ctx: CustomProperty.Context, structure: Structure) => CrossLinkRestraintProvider.attach(ctx, structure, void 0, true),
+        detach: (_, data) => CrossLinkRestraintProvider.ref(data, false)
     }
 }

+ 3 - 2
src/mol-model-props/rcsb/representations/validation-report-clashes.ts

@@ -287,7 +287,8 @@ export const ClashesRepresentationProvider: StructureRepresentationProvider<Clas
     defaultColorTheme: { name: 'uniform', props: { value: Color(0xFA28FF) } },
     defaultSizeTheme: { name: 'physical' },
     isApplicable: (structure: Structure) => structure.elementCount > 0,
-    ensureCustomProperties: (ctx: CustomProperty.Context, structure: Structure) => {
-        return ClashesProvider.attach(ctx, structure)
+    ensureCustomProperties: {
+        attach: (ctx: CustomProperty.Context, structure: Structure) => ClashesProvider.attach(ctx, structure, void 0, true),
+        detach: (_, data) => ClashesProvider.ref(data, false)
     }
 }

+ 16 - 6
src/mol-plugin-state/transforms/representation.ts

@@ -210,7 +210,7 @@ const StructureRepresentation3D = PluginStateTransform.BuiltIn({
         return Task.create('Structure Representation', async ctx => {
             const propertyCtx = { runtime: ctx, fetch: plugin.fetch }
             const provider = plugin.structureRepresentation.registry.get(params.type.name)
-            if (provider.ensureCustomProperties) await provider.ensureCustomProperties(propertyCtx, a.data)
+            if (provider.ensureCustomProperties) await provider.ensureCustomProperties.attach(propertyCtx, a.data)
             const props = params.type.params || {}
             const repr = provider.factory({ webgl: plugin.canvas3d?.webgl, ...plugin.structureRepresentation.themeCtx }, provider.getParams)
             await Theme.ensureDependencies(propertyCtx, plugin.structureRepresentation.themeCtx, { structure: a.data }, params)
@@ -222,12 +222,15 @@ const StructureRepresentation3D = PluginStateTransform.BuiltIn({
     },
     update({ a, b, oldParams, newParams }, plugin: PluginContext) {
         return Task.create('Structure Representation', async ctx => {
-            if (newParams.type.name !== oldParams.type.name) return StateTransformer.UpdateResult.Recreate;
+            const oldProvider = plugin.structureRepresentation.registry.get(oldParams.type.name);
             const propertyCtx = { runtime: ctx, fetch: plugin.fetch }
+            if (oldProvider.ensureCustomProperties) oldProvider.ensureCustomProperties.detach(propertyCtx, a.data);
+            Theme.releaseDependencies(propertyCtx, plugin.structureRepresentation.themeCtx, { structure: a.data }, oldParams);
+
+            if (newParams.type.name !== oldParams.type.name) return StateTransformer.UpdateResult.Recreate;
             const provider = plugin.structureRepresentation.registry.get(newParams.type.name)
-            if (provider.ensureCustomProperties) await provider.ensureCustomProperties(propertyCtx, a.data)
+            if (provider.ensureCustomProperties) await provider.ensureCustomProperties.attach(propertyCtx, a.data)
             const props = { ...b.data.repr.props, ...newParams.type.params }
-            await Theme.releaseDependencies(propertyCtx, plugin.structureRepresentation.themeCtx, { structure: a.data }, oldParams)
             await Theme.ensureDependencies(propertyCtx, plugin.structureRepresentation.themeCtx, { structure: a.data }, newParams)
             b.data.repr.setTheme(Theme.create(plugin.structureRepresentation.themeCtx, { structure: a.data }, newParams));
             await b.data.repr.createOrUpdate(props, a.data).runInContext(ctx);
@@ -587,7 +590,7 @@ const VolumeRepresentation3D = PluginStateTransform.BuiltIn({
         return Task.create('Volume Representation', async ctx => {
             const propertyCtx = { runtime: ctx, fetch: plugin.fetch }
             const provider = plugin.volumeRepresentation.registry.get(params.type.name)
-            if (provider.ensureCustomProperties) await provider.ensureCustomProperties(propertyCtx, a.data)
+            if (provider.ensureCustomProperties) await provider.ensureCustomProperties.attach(propertyCtx, a.data)
             const props = params.type.params || {}
             const repr = provider.factory({ webgl: plugin.canvas3d?.webgl, ...plugin.volumeRepresentation.themeCtx }, provider.getParams)
             repr.setTheme(Theme.create(plugin.volumeRepresentation.themeCtx, { volume: a.data }, params))
@@ -598,7 +601,14 @@ const VolumeRepresentation3D = PluginStateTransform.BuiltIn({
     },
     update({ a, b, oldParams, newParams }, plugin: PluginContext) {
         return Task.create('Volume Representation', async ctx => {
-            if (newParams.type.name !== oldParams.type.name) return StateTransformer.UpdateResult.Recreate;
+            if (newParams.type.name !== oldParams.type.name) {
+                const oldProvider = plugin.volumeRepresentation.registry.get(oldParams.type.name);
+                if (oldProvider.ensureCustomProperties) {
+                    const propertyCtx = { runtime: ctx, fetch: plugin.fetch }
+                    oldProvider.ensureCustomProperties.detach(propertyCtx, a.data)
+                }
+                return StateTransformer.UpdateResult.Recreate;
+            }
             const props = { ...b.data.repr.props, ...newParams.type.params }
             b.data.repr.setTheme(Theme.create(plugin.volumeRepresentation.themeCtx, { volume: a.data }, newParams))
             await b.data.repr.createOrUpdate(props, a.data).runInContext(ctx);

+ 4 - 1
src/mol-repr/representation.ts

@@ -48,7 +48,10 @@ export interface RepresentationProvider<D, P extends PD.Params, S extends Repres
     readonly defaultColorTheme: { name: string, props?: {} }
     readonly defaultSizeTheme: { name: string, props?: {} }
     readonly isApplicable: (data: D) => boolean
-    readonly ensureCustomProperties?: (ctx: CustomProperty.Context, data: D) => Promise<void>
+    readonly ensureCustomProperties?: {
+        attach: (ctx: CustomProperty.Context, data: D) => Promise<void>,
+        detach: (ctx: CustomProperty.Context, data: D) => void
+    }
 }
 
 export namespace RepresentationProvider {

+ 3 - 2
src/mol-repr/structure/representation/cartoon.ts

@@ -64,7 +64,8 @@ export const CartoonRepresentationProvider: StructureRepresentationProvider<Cart
     defaultColorTheme: { name: 'polymer-id' },
     defaultSizeTheme: { name: 'uniform' },
     isApplicable: (structure: Structure) => structure.polymerResidueCount > 0,
-    ensureCustomProperties: (ctx: CustomProperty.Context, structure: Structure) => {
-        return SecondaryStructureProvider.attach(ctx, structure)
+    ensureCustomProperties: {
+        attach: (ctx: CustomProperty.Context, structure: Structure) => SecondaryStructureProvider.attach(ctx, structure, void 0, true),
+        detach: (_, data) => SecondaryStructureProvider.ref(data, false)
     }
 }

+ 3 - 3
src/mol-theme/theme.ts

@@ -56,9 +56,9 @@ namespace Theme {
         await theme.sizeThemeRegistry.get(props.sizeTheme.name).ensureCustomProperties?.attach(ctx, data)
     }
 
-    export async function releaseDependencies(ctx: CustomProperty.Context, theme: ThemeRegistryContext, data: ThemeDataContext, props: Props) {
-        await theme.colorThemeRegistry.get(props.colorTheme.name).ensureCustomProperties?.detach(ctx, data)
-        await theme.sizeThemeRegistry.get(props.sizeTheme.name).ensureCustomProperties?.detach(ctx, data)
+    export function releaseDependencies(ctx: CustomProperty.Context, theme: ThemeRegistryContext, data: ThemeDataContext, props: Props) {
+        theme.colorThemeRegistry.get(props.colorTheme.name).ensureCustomProperties?.detach(ctx, data)
+        theme.sizeThemeRegistry.get(props.sizeTheme.name).ensureCustomProperties?.detach(ctx, data)
     }
 }