delphirtl
Version:
RTL functions from Delphi
234 lines • 15.1 kB
JavaScript
;
/*
* A simple messaging system by Chee Wee Chua, Jul 2022
* See examples in ./examples
*
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.SFunction = exports.SMethodNotImplemented = exports.TMessageManager = exports.TMessage = void 0;
const SMethodNotImplemented = "Method not implemented.";
exports.SMethodNotImplemented = SMethodNotImplemented;
const SFunction = 'function';
exports.SFunction = SFunction;
/**
* Base class from which other classes derive from
*
* @abstract
* @class TMessageBase
* @typedef {TMessageBase}
* @template T
* @implements {IMessage<T>}
* @implements {IMessageName}
* @category Messaging
*/
class TMessageBase {
constructor(aValue) { this.value = aValue; }
getName() {
return typeof this.value;
}
}
/**
* Description placeholder
*
* @class TMessage
* @typedef {TMessage}
* @template T
* @extends {TMessageBase<T>}
* @category Messaging
*/
class TMessage extends TMessageBase {
}
exports.TMessage = TMessage;
/**
* Description placeholder
*
* @class TCallback
* @typedef {TCallback}
* @template T
* @implements {IMessageName}
* @category Messaging
*/
class TCallback {
getName() {
throw new Error(SMethodNotImplemented);
}
constructor(aCallback) {
this.fCallback = aCallback;
}
}
/**
* TMessageManager enables messaging between different code points.
*
* @class TMessageManager
* @typedef {TMessageManager}
* @category Messaging
*/
class TMessageManager {
constructor() {
this.reset();
}
reset() {
// Enums works similarly to number during runtime, so, disable Number as a native type from working
this.fDisabledTypes = [];
this.fDisabledTypes.push(Number.name);
this.fListeners = new Map();
}
disableType(aType) {
const lTypeName = (typeof aType === 'function') ? (aType.name) : aType;
this.fDisabledTypes.push(lTypeName);
}
enableType(aType) {
let lIndex = -1;
const lTypeName = (typeof aType === 'function') ? (aType.name) : aType;
for (let i = 0; i < this.fDisabledTypes.length; i++) {
if (lTypeName === this.fDisabledTypes[i]) {
lIndex = i;
break;
}
}
if (lIndex != -1) {
this.fDisabledTypes.splice(lIndex, 1);
}
}
ensureTypeEnabled(aSuffix) {
for (const lType of this.fDisabledTypes) {
if (aSuffix === lType) {
throw new Error(`${aSuffix} not enabled`);
}
}
}
typesDisabled() {
return this.fDisabledTypes;
}
static getDefaultManager() {
if (!TMessageManager.fDefaultManager) {
this.fDefaultManager = new TMessageManager();
}
return this.fDefaultManager;
}
/**
* Sends the given message to listeners that subscribes to the given class.
*
* @template {MessageType} T
* @param {SubscriptionIdentifierType} aClass
* @param {T} aMessage
* @category Messaging
*/
sendMessage(aClass, aMessage) {
const lClassName = (typeof aClass === 'function') ? (aClass.name) : aClass;
const lMessageClassName = `${lClassName.toUpperCase()}`;
const lListenerList = this.fListeners.get(lMessageClassName);
if (lListenerList !== undefined) {
for (const lListener of lListenerList) {
try {
lListener(aMessage);
}
catch (e) {
// keep going
}
}
}
}
/**
* Sends a wrapped message to listeners on the given class
*
* @template {MessageType} T
* @param {SubscriptionIdentifierType} aClass
* @param {TMessage<T>} aMessage
*/
sendWrappedMessage(aClass, aMessage) {
const lClassName = (typeof aMessage.value) != "object" ? (typeof aMessage.value).toUpperCase() : aMessage.value.constructor.name.toUpperCase();
const lMessageClassName = `${aMessage.constructor.name}<${lClassName}>`;
const lListenerList = this.fListeners.get(lMessageClassName);
if (lListenerList !== undefined) {
for (const lListener of lListenerList) {
try {
lListener(aMessage);
}
catch (e) {
// keep going
}
}
}
}
/**
* Subscribes to the given class and receives the given message
*
* @template {MessageType} T
* @param {SubscriptionIdentifierType} aClass
* @param {(aMessage: T) => void} aMessageListener
* @returns {SubscriptionIndex}
* @category Messaging
*/
subscribeToMessage(aClass, aMessageListener) {
const lSuffix = (typeof aClass === 'function') ? (aClass.name) : aClass;
this.ensureTypeEnabled(lSuffix);
const lMessageClassName = `${lSuffix.toUpperCase()}`; // TMessage<Number>, TMessage<String>, TMessage<Date>
let lListenerList = this.fListeners.get(lMessageClassName); // name is erased, so aMessageClass is always TMessage
if (!lListenerList) {
lListenerList = new Array();
this.fListeners.set(lMessageClassName, lListenerList);
}
const index = lListenerList.push(aMessageListener) - 1;
return index;
}
/**
* Subscribes to the wrapped message on the given class
*
* @template {MessageType} T
* @param {SubscriptionIdentifierType} aClass
* @param {(aMessage: TMessage<T>) => void} aMessageListener
* @returns {SubscriptionIndex}
*/
subscribeToWrappedMessage(aClass, aMessageListener) {
const lSuffix = (typeof aClass === 'function') ? (aClass.name) : aClass;
this.ensureTypeEnabled(lSuffix);
const lMessageClassName = `${TMessage.name}<${lSuffix.toUpperCase()}>`; // TMessage<NUMBER>, TMessage<STRING>, TMessage<DATE>
let lListenerList = this.fListeners.get(lMessageClassName); // name is erased, so aMessageClass is always TMessage
if (!lListenerList) {
lListenerList = new Array();
this.fListeners.set(lMessageClassName, lListenerList);
}
const index = lListenerList.push(aMessageListener) - 1;
return index;
}
/**
* Unsubscribes from messages on the given class
*
* @public
* @param {SubscriptionIdentifierType} aClass
* @param {SubscriptionIndex} aSubscriptionIndex
* @category Messaging
*/
unsubscribe(aClass, aSubscriptionIndex) {
const lClassName = (typeof aClass === 'function') ? (aClass.name) : aClass;
const lMessageClassName = `${lClassName.toUpperCase()}`;
const lListenerList = this.fListeners.get(lMessageClassName);
if (lListenerList != undefined) {
lListenerList.splice(aSubscriptionIndex, 1);
if (lListenerList.length === 0) {
this.fListeners.delete(lMessageClassName);
}
}
}
/**
* Unsubscribes from the wrapped message on the given class
*
* @param {SubscriptionIdentifierType} aClass
* @param {SubscriptionIndex} aSubscriptionIndex
* @category Messaging
*/
unsubscribeWrappedMessage(aClass, aSubscriptionIndex) {
const lSuffix = (typeof aClass === 'function') ? (aClass.name) : aClass;
const lMessageClassName = `${TMessage.name}<${lSuffix.toUpperCase()}>`; // TMessage<NUMBER>, TMessage<STRING>, TMessage<DATE>
let lListenerList = this.fListeners.get(lMessageClassName);
if (lListenerList !== undefined) {
lListenerList.splice(aSubscriptionIndex, 1);
if (lListenerList.length === 0) {
this.fListeners.delete(lMessageClassName);
}
}
}
}
exports.TMessageManager = TMessageManager;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVzc2FnaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL21lc3NhZ2luZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7RUFJRTs7O0FBRUYsTUFBTSxxQkFBcUIsR0FBRyx5QkFBeUIsQ0FBQztBQTBTcEQsc0RBQXFCO0FBelN6QixNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUM7QUF5U0YsOEJBQVM7QUFuUXBDOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFlLFlBQVk7SUFFdkIsWUFBWSxNQUFTLElBQUksSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUEsQ0FBQyxDQUFDO0lBQzlDLE9BQU87UUFDSCxPQUFPLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUM3QixDQUFDO0NBQ0o7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sUUFBWSxTQUFRLFlBQWU7Q0FDeEM7QUFvT0csNEJBQVE7QUF0Tlo7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFNBQVM7SUFDWCxPQUFPO1FBQ0gsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRCxZQUFZLFNBQXVCO1FBQy9CLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO0lBQy9CLENBQUM7Q0FDSjtBQU1EOzs7Ozs7R0FNRztBQUNILE1BQU0sZUFBZTtJQUtqQjtRQUNJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNqQixDQUFDO0lBRUQsS0FBSztRQUNELG1HQUFtRztRQUNuRyxJQUFJLENBQUMsY0FBYyxHQUFHLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFTSxXQUFXLENBQUMsS0FBaUM7UUFDaEQsTUFBTSxTQUFTLEdBQUcsQ0FBQyxP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