API Docs for: 0.1.1
Show:

File: src/components/map/core/eventlisteners.js

(function () {
  /*-----------------------
  ------- VARIABLES -------
  -----------------------*/
  var stateOfEvents = {};
  var activeEventListeners = {};
  var detectors = {};

  /*-----------------------
  --------- IMPORT --------
  -----------------------*/
  var mapEvents = window.flatworld.mapEvents;

  /*-----------------------
  ---------- API ----------
  -----------------------*/
  window.flatworld.eventListeners = eventListenersModule();

  /*-----------------------
  -------- PUBLIC ---------
  -----------------------*/
  /**
   * This keeps all the event listeners and detectors in one class. You add detectors / event listener types with addDetector and you add
   * event listeners with on.
   *
   * @namespace flatworld
   * @class eventListeners
   */
  function eventListenersModule() {
    /*---------------------------
    ------------ API ------------
    ---------------------------*/
    return {
      on,
      off,
      isOn,
      setActivityState,
      getActivityState,
      setDetector,
      clearDetector,
    };

    /*---------------------------
    ----------- PUBLIC ----------
    ---------------------------*/
    /**
     * Activates the eventListener.
     *
     * @method on
     * @throws {Error}          General error, if detector for this event type has not been set.
     * @param  {String}  type   REQUIRED. The type of event. This type has been created with setDetector.
     * @param  {Boolean} cb     REQUIRED. Callback to do it's eventlistener magic.
     */
    function on(type = '', cb = false) {
      if (!detectors[type] && !detectors[type].size) {
        throw new Error('eventlisteners.on needs to have detector set with this event type!');
      }

      detectors[type].on(_createEventListenerWrapper('Map' + type, cb));
      activeEventListeners[type] = activeEventListeners[type] || new Set();
      activeEventListeners[type].add(cb);
    }
    /**
     * Deactivates the eventListener. Callback is optional. If is not provided will remove all this types eventListeners
     *
     * @method off
     * @param  {String}  type   REQUIRED. The type of event. This type has been created with setDetector.
     * @param  {Boolean} cb     Callback to do it's eventlistener magic.
     */
    function off(type = '', cb = false) {
      detectors[type].off(cb);
      cb ? activeEventListeners[type].delete(cb) : delete activeEventListeners[type];
    }
    /**
     * Activates the eventListener. Callback is optional. If is not provided will check if the eventlistener type has any listeners active.
     *
     * @method isOn
     * @param  {String}  type   REQUIRED. The type of event. This type has been created with setDetector.
     * @param  {Boolean} cb     Callback to do it's eventlistener magic.
     */
    function isOn(type = '', cb = false) {
      var answer;

      answer = cb ? activeEventListeners[type].has(cb) : !!activeEventListeners[type].size;

      return answer;
    }
    /**
     * Sets the state of the event. State is very important e.g. for fluent dragging and selecting. When we start to drag, we avoid
     * selecting units and vice versa, when we keep an event state tracking through this.
     *
     * @method setActivityState
     * @param {String} type        EventType
     * @param {Boolean} newState   The new state value
     */
    function setActivityState(type, newState) {
      stateOfEvents[type] = newState;
    }
    /**
     * get activity state of the event
     *
     * @method getActivityState
     * @param  {String} type   EventType
     * @return {Boolean}
     */
    function getActivityState(type = '') {
      return stateOfEvents[type];
    }
    /**
     * Set event detector. If there is already detector of this type, we overwrite it.
     *
     * @method setDetector
     * @param {String}   type    Event type
     * @param {Function} cbOn    Callback which sets activates the detector
     * @param {Function} cbOff   Callback which sets deactivates the detector
     */
    function setDetector(type = '', cbOn = () => {}, cbOff = () => {}) {
      detectors[type] = {};
      detectors[type] = {
        on: cbOn,
        off: cbOff,
      };
    }
    /**
     * Clear event detector. We also remove all possible eventlisteners set on this event type.
     *
     * @method clearDetector
     * @param {String}   type  Event type
     */
    function clearDetector(type = '') {
      /* remove all event listeners before we empty the data */
      activeEventListeners[type].forEach(cb => {
        detectors[type].cbOff(cb);
      });

      /* remove all data / references to event listeners and detector */
      delete activeEventListeners[type];
      delete detectors[type];
    }

    /*-----------------------------
    ----------- PRIVATE -----------
    ------------------------------*/
    /**
     * This creates a wrapper for callback. The idea is to send map events from this wrapper for all events.
     *
     * @private
     * @static
     * @method _createEventListenerWrapper
     * @param  {String}   type   Event type
     * @param  {Function} cb     Event callback
     */
    function _createEventListenerWrapper(type, cb) {
      /* NOTE! There can be more than one arguments in an event. E.g. Hamster.js */
      return (...args) => {
        /**
         * @event Event gets fired when the specific eventListener trigger. The name consists of "Map" + the given event type, like such:
         * "MapDrag"
         */
        mapEvents.publish(type);
        cb(...args);
      };
    }
  }
})();