class Listenable {
	/**
	 * Adds a callback for a specific event type.
	 * You may set requestInitialCalls to true to ask the listenable instance to fire the callback with pre-existing values.
	 */
	addEventListener(eventType, callback, requestInitialCalls = false) {
		if (!this.eventListeners) {
			this.eventListeners = { };
		}
		if (!(eventType in this.eventListeners)) {
			this.eventListeners[eventType] = [ ];
		}
		this.eventListeners[eventType].push(callback);

		if (requestInitialCalls) {
			this.performInitialCalls(eventType, callback);
		}
	}

	removeEventListener(eventType, callback) {
		if (this.eventListeners && (eventType in this.eventListeners)) {
			var index = this.eventListeners[eventType].indexOf(callback);
			this.eventListeners[eventType].splice(index, 1);
		}
	}

	dispatchEvent(event) {
		if (this.eventListeners && (event.type in this.eventListeners)) {
			var callbacks = this.eventListeners[event.type];
			for (var i = 0; i < callbacks.length; i++) {
				callbacks[i](event);
			}
		}
	}

	/**
	 * Override this if you want to use the requestInitialCalls flag in the addEventListener() function.
	 * Call callback with pre-existing values in this function.
	 */
	performInitialCalls(eventType, callback) {
		console.error("You must override performInitialCalls() to be able to use the requestInitialCalls flag.");
	}
}