Scope.ts
        
        
            
                    54 lines
            
             | 1.4 KiB
            
                | video/mp2t
            
             |
                TypeScriptLexer
            
          
        |  | r94 | import { IDestroyable, IRemovable } from "@implab/core-amd/interfaces"; | |
| import { isDestroyable, isRemovable } from "@implab/core-amd/safe"; | |||
|  | r118 | import { isUnsubscribable, Unsubscribable } from "../observable"; | |
|  | r94 | ||
| export interface IScope { | |||
|  | r102 | own(target: (() => void) | IDestroyable | IRemovable | Unsubscribable): void; | |
|  | r94 | } | |
|  | r131 | const guard = (cb: () => void) => { | |
| try { | |||
| cb(); | |||
| } catch { | |||
| // guard | |||
| } | |||
| }; | |||
|  | r94 | export class Scope implements IDestroyable, IScope { | |
|  | r131 | private readonly _pending: (() => void)[] = []; | |
| private _disposed = false; | |||
|  | r94 | ||
| static readonly dummy: IScope = { own() { } }; | |||
|  | r102 | own(target: (() => void) | IDestroyable | IRemovable | Unsubscribable) { | |
|  | r94 | if (target instanceof Function) { | |
|  | r131 | this._own(target); | |
|  | r94 | } else if (isDestroyable(target)) { | |
|  | r131 | this._own(() => target.destroy()); | |
|  | r94 | } else if (isRemovable(target)) { | |
|  | r131 | this._own(() => target.remove()); | |
|  | r118 | } else if (isUnsubscribable(target)) { | |
|  | r131 | this._own(() => target.unsubscribe()); | |
|  | r94 | } | |
| } | |||
|  | r131 | private _own(target: () => void) { | |
| if (this._disposed) | |||
| guard(target); | |||
| else | |||
| this._pending.push(target); | |||
| } | |||
|  | r94 | clean() { | |
|  | r131 | this._pending.forEach(guard); | |
| this._pending.length = 0; | |||
|  | r94 | } | |
| destroy() { | |||
|  | r131 | if (!this._disposed) { | |
| this._disposed = true; | |||
| this.clean(); | |||
| } | |||
|  | r94 | } | |
| } | 
