ActivatableMixin.ts
89 lines
| 2.7 KiB
| video/mp2t
|
TypeScriptLexer
|
|
r49 | import { IActivationController, IActivatable, ICancellation } from "../interfaces"; | ||
| import { AsyncComponent } from "./AsyncComponent"; | ||||
| import { Cancellation } from "../Cancellation"; | ||||
| import { TraceSource } from "../log/TraceSource"; | ||||
| type Constructor<T = {}> = new (...args: any[]) => T; | ||||
| const log = TraceSource.get("@implab/core/components/ActivatableMixin"); | ||||
| export function ActivatableMixin<TBase extends Constructor<AsyncComponent>>(Base: TBase) { | ||||
| return class extends Base implements IActivatable { | ||||
|
|
r115 | _controller: IActivationController | undefined; | ||
|
|
r49 | |||
|
|
r115 | _active = false; | ||
|
|
r49 | |||
| isActive() { | ||||
| return this._active; | ||||
| } | ||||
|
|
r115 | hasActivationController() { | ||
| return !!this._controller; | ||||
| } | ||||
|
|
r49 | getActivationController() { | ||
|
|
r115 | if (!this._controller) | ||
| throw Error("Activation controller isn't set"); | ||||
|
|
r49 | return this._controller; | ||
| } | ||||
| setActivationController(controller: IActivationController) { | ||||
| this._controller = controller; | ||||
| } | ||||
| async onActivating(ct: ICancellation) { | ||||
| if (this._controller) | ||||
| await this._controller.activating(this, ct); | ||||
| } | ||||
| async onActivated(ct: ICancellation) { | ||||
| if (this._controller) | ||||
| await this._controller.activated(this, ct); | ||||
| } | ||||
| activate(ct: ICancellation = Cancellation.none) { | ||||
| return this.runOperation(this._activateAsync.bind(this), ct); | ||||
| } | ||||
| async _activateAsync(ct: ICancellation) { | ||||
| if (this.isActive()) | ||||
| return; | ||||
| await this.onActivating(ct); | ||||
| this._active = true; | ||||
| try { | ||||
| await this.onActivated(ct); | ||||
| } catch (e) { | ||||
| log.error("Suppressed onActivated error: {0}", e); | ||||
| } | ||||
| } | ||||
| async onDeactivating(ct: ICancellation) { | ||||
| if (this._controller) | ||||
| await this._controller.deactivating(this, ct); | ||||
| } | ||||
| async onDeactivated(ct: ICancellation) { | ||||
| if (this._controller) | ||||
| await this._controller.deactivated(this, ct); | ||||
| } | ||||
| deactivate(ct: ICancellation = Cancellation.none) { | ||||
| return this.runOperation(this._deactivateAsync.bind(this), ct); | ||||
| } | ||||
| async _deactivateAsync(ct: ICancellation) { | ||||
| if (!this.isActive()) | ||||
| return; | ||||
| await this.onDeactivating(ct); | ||||
| this._active = false; | ||||
| try { | ||||
| await this.onDeactivated(ct); | ||||
| } catch (e) { | ||||
| log.error("Suppressed onDeactivated error: {0}", e); | ||||
| } | ||||
| } | ||||
| }; | ||||
| } | ||||
| export const traceSource = log; | ||||
