/**
* @class EventHolder
* @description holds events and further sub event holders
* @property {Array<Function>} callbacks - array of callback function to be used
* called when the event is triggered
* @property {Array<Function>} allSubCallbacks - array of all callbacks
* functions in this EventHolder and all subEventHolders
* @property {object} subEvents - gets the subevents
*/
class EventHolder {
_callbacks = [];
_subEvents = {};
constructor() {}
get callbacks() {
return this._callbacks;
}
get subEvents() {
return this._subEvents;
}
get allSubCallbacks() {
return Object.values(this._subEvents).reduce(
(acc, el) => [...acc, ...el.callbacks, ...el.allSubCallbacks],
[]
);
}
/**
* @function getSubEvent
* @description returns the subEvent from the name passed in
* @memberof EventHolder
* @instance
* @param {string} name - the name of the sub event to return
* @returns {EventHolder} - the sub event holder
*/
getSubEvent(name) {
return this._subEvents[name];
}
/**
* @function getCallbacks
* @description gets the callbacks from the path, will call sub event
* holders to get events
* @memberof EventHolder
* @instance
* @param {Array<string>} path - path the the event
* @returns {Array<Function>} - the callbacks
*/
getCallbacks(path) {
if (path.length === 0) {
return this._callbacks;
} else if (path[0] === '**') {
return Object.values(this._subEvents).reduce(
(acc, el) => [...acc, ...el.getCallbacks(path.slice(1))],
[]
);
} else if (path[0] === '***') {
return this.allSubCallbacks;
} else if (typeof this._subEvents[path[0]] !== 'undefined') {
return this._subEvents[path[0]].getCallbacks(path.slice(1));
} else {
return [];
}
}
/**
* @function addCallback
* @description adds a callback to this events callbacks
* @memberof EventHolder
* @instance
* @param {Event} event - the event to add
*/
addCallback(event) {
event.removeCallback = this._removeCallback;
this._callbacks.push(event);
}
/**
* @function addSubEvent
* @description adds a sub EventHolder
* @memberof EventHolder
* @instance
* @param {string} name - the name of the subevent to add
*/
addSubEvent(name) {
if (typeof this._subEvents[name] === 'undefined') {
this._subEvents[name] = new EventHolder();
}
}
/**
* @function add
* @description adds an event to this event holder of a sub event holder
* @memberof EventHolder
* @instance
* @param {Array<string>} path - the path to the event
* @param {Event} event - the event to add
*/
add(path, event) {
if (path.length > 0) {
this.addSubEvent(path[0]);
this._subEvents[path[0]].add(path.slice(1), event);
} else {
this.addCallback(event);
}
}
/**
* @function remove
* @description removes a event from the event holder
* @memberof EventHolder
* @instance
* @param {Array<string>} path - path to event
* @param {Event} event - the event to remove
*/
remove(path, event) {
if (path.length > 0) {
if (typeof this._subEvents[path[0]] !== 'undefined') {
this._subEvents[path[0]].remove(path.slice(1), event);
}
} else {
this._removeCallback(event);
}
}
/**
* @function _removeCallback
* @description removes a callback from the callbacks
* @memberof EventHolder
* @instance
* @private
* @param {Event} event - the event to remove
*/
_removeCallback(event) {
this._callbacks = this._callbacks.filter((el) => el.id !== event.id);
}
}
module.exports = EventHolder;