瀏覽代碼

Clean up disposal behavior of contexts

Steven Silvester 8 年之前
父節點
當前提交
fcf3a2fd24
共有 4 個文件被更改,包括 29 次插入18 次删除
  1. 21 12
      src/docmanager/context.ts
  2. 1 5
      src/docmanager/savehandler.ts
  3. 2 1
      src/docmanager/widgetmanager.ts
  4. 5 0
      src/docregistry/interfaces.ts

+ 21 - 12
src/docmanager/context.ts

@@ -10,7 +10,7 @@ import {
 } from 'phosphor/lib/core/disposable';
 
 import {
-  defineSignal, ISignal
+  clearSignalData, defineSignal, ISignal
 } from 'phosphor/lib/core/signaling';
 
 import {
@@ -62,6 +62,11 @@ class Context implements IDocumentContext<IDocumentModel> {
    */
   populated: ISignal<IDocumentContext<IDocumentModel>, void>;
 
+  /**
+   * A signal emitted when the context is disposed.
+   */
+  disposed: ISignal<IDocumentContext<IDocumentModel>, void>;
+
   /**
    * The unique id of the context.
    *
@@ -147,8 +152,10 @@ class Context implements IDocumentContext<IDocumentModel> {
     if (this.isDisposed) {
       return;
     }
+    this.disposed.emit(void 0);
+    clearSignalData(this);
+    this._manager.removeContext(this.id);
     this._manager = null;
-    this._id = '';
   }
 
   /**
@@ -246,6 +253,7 @@ defineSignal(Context.prototype, 'kernelChanged');
 defineSignal(Context.prototype, 'pathChanged');
 defineSignal(Context.prototype, 'contentsModelChanged');
 defineSignal(Context.prototype, 'populated');
+defineSignal(Context.prototype, 'disposed');
 
 
 /**
@@ -277,14 +285,7 @@ class ContextManager implements IDisposable {
     }
     this._manager = null;
     for (let id in this._contexts) {
-      let contextEx = this._contexts[id];
-      contextEx.context.dispose();
-      contextEx.model.dispose();
-      contextEx.saveHandler.dispose();
-      let session = contextEx.session;
-      if (session) {
-        session.dispose();
-      }
+      this._contexts[id].context.dispose();
     }
     this._contexts = null;
     this._opener = null;
@@ -353,12 +354,20 @@ class ContextManager implements IDisposable {
   }
 
   /**
-   * Remove a context.
+   * Remove a context that has been disposed.
+   *
+   * #### Notes
+   * This is called when a context is disposed,
+   * and should not be called by user code.
    */
   removeContext(id: string): void {
     let contextEx = this._contexts[id];
     contextEx.model.dispose();
-    contextEx.context.dispose();
+    contextEx.saveHandler.dispose();
+    let session = contextEx.session;
+    if (session) {
+      session.dispose();
+    }
     delete this._contexts[id];
   }
 

+ 1 - 5
src/docmanager/savehandler.ts

@@ -100,11 +100,6 @@ class SaveHandler implements IDisposable {
   private _save(): void {
     let context = this._context;
 
-    // Bail if the context is disposed.
-    if (context.isDisposed) {
-      return;
-    }
-
     // Trigger the next update.
     this._setTimer();
 
@@ -169,6 +164,7 @@ class SaveHandler implements IDisposable {
   private _context: IDocumentContext<IDocumentModel> = null;
   private _services: IServiceManager = null;
   private _stopped = false;
+  private _path = '';
 }
 
 

+ 2 - 1
src/docmanager/widgetmanager.ts

@@ -133,7 +133,8 @@ class DocumentWidgetManager implements IDisposable {
       this._widgets[id].splice(index, 1);
       // Dispose of the context if this is the last widget using it.
       if (!this._widgets[id].length) {
-        this._contextManager.removeContext(id);
+        let context = this._contextManager.getContext(id);
+        context.dispose();
       }
     });
     Private.idProperty.set(widget, id);

+ 5 - 0
src/docregistry/interfaces.ts

@@ -120,6 +120,11 @@ interface IDocumentContext<T extends IDocumentModel> extends IDisposable {
    */
   populated: ISignal<IDocumentContext<T>, void>;
 
+  /**
+   * A signal emitted when the context is disposed.
+   */
+  disposed: ISignal<IDocumentContext<T>, void>;
+
   /**
    * The unique id of the context.
    *