Source: ReactiveSystem.js

goog.provide('entitas.ReactiveSystem');
goog.require('entitas.GroupObserver');


/**
 * @constructor
 *
 * @param pool
 * @param subSystem
 */
entitas.ReactiveSystem = function(pool, subSystem) {
  var triggers = 'triggers' in subSystem ? subSystem['triggers'] : [subSystem['trigger']];
  this._subsystem = subSystem;
  var ensureComponents = as(subSystem, 'ensureComponents');
  if (ensureComponents != null) {
    this._ensureComponents = ensureComponents.ensureComponents;
  }
  var excludeComponents = as(subSystem, 'excludeComponents');
  if (excludeComponents != null) {
    this._excludeComponents = excludeComponents.excludeComponents;
  }
  this._clearAfterExecute = as(subSystem, 'clearAfterExecute') != null;
  var triggersLength = triggers.length;
  var groups = new Array(triggersLength);
  var eventTypes = new Array(triggersLength);
  for (var i = 0; i < triggersLength; i++) {
    var trigger = triggers[i];
    groups[i] = pool.getGroup(trigger.trigger);
    eventTypes[i] = trigger.eventType;
  }
  this._observer = new entitas.GroupObserver(groups, eventTypes);
  this._buffer = [];
}
Object.defineProperty(entitas.ReactiveSystem.prototype, "subsystem", {
  /**
   * Get subsystems
   * @type {entitas.IReactiveExecuteSystem}
   * @name entitas.Pool#subsystem */
  get: function () { return this._subsystem; },
  enumerable: true,
  configurable: true
});
entitas.ReactiveSystem.prototype.activate = function () {
  this._observer.activate();
};
entitas.ReactiveSystem.prototype.deactivate = function () {
  this._observer.deactivate();
};
entitas.ReactiveSystem.prototype.clear = function () {
  this._observer.clearCollectedEntities();
};
/**
 * execute
 */
entitas.ReactiveSystem.prototype.execute = function () {
  var collectedEntities = this._observer.collectedEntities;
  var ensureComponents = this._ensureComponents;
  var excludeComponents = this._excludeComponents;
  var buffer = this._buffer;
  var j = buffer.length;
  if (Object.keys(collectedEntities).length != 0) {
    if (ensureComponents) {
      if (excludeComponents) {
        for (var k in collectedEntities) {
          var e = collectedEntities[k];
          if (ensureComponents.matches(e) && !excludeComponents.matches(e)) {
            buffer[j++] = e.addRef();
          }
        }
      }
      else {
        for (var k in collectedEntities) {
          var e = collectedEntities[k];
          if (ensureComponents.matches(e)) {
            buffer[j++] = e.addRef();
          }
        }
      }
    }
    else if (excludeComponents) {
      for (var k in collectedEntities) {
        var e = collectedEntities[k];
        if (!excludeComponents.matches(e)) {
          buffer[j++] = e.addRef();
        }
      }
    }
    else {
      for (var k in collectedEntities) {
        var e = collectedEntities[k];
        buffer[j++] = e.addRef();
      }
    }
    this._observer.clearCollectedEntities();
    if (buffer.length != 0) {
      this._subsystem.execute(buffer);
      for (var i = 0, bufferCount = buffer.length; i < bufferCount; i++) {
        buffer[i].release();
      }
      buffer.length = 0;
      if (this._clearAfterExecute) {
        this._observer.clearCollectedEntities();
      }
    }
  }
};