Source: GroupObserver.js

goog.provide('entitas.GroupObserver');
goog.require('entitas.GroupEventType');
goog.require('entitas.exceptions.GroupObserverException');


/**
 * @constructor
 * @param {Array<entitas.Group>} groups
 * @param {number} eventTypes
 */
entitas.GroupObserver = function(groups, eventTypes) {
  var _this = this;
  this._collectedEntities = {};
  this._groups = null;
  this._eventTypes = null;
  this._addEntityCache = null;
  /**
   * Adds an entity to this observer group
   * @param group
   * @param {entitas.Entity}entity
   * @param index
   * @param {entitas.IComponent}component
   */
  this.addEntity = function (group, entity, index, component) {
    if (!(entity.id in _this._collectedEntities)) {
      _this._collectedEntities[entity.id] = entity;
      entity.addRef();
    }
  };
  this._groups = Array.isArray(groups) ? groups : [groups];
  this._eventTypes = Array.isArray(eventTypes) ? eventTypes : [eventTypes];
  if (groups.length !== eventTypes.length) {
    throw new entitas.exceptions.GroupObserverException("Unbalanced count with groups (" + groups.length +
      ") and event types (" + eventTypes.length + ")");
  }
  this._collectedEntities = {};
  this._addEntityCache = this.addEntity;
  this.activate();
}
Object.defineProperty(entitas.GroupObserver.prototype, "collectedEntities", {
  /**
   * Entities being observed
   * @type {Object<string,entitas.Entity>}
   * @name entitas.GroupObserver#collectedEntities */
  get: function () { return this._collectedEntities; },
  enumerable: true,
  configurable: true
});
/**
 * Activate events
 */
entitas.GroupObserver.prototype.activate = function () {
  for (var i = 0, groupsLength = this._groups.length; i < groupsLength; i++) {
    var group = this._groups[i];
    var eventType = this._eventTypes[i];
    if (eventType === GroupEventType.OnEntityAdded) {
      group.onEntityAdded.remove(this._addEntityCache);
      group.onEntityAdded.add(this._addEntityCache);
    }
    else if (eventType === GroupEventType.OnEntityRemoved) {
      group.onEntityRemoved.remove(this._addEntityCache);
      group.onEntityRemoved.add(this._addEntityCache);
    }
    else if (eventType === GroupEventType.OnEntityAddedOrRemoved) {
      group.onEntityAdded.remove(this._addEntityCache);
      group.onEntityAdded.add(this._addEntityCache);
      group.onEntityRemoved.remove(this._addEntityCache);
      group.onEntityRemoved.add(this._addEntityCache);
    }
    else {
      throw "Invalid eventType [" + typeof eventType + ":" + eventType + "] in GroupObserver::activate";
    }
  }
};
/**
 * Deavtivate events
 */
entitas.GroupObserver.prototype.deactivate = function () {
  var e;
  for (var i = 0, groupsLength = this._groups.length; i < groupsLength; i++) {
    var group = this._groups[i];
    group.onEntityAdded.remove(this._addEntityCache);
    group.onEntityRemoved.remove(this._addEntityCache);
    this.clearCollectedEntities();
  }
};
/**
 * Clear the list of entities
 */
entitas.GroupObserver.prototype.clearCollectedEntities = function () {
  for (var e in this._collectedEntities) {
    this._collectedEntities[e].release();
  }
  this._collectedEntities = {};
};