var EventEmitter = require('./EventEmitter'); var BitSet = require('./BitSet'); /** * Represents the group of components. * Basically it's a criteria for finding Entity. * ComponentGroup has three BitSet which will be used to search Entity: * contain, intersect, exclude. * contain will only match if a Entity has all the Component in BitSet. * intersect will match if a Entity has at least one of the Component in BitSet. * exclude will match if a Entity doesn't have a Component in BitSet. * This class can be generated by a {@link ComponentGroup.createBuilder}. * @constructor * @extends EventEmitter * @see BitSet * @see Entity * @see Component */ function ComponentGroup(contain, intersect, exclude) { EventEmitter.call(this); /** * The ID of this object. * This will be given by Engine, and it shouldn't be edited. * @readonly * @var {Number} */ this.id = null; /** * The Engine associated with this object. * @private * @var {Engine} */ this._engine = null; /** * The 'contain' criteria. * This will only match if a Entity has all the Component in this BitSet. * @var {BitSet} */ this.contain = contain; /** * The 'intersect' criteria. * This will match if a Entity has at least one of the Component in BitSet. * @var {BitSet} */ this.intersect = intersect; /** * The 'exclude' criteria. * This will match if a Entity doesn't have a Component in this BitSet. * @var {BitSet} */ this.exclude = exclude; } ComponentGroup.prototype = Object.create(EventEmitter.prototype); ComponentGroup.prototype.constructor = ComponentGroup; /** * Checkes whether if the Entity matches its criteria. * @param entity {Entity} - The Entity to check. * @returns {Boolean} Whether if the Entity matches its criteria. */ ComponentGroup.prototype.matches = function(entity) { var compBits = entity.componentBits; if(compBits.isEmpty()) return false; if(!compBits.contains(this.contain)) return false; if(!this.intersect.isEmpty() && !this.intersect.intersects(compBits)) return false; if(this.exclude.intersects(compBits)) return false; return true; } /** * Checkes whether if the ComponentGroup equals the other. * The ComponentGroups are equal if they have same criteria. * @param o {ComponentGroup} - The other ComponentGroup. * @returns {Boolean} Whether if the ComponentGroups are equal. */ ComponentGroup.prototype.equals = function(o) { if(!this.contain.equals(o.contain)) return false; if(!this.intersect.equals(o.intersect)) return false; if(!this.exclude.equals(o.exclude)) return false; return true; } /** * Creates a Builder object that helps to make ComponentGroup object. * @static * @param engine {Engine} - The Engine which will use this ComponentGroup. * @returns {ComponentGroup.Builder} A Builder object. */ ComponentGroup.createBuilder = function(engine) { return new ComponentGroup.Builder(engine); } /** * This class helps to create a ComponentGroup object. * @constructor * @param engine {Engine} - The Engine which will use this object. */ ComponentGroup.Builder = function(engine) { this._engine = engine; this._contain = new BitSet(); this._intersect = new BitSet(); this._exclude = new BitSet(); } /** * Resets the criteria of this object. * @returns {ComponentGroup.Builder} The Builder itself to make it chainable. */ ComponentGroup.Builder.prototype.reset = function() { this._contain = new BitSet(); this._intersect = new BitSet(); this._exclude = new BitSet(); return this; } /** * Sets contain condition of the object. * @param args... {Function} - The list of component constructors. * @returns {ComponentGroup.Builder} The Builder itself to make it chainable. */ ComponentGroup.Builder.prototype.contain = function(args) { this._contain.or(this._engine.getComponentsBitSet(arguments)); return this; } /** * Sets intersect condition of the object. * @param args... {Function} - The list of component constructors. * @returns {ComponentGroup.Builder} The Builder itself to make it chainable. */ ComponentGroup.Builder.prototype.intersect = function(args) { this._intersect.or(this._engine.getComponentsBitSet(arguments)); return this; } /** * Sets exclude condition of the object. * @param args... {Function} - The list of component constructors. * @returns {ComponentGroup.Builder} The Builder itself to make it chainable. */ ComponentGroup.Builder.prototype.exclude = function(args) { this._exclude.or(this._engine.getComponentsBitSet(arguments)); return this; } /** * Builds ComponentGroup object. * @returns {ComponentGroup} The CompoentGroup object. */ ComponentGroup.Builder.prototype.build = function() { return new ComponentGroup(this._contain, this._intersect, this._exclude); } /** * This event is fired to ComponentGroup when a Entity matching its criteria * has added to {@link Engine}. * * @event ComponentGroup#entityAdded * @type {Entity} * @see Engine */ /** * This event is fired to ComponentGroup when a Entity matching its criteria * has removed from {@link Engine}. * * @event ComponentGroup#entityRemoved * @type {Entity} * @see Engine */ if(typeof module !== 'undefined') { module.exports = ComponentGroup; }