ソースを参照

PluginBehavior dispose logic

dsehnal 2 年 前
コミット
339b2e696c

+ 4 - 0
CHANGELOG.md

@@ -6,6 +6,10 @@ Note that since we don't clearly distinguish between a public and private interf
 
 ## [Unreleased]
 
+## [v3.12.1] - 2022-07-20
+
+- Fix plugin behavior dispose logic to correctly unsubscribe observables.
+
 ## [v3.12.0] - 2022-07-17
 
 - Add ``colorMarker`` option to Renderer. This disables the highlight and select marker at a shader level for faster rendering of large scenes in some cases.

+ 5 - 5
src/mol-plugin/behavior/behavior.ts

@@ -17,7 +17,8 @@ export { PluginBehavior };
 
 interface PluginBehavior<P = unknown> {
     register(ref: StateTransform.Ref): void,
-    unregister(): void,
+    unregister?(): void,
+    dispose?(): void,
 
     /** Update params in place. Optionally return a promise if it depends on an async action. */
     update?(params: P): boolean | Promise<boolean>
@@ -102,7 +103,7 @@ namespace PluginBehavior {
             register(): void {
                 this.sub = cmd.subscribe(this.ctx, data => action(data, this.ctx));
             }
-            unregister(): void {
+            dispose(): void {
                 if (this.sub) this.sub.unsubscribe();
                 this.sub = void 0;
             }
@@ -123,7 +124,7 @@ namespace PluginBehavior {
             this.subs.push(sub);
         }
         abstract register(): void;
-        unregister() {
+        dispose(): void {
             for (const s of this.subs) s.unsubscribe();
             this.subs = [];
         }
@@ -146,8 +147,7 @@ namespace PluginBehavior {
         protected subscribeObservable<T>(o: Observable<T>, action: (v: T) => void) {
             this.subs.push(o.subscribe(action));
         }
-
-        unregister() {
+        dispose(): void {
             for (const s of this.subs) s.unsubscribe();
             this.subs = [];
         }

+ 6 - 2
src/mol-plugin/behavior/static/state.ts

@@ -37,12 +37,16 @@ export function SyncBehaviors(ctx: PluginContext) {
 
     ctx.state.events.object.removed.subscribe(o => {
         if (!SO.isBehavior(o.obj)) return;
-        o.obj.data.unregister();
+        o.obj.data.unregister?.();
+        o.obj.data.dispose?.();
     });
 
     ctx.state.events.object.updated.subscribe(o => {
         if (o.action === 'recreate') {
-            if (o.oldObj && SO.isBehavior(o.oldObj)) o.oldObj.data.unregister();
+            if (o.oldObj && SO.isBehavior(o.oldObj)) {
+                o.oldObj.data.unregister?.();
+                o.oldObj.data.dispose?.();
+            }
             if (o.obj && SO.isBehavior(o.obj)) o.obj.data.register(o.ref);
         }
     });

+ 2 - 1
src/mol-plugin/state.ts

@@ -124,7 +124,8 @@ class PluginState extends PluginComponent {
     dispose() {
         this.behaviors.cells.forEach(cell => {
             if (PluginBehavior.Behavior.is(cell.obj)) {
-                cell.obj.data.unregister();
+                cell.obj.data.unregister?.();
+                cell.obj.data.dispose?.();
             }
         });