|
|
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 {
|
|
|
_controller: IActivationController;
|
|
|
|
|
|
_active: boolean;
|
|
|
|
|
|
isActive() {
|
|
|
return this._active;
|
|
|
}
|
|
|
|
|
|
getActivationController() {
|
|
|
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;
|