UNPKG

sam-ecs

Version:

A specialized entity component system

272 lines (224 loc) 8.77 kB
'use strict'; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } //ProcessorManager.js// /** * @description - Manages the processors in the ECS * @author - Sam Faulkner */ var Dict = require('collections/dict.js'), Set = require('collections/set.js'), SortedSet = require('collections/sorted-set.js'); var ProcessorManager = function () { function ProcessorManager(stateManager) { _classCallCheck(this, ProcessorManager); if (!stateManager) throw new TypeError("StateManager must be defined!"); this._stateManager = stateManager; var _this = this; this._processorsOrder = new SortedSet([], function (first, second) { return first.order == second.order; }, function (first, second) { return first.order - second.order; }); this._processors = new Dict(); this._processorOrder = 0; this._stateManager._entities.addMapChangeListener(function (value, key, map) { // entity was removed was deleted if (!value) { _this._processors.forEach(function (processorValue, processorKey) { if (processorValue.get('cachedEntityList').has(key)) { _this.fetchCachedList(processorValue.get('name')); } }); } // entity was added else { _this._processors.forEach(function (processorValue, processorKey) { if (processorValue.get('object').getComponentNames().testEntity(value.get('object')) || //the entity removed one of its components processorValue.get('cachedEntityList').has(key)) { _this.fetchCachedList(processorValue.get('name')); } }); } }, 'entities', false); } /** * @description - Gets the processor set * @returns {Set} the set of processors */ _createClass(ProcessorManager, [{ key: 'getProcessors', value: function getProcessors() { return this._processors; } /** * @description - Gets the processor order set * @returns {Set} the sorted set of processor objects that * are used to determine the processor order */ }, { key: 'getProcessorOrder', value: function getProcessorOrder() { return this._processorsOrder; } /** * @description - Adds a processor to the processor manager * @param {Processor} processor - the processor to be added */ }, { key: 'addProcessor', value: function addProcessor(processor) { var addToOrder = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; this._processors.set(processor.getName(), new Dict({ 'name': processor.getName(), 'order': ++this._processorOrder, 'object': processor, 'cachedEntityList': new Set() })); /* in case we would want a processor to be updated seperately * (like a RenderProcessor) we don't always add it to the update order */ if (addToOrder) { this._processorsOrder.add({ 'name': processor.getName(), 'order': this._processorOrder }); } this.fetchCachedList(processor.getName()); } /** * @description - Gets the entities that belong to the family of entites * the processor has defined * @param {String} processorName - the name of the processor to fetch entites * for */ }, { key: 'fetchCachedList', value: function fetchCachedList(processorName) { if (!this._processors.has(processorName)) { throw new TypeError("Can't fetch an entity list for an untracked processor: '" + processorName + "'!"); } var _this = this, processorObject = this._processors.get(processorName), list = new Set(this._stateManager.getEntitySet().toArray()), sorted = false; if (processorObject.has('sorter')) { sorted = true; list = new SortedSet(list.toArray(), function (first, second) { return first === second; }, function (first, second) { return processorObject.get('sorter')(first, second, _this._stateManager); }); } var family = processorObject.get('object').getComponentNames(); var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = family.getHaves().toArray()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var component = _step.value; if (!this._stateManager.hasComponent(component)) { processorObject.set('cachedEntityList', new Set()); return; } list = list.intersection(this._stateManager.getEntitiesByComponent(component)); if (list.length <= 0) break; } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } if (list.length > 0) { var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = family.getCannotHaves().toArray()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var component = _step2.value; if (this._stateManager.hasComponent(component)) { list = list.difference(this._stateManager.getEntitiesByComponent(component)); } if (list.length <= 0) break; } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } processorObject.set('cachedEntityList', list); } /** * @description - Removes a processor from the processor manager * @param {Processor} processor - the processor to be removed */ }, { key: 'removeProcessor', value: function removeProcessor(processor) { if (this._processors.has(processor.getName())) { this._processorsOrder.remove({ 'name': processor.getName(), 'order': this._processors.get(processor.getName()).get('order') }); this._processors.delete(processor.getName()); } } /** * @description - Updates all the processors this manager has */ }, { key: 'update', value: function update() { var _this = this; this._processorsOrder.forEach(function (value, index) { _this.updateProcessor(value.name); }); } /** * @description - Updates a single processor * @param {String} processorName - the name of the processor to update */ }, { key: 'updateProcessor', value: function updateProcessor(processorName) { var processorObject = this._processors.get(processorName); processorObject.get('object').update(processorObject.get('cachedEntityList')); } /** * @description - Adds a sorter for the entities to be processed * by a given processor */ }, { key: 'addSorterForProcessor', value: function addSorterForProcessor(sorter, processorName) { if (!this._processors.has(processorName)) { throw new TypeError("Can't add a sorting function for processor: '" + processorName + "'!"); } var processorObject = this._processors.get(processorName); processorObject.set('sorter', sorter); this.fetchCachedList(processorName); } }]); return ProcessorManager; }(); module.exports = ProcessorManager;