xiamidaxia 7 месяцев назад
Родитель
Сommit
50fa5a8eba

+ 90 - 0
packages/common/utils/src/disposable-collection.ts

@@ -0,0 +1,90 @@
+import { Emitter, Event } from './event';
+import { Disposable } from './disposable';
+
+export class DisposableImpl implements Disposable {
+  readonly toDispose = new DisposableCollection();
+
+  dispose(): void {
+    this.toDispose.dispose();
+  }
+
+  get disposed(): boolean {
+    return this.toDispose.disposed;
+  }
+
+  get onDispose(): Event<void> {
+    return this.toDispose.onDispose;
+  }
+}
+
+export class DisposableCollection implements Disposable {
+  protected readonly disposables: Disposable[] = [];
+
+  protected readonly onDisposeEmitter = new Emitter<void>();
+
+  private _disposed = false;
+
+  constructor(...toDispose: Disposable[]) {
+    toDispose.forEach((d) => this.push(d));
+  }
+
+  get length() {
+    return this.disposables.length;
+  }
+
+  get onDispose(): Event<void> {
+    return this.onDisposeEmitter.event;
+  }
+
+  get disposed(): boolean {
+    return this._disposed;
+  }
+
+  dispose(): void {
+    if (this.disposed) {
+      return;
+    }
+    this._disposed = true;
+    this.disposables
+      .slice()
+      .reverse()
+      .forEach((disposable) => {
+        try {
+          disposable.dispose();
+        } catch (e) {
+          console.error(e);
+        }
+      });
+    this.onDisposeEmitter.fire(undefined);
+    this.onDisposeEmitter.dispose();
+  }
+
+  push(disposable: Disposable): Disposable {
+    if (this.disposed) return Disposable.NULL;
+    if (disposable === Disposable.NULL) {
+      return Disposable.NULL;
+    }
+    const { disposables } = this;
+    if (disposables.find((d) => d === disposable)) {
+      return Disposable.NULL;
+    }
+    const originalDispose = disposable.dispose;
+    const toRemove = Disposable.create(() => {
+      const index = disposables.indexOf(disposable);
+      if (index !== -1) {
+        disposables.splice(index, 1);
+      }
+      disposable.dispose = originalDispose;
+    });
+    disposable.dispose = () => {
+      toRemove.dispose();
+      disposable.dispose();
+    };
+    disposables.push(disposable);
+    return toRemove;
+  }
+
+  pushAll(disposables: Disposable[]): Disposable[] {
+    return disposables.map((disposable) => this.push(disposable));
+  }
+}

+ 2 - 1
packages/common/utils/src/disposable.spec.ts

@@ -1,6 +1,7 @@
 import { describe, test, expect } from 'vitest';
 
-import { Disposable, DisposableCollection, DisposableImpl } from './disposable';
+import { DisposableCollection, DisposableImpl } from './disposable-collection';
+import { Disposable } from './disposable';
 
 describe('disposable', () => {
   test('Disposable', async () => {

+ 0 - 90
packages/common/utils/src/disposable.ts

@@ -1,5 +1,3 @@
-import { Emitter, type Event } from './event';
-
 /**
  * An object that performs a cleanup operation when `.dispose()` is called.
  *
@@ -29,91 +27,3 @@ export namespace Disposable {
 
   export const NULL = Object.freeze(create(() => {}));
 }
-
-export class DisposableImpl implements Disposable {
-  readonly toDispose = new DisposableCollection();
-
-  dispose(): void {
-    this.toDispose.dispose();
-  }
-
-  get disposed(): boolean {
-    return this.toDispose.disposed;
-  }
-
-  get onDispose(): Event<void> {
-    return this.toDispose.onDispose;
-  }
-}
-
-export class DisposableCollection implements Disposable {
-  protected readonly disposables: Disposable[] = [];
-
-  protected readonly onDisposeEmitter = new Emitter<void>();
-
-  private _disposed = false;
-
-  constructor(...toDispose: Disposable[]) {
-    toDispose.forEach((d) => this.push(d));
-  }
-
-  get length() {
-    return this.disposables.length;
-  }
-
-  get onDispose(): Event<void> {
-    return this.onDisposeEmitter.event;
-  }
-
-  get disposed(): boolean {
-    return this._disposed;
-  }
-
-  dispose(): void {
-    if (this.disposed) {
-      return;
-    }
-    this._disposed = true;
-    this.disposables
-      .slice()
-      .reverse()
-      .forEach((disposable) => {
-        try {
-          disposable.dispose();
-        } catch (e) {
-          console.error(e);
-        }
-      });
-    this.onDisposeEmitter.fire(undefined);
-    this.onDisposeEmitter.dispose();
-  }
-
-  push(disposable: Disposable): Disposable {
-    if (this.disposed) return Disposable.NULL;
-    if (disposable === Disposable.NULL) {
-      return Disposable.NULL;
-    }
-    const { disposables } = this;
-    if (disposables.find((d) => d === disposable)) {
-      return Disposable.NULL;
-    }
-    const originalDispose = disposable.dispose;
-    const toRemove = Disposable.create(() => {
-      const index = disposables.indexOf(disposable);
-      if (index !== -1) {
-        disposables.splice(index, 1);
-      }
-      disposable.dispose = originalDispose;
-    });
-    disposable.dispose = () => {
-      toRemove.dispose();
-      disposable.dispose();
-    };
-    disposables.push(disposable);
-    return toRemove;
-  }
-
-  pushAll(disposables: Disposable[]): Disposable[] {
-    return disposables.map((disposable) => this.push(disposable));
-  }
-}

+ 3 - 5
packages/common/utils/src/event.ts

@@ -1,7 +1,5 @@
 import { NOOP } from './objects';
-import { type Disposable } from './disposable';
-
-const DisposableNULL: Disposable = Object.freeze({ dispose: NOOP });
+import { Disposable } from './disposable';
 
 export interface EventListener<T> {
   (args: T): void;
@@ -12,7 +10,7 @@ export interface Event<T> {
 }
 
 export namespace Event {
-  export const None: Event<any> = () => DisposableNULL;
+  export const None: Event<any> = () => Disposable.NULL;
 }
 
 export class Emitter<T = any> {
@@ -28,7 +26,7 @@ export class Emitter<T = any> {
     if (!this._event) {
       this._event = (listener: EventListener<T>, thisArgs?: any) => {
         if (this._disposed) {
-          return DisposableNULL;
+          return Disposable.NULL;
         }
         if (!this._listeners) {
           this._listeners = [];

+ 1 - 0
packages/common/utils/src/index.ts

@@ -3,6 +3,7 @@ export * from './objects';
 export * from './types';
 export * from './event';
 export * from './disposable';
+export * from './disposable-collection';
 export * from './cancellation';
 export * from './promise-util';
 export * from './cache';