nope/lib/communication/bridge.ts
2020-12-04 19:10:33 +01:00

134 lines
3.4 KiB
TypeScript

/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-11-06 08:52:36
* @modify date 2020-12-04 17:44:34
* @desc [description]
*/
import { ILogger } from "js-logger";
import { ICommunicationInterface } from "../types/nope/nopeCommunication.interface";
import { INopeObservable } from "../types/nope/nopeObservable.interface";
const METHODS: Array<keyof ICommunicationInterface> = [
"emitAurevoir",
"emitBonjour",
"emitEvent",
"emitNewInstanceGeneratorsAvailable",
"emitNewInstancesAvailable",
"emitNewObersvablesAvailable",
"emitNewServicesAvailable",
"emitRpcRequest",
"emitRpcResult",
"emitTaskCancelation",
"offEvent",
"offRpcRequest",
"offRpcResponse",
"onAurevoir",
"onBonjour",
"onEvent",
"onNewInstanceGeneratorsAvailable",
"onNewInstancesAvailable",
"onNewObservablesAvailable",
"onNewServicesAvailable",
"onRpcRequest",
"onRpcResult",
"onTaskCancelation"
];
const STORING = ["offEvent", "offRpcRequest", "offRpcResponse"];
const REMOVING = [
"onAurevoir",
"onBonjour",
"onEvent",
"onNewInstanceGeneratorsAvailable",
"onNewInstancesAvailable",
"onNewObservablesAvailable",
"onNewServicesAvailable",
"onRpcRequest",
"onRpcResult",
"onTaskCancelation"
];
/**
* A Communication Layer for the Dispatchers.
* Here, only a Events are used.
*
* @export
* @class EventLayer
* @implements {ICommunicationInterface}
*/
//@ts-ignore Ignore the Interface. Its implemented manually
export class Bridge implements ICommunicationInterface {
connected: INopeObservable<boolean>;
protected _layers: Set<ICommunicationInterface>;
public addLayer(layer: ICommunicationInterface) {
if (!this._layers.has(layer)) {
this._layers.add(layer);
if (this._enableDynamicAdding) {
// Play the history:
for (const method of STORING) {
for (const args of this[`_map_${method}`]) {
layer[method as any](...args);
}
}
for (const method of REMOVING) {
for (const args of this[`_map_${method}`]) {
layer[method as any](...args);
}
}
}
}
}
public removeLayer(layer: ICommunicationInterface) {
if (this._layers.has(layer)) {
this._layers.delete(layer);
}
}
constructor(
public readonly subscriptionMode: "individual" | "generic" = "individual",
public readonly resultSharing: "individual" | "generic" = "individual",
protected _enableDynamicAdding = false,
protected _logger?: ILogger
) {
this._layers = new Set<ICommunicationInterface>();
const _this = this;
for (const method of METHODS) {
if (
_enableDynamicAdding &&
(STORING.includes(method) || REMOVING.includes(method))
) {
this[`_map_${method}`] = new Array<any[]>();
// Define a Function which stores the Actions:
this[method as any] = async (...args) => {
// Store the Call
_this[`_map_${method}`].push(...args);
for (const _layer of _this._layers) {
_layer[method as any](...args);
}
};
} else {
// Define a Function which stores the Actions:
this[method as any] = async (...args) => {
if (_this._logger) {
_this._logger.debug(method, ...args);
}
for (const _layer of _this._layers) {
_layer[method as any](...args);
}
};
}
}
}
}