import { isFunction } from '../utils/utils.js';
/**
* A prototyp of a basic event interface. Classes might inherit
* from this class or provide the same shape by convention.
*
* The field-map "events" defines possible *event names* pointing to an
* array of *listeners* for a special class. For example:
*
* events = {
* 'changed': []
* }
*
* Listeners a functions which are called with an optional payload
* object.
*
* @author rkoppe <roland.koppe@awi.de>
*/
export class EventObject {
/**
* {@code events} are optional and can also be defined later.
*
* @param {Object} events (optional)
*/
constructor(events) {
this.events = events || {};
}
/**
* Registers the given listener function for the event name.
*
* @param {string} name
* @param {function} listener
*/
on(name, listener) {
if (!(name in this.events)) throw new Error('Event ' + name + ' is not supported.');
if (!isFunction(listener)) throw new Error('Listener must be a function.');
if (!listener || (Object.prototype.toString.call(listener) !== '[object Function]')) throw new Error('Listener must be a function.');
this.events[name].push(listener);
}
/**
* Unregisters all listeners from an event
*
* @param {string} name
*/
off(name) {
if (name in this.events) {
this.events[name] = [];
} else {
throw new Error('Event ' + name + ' is not supported.');
}
}
/**
* Fires an event with given name and payload.
*
* @param {string} name
* @param {object} payload
*/
fire(name, payload) {
if (!(name in this.events)) throw new Error('Event ' + name + ' is not supported.');
for (let i = 0; i < this.events[name].length; i++) {
this.events[name][i].call(this, payload);
}
}
}