API Docs for: 0.1.1
Show:

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

(function () {
  /*---------------------
  ------- IMPORT --------
  ----------------------*/
  const { EventEmitter } = window.flatworld_libraries;

  /*---------------------
  --------- API ---------
  ----------------------*/
  window.flatworld.mapEvents = setupMapEvents();

  /*---------------------
  -------- PUBLIC -------
  ----------------------*/
  /**
   * This module handles map events. Like informing map movement, object selection and other
   * changes. Not that ALL the eventlisteners and their callbacks will throw one event!
   * But that event will have no extra parameters, so when you do special things, like selecting
   * objects on the map, you should throw another event when that happens and you can pass on
   * the objects that were selected from the map.
   * This uses https://github.com/primus/eventemitter3 and follows the nodeJS event
   * conventions: https://nodejs.org/api/events.html
   * Events atm:
   * - mapdrag
   * - mapzoomed
   * - objectsSelected (in hexagon extension units.js)
   * - mapMoved
   * - mapResize
   * @namespace flatworld
   * @class mapEvents
   * @return {Object}     subsribe and publish
   * @todo add mapfullscreen, mapfullSize and check if something is missing from the list
   */
  function setupMapEvents() {
    const TIMER_FOR_SAME_TYPE = 50;
    let lastTimePublished = {};
    const EE = new EventEmitter();

    /*---------------------
    --------- API ---------
    ----------------------*/
    return {
      subscribe,
      publish,
      debounce,
      removeAllListeners: EE.removeAllListeners.bind(EE)
    };

    /*---------------------
    -------- PUBLIC -------
    ----------------------*/
    function subscribe(type, cb) {
      EE.on(type, cb);
      lastTimePublished[type] = 0;
    }
    /**
     * publish
     * @param  {String}    type   Type can be string or an object with:
     * { name: String (required), cooldown: Int, debounce: Int }.
     * @param  {...[]} data       Can hold any data with rest of the parameters
     */
    function publish(type = '', datas) {
      const timestamp = new Date().getTime();
      const realType = type.name || type;

      if ((lastTimePublished[realType] + (type.cooldown || TIMER_FOR_SAME_TYPE) < timestamp)) {
        lastTimePublished[realType] = timestamp;
        EE.emit(realType, datas);
      }
    }

    // Function from underscore.js
    // Returns a function, that, as long as it continues to be invoked, will not
    // be triggered. The function will be called after it stops being called for
    // N milliseconds. If `immediate` is passed, trigger the function on the
    // leading edge, instead of the trailing.
    function debounce(func, wait, immediate) {
      let timeout;

      return function() {
        const context = this, args = arguments;
        const later = function() {
          timeout = null;
          if (!immediate) func.apply(context, args);
        };
        const callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
      }
    }
  }
})();