From 9125d012f5fd9d23160c1a0cfaf87d1f77b41e06 Mon Sep 17 00:00:00 2001 From: sz-piotr Date: Sat, 23 Dec 2017 13:51:11 +0100 Subject: [PATCH] entity onChange clear and build --- lib/ouyo.js | 683 +----------------------------------------------- lib/ouyo.js.map | 2 +- src/Game.js | 6 +- 3 files changed, 7 insertions(+), 684 deletions(-) diff --git a/lib/ouyo.js b/lib/ouyo.js index 91d08e0..027101e 100644 --- a/lib/ouyo.js +++ b/lib/ouyo.js @@ -1,683 +1,2 @@ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define("OUYO", [], factory); - else if(typeof exports === 'object') - exports["OUYO"] = factory(); - else - root["OUYO"] = factory(); -})(typeof self !== 'undefined' ? self : this, function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); - -// CONCATENATED MODULE: ./src/Key.js -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"); } } - -var KEY_BITS = 31; - -var POWERS = []; -for (var i = 0; i < KEY_BITS; i++) { - POWERS[i] = Math.pow(2, i); -} - -var Key = function () { - function Key(length) { - _classCallCheck(this, Key); - - this.values = []; - for (var _i = 0; _i < length / KEY_BITS; _i++) { - this.values.push(0); - } - } - - _createClass(Key, [{ - key: "set", - value: function set(index) { - this.setBit(index, true); - return this; - } - }, { - key: "unset", - value: function unset(index) { - this.setBit(index, false); - return this; - } - }, { - key: "setBit", - value: function setBit(index, value) { - var valueIndex = 0; - while (index >= KEY_BITS) { - valueIndex++; - index -= KEY_BITS; - } - - var previousValue = (this.values[valueIndex] & POWERS[index]) !== 0; - if (value && !previousValue) { - this.values[valueIndex] += POWERS[index]; - } else if (!value && previousValue) { - this.values[valueIndex] -= POWERS[index]; - } - } - }, { - key: "matches", - value: function matches(other) { - for (var _i2 = 0; _i2 < other.values.length; _i2++) { - var currentValue = this.values[_i2] || 0; - var otherValue = other.values[_i2]; - if ((currentValue & otherValue) !== otherValue) { - return false; - } - } - return true; - } - }]); - - return Key; -}(); -// CONCATENATED MODULE: ./src/utils.js -function map(array, fn) { - var result = []; - for (var i = 0; i < array.length; i++) { - result[i] = fn(array[i]); - } - return result; -} - -function filter(array, fn) { - var result = []; - for (var i = 0; i < array.length; i++) { - var value = array[i]; - if (fn(value)) { - result.push(value); - } - } - return result; -} - -function forEach(array, fn) { - for (var i = 0; i < array.length; i++) { - fn(array[i]); - } -} - -function forEach2(a, b, fn) { - for (var i = 0; i < a.length; i++) { - var aItem = a[i]; - for (var j = 0; j < b.length; j++) { - fn(aItem, b[j]); - } - } -} - -function assert(condition, errorMessage) { - if (!condition) { - throw new Error(errorMessage); - } -} -// CONCATENATED MODULE: ./src/Entity.js -var Entity__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 Entity__classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - - - - -var Entity_index = 0; - -var Entity_Entity = function () { - function Entity(componentCount, onKeyChanged) { - Entity__classCallCheck(this, Entity); - - this.id = Entity_index++; - - this.key = new Key(componentCount); - this._components = makeNullArray(componentCount); - - this._changeAnnounced = false; - this._onKeyChanged = onKeyChanged; - } - - Entity__createClass(Entity, [{ - key: 'add', - value: function add(componentInstance) { - var index = componentInstance._id; - - assert(!this._components[index], 'Cannot add another instance of the same component.'); - assert(index < this._components.length, 'Unknown component passed as argument.'); - - this.key.setBit(index, true); - this._components[index] = componentInstance; - - this._onChange(); - return this; - } - }, { - key: 'has', - value: function has(Component) { - return !!this._components[Component.id]; - } - }, { - key: 'get', - value: function get(Component) { - var component = this._components[Component.id]; - assert(component, 'Requested component is not present.'); - return component; - } - }, { - key: 'remove', - value: function remove(Component) { - var index = Component.id; - var component = this._components[index]; - - assert(component, 'Cannot remove component instance, because it doesn\'t exist on target entity.'); - - this.key.unset(index); - this._components[index] = null; - this._onChange(); - return this; - } - }, { - key: '_onChange', - value: function _onChange() { - if (!this._changeAnnounced) { - this._onKeyChanged(this); - } - this._changeAnnounced = true; - } - }, { - key: 'onChangeRegistered', - value: function onChangeRegistered() { - this._changeAnnounced = false; - } - }]); - - return Entity; -}(); - -function makeNullArray(size) { - var array = []; - for (var i = 0; i < size; i++) { - array[i] = null; - } - return array; -} -// CONCATENATED MODULE: ./src/Events.js -var Events__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 Events__classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - - - -var Events_Events = function () { - function Events() { - Events__classCallCheck(this, Events); - - this._events = []; - this._eventTimes = {}; - } - - Events__createClass(Events, [{ - key: 'emit', - value: function emit(event, time) { - if (typeof event === 'string') { - event = { type: event }; - } - var lastTime = safeGet(this._eventTimes[event.type], time); - event.timeDelta = (time - lastTime) / 1000; - this._eventTimes[event.type] = time; - this._events.push(event); - } - }, { - key: 'get', - value: function get(eventType) { - return filter(this._events, function (e) { - return e.type === eventType; - }); - } - }, { - key: 'clear', - value: function clear() { - this._events.length = 0; - } - }]); - - return Events; -}(); - -function safeGet(value, fallback) { - return value !== undefined ? value : fallback; -} -// CONCATENATED MODULE: ./src/IndexedArray.js -var IndexedArray__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 IndexedArray__classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var IndexedArray = function () { - function IndexedArray() { - IndexedArray__classCallCheck(this, IndexedArray); - - this._indices = {}; - this.elements = []; - } - - IndexedArray__createClass(IndexedArray, [{ - key: "put", - value: function put(object) { - this._indices[object.id] = this.elements.length; - this.elements.push(object); - } - }, { - key: "has", - value: function has(object) { - return this._indices[object.id] !== undefined; - } - }, { - key: "remove", - value: function remove(object) { - var index = this._indices[object.id]; - if (index !== undefined) { - delete this._indices[object.id]; - var otherObject = this.elements.pop(); - if (otherObject.id !== object.id) { - this.elements[index] = otherObject; - this._indices[otherObject.id] = index; - } - } - } - }]); - - return IndexedArray; -}(); -// CONCATENATED MODULE: ./src/Query.js -var Query__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 Query__classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - - - - - -var Query_Query = function () { - function Query() { - var _this = this; - - Query__classCallCheck(this, Query); - - this._entities = new IndexedArray(); - this._one = false; - - this.subQueries = [this]; - - for (var _len = arguments.length, components = Array(_len), _key = 0; _key < _len; _key++) { - components[_key] = arguments[_key]; - } - - this.key = new Key(Query_maxId(components) + 1); - forEach(components, function (_ref) { - var id = _ref.id; - return _this.key.set(id); - }); - } - - Query__createClass(Query, [{ - key: 'one', - value: function one() { - this._one = true; - return this; - } - }, { - key: 'onChange', - value: function onChange(entity) { - var isInQuery = this._entities.has(entity); - var matched = entity.key.matches(this.key); - - if (!isInQuery && matched) { - this._entities.put(entity); - } else if (isInQuery && !matched) { - this._entities.remove(entity); - } - } - }, { - key: 'onRemove', - value: function onRemove(entity) { - this._entities.remove(entity); - } - }, { - key: 'entities', - get: function get() { - return this._one ? this._entities.elements[0] : this._entities.elements; - } - }]); - - return Query; -}(); - -function Query_maxId(components) { - var maxId = 0; - forEach(components, function (_ref2) { - var id = _ref2.id; - return id > maxId && (maxId = id); - }); - return maxId; -} - -var Query_QueryArray = function () { - function QueryArray(queries) { - Query__classCallCheck(this, QueryArray); - - this.subQueries = queries; - } - - Query__createClass(QueryArray, [{ - key: 'entities', - get: function get() { - return map(this.subQueries, function (query) { - return query.entities; - }); - } - }]); - - return QueryArray; -}(); - -var emptyQuery = { - entities: [], - subQueries: [] -}; - -function unifyQuery() { - var query = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : emptyQuery; - - return Array.isArray(query) ? new Query_QueryArray(query) : query; -} -// CONCATENATED MODULE: ./src/component.js - - -function component_createComponent(fields, id) { - var body = ''; - forEach(fields, function (field) { - assert(isValid(field), 'Invalid identifier: ' + field); - body += 'this.' + field + '=' + field + ';'; - }); - /* eslint-disable no-new-func */ - return decorate(new Function(fields, body), id); -} - -function isValid(field) { - return (/^[a-zA-Z]\w*$/.exec(field) - ); -} - -function decorate(constructor, id) { - constructor.id = id; - constructor.prototype._id = id; - return constructor; -} -// CONCATENATED MODULE: ./src/ticker.js -var defaultTicker = function defaultTicker(update) { - window.requestAnimationFrame(onAnimationFrame); - var lastTime = Date.now(); - function onAnimationFrame() { - window.requestAnimationFrame(onAnimationFrame); - var now = Date.now(); - update(Math.min(now - lastTime, 100)); - lastTime = now; - } -}; -// CONCATENATED MODULE: ./src/Game.js -var Game__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 Game__classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - - - - - - - - -var Game_Game = function () { - function Game() { - var _this = this; - - var onTick = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultTicker; - - Game__classCallCheck(this, Game); - - this._changed = []; - this._removed = []; - - this._systems = []; - this._queries = []; - - this._events = new Events_Events(); - - this._componentCount = 0; - - this._started = false; - this._time = 0; - this._onTick = onTick; - this._onEntityChange = function (entity) { - return _this._changed.push(entity); - }; - - this._proxy = { - createEntity: function createEntity(assemblage) { - return _this._createEntity(assemblage); - }, - removeEntity: function removeEntity(entity) { - return _this._removeEntity(entity); - }, - emit: function emit(event) { - return _this._emit(event); - } - }; - } - - Game__createClass(Game, [{ - key: 'createComponent', - value: function createComponent() { - assert(!this._started, 'Cannot create component after the game was started.'); - - for (var _len = arguments.length, fields = Array(_len), _key = 0; _key < _len; _key++) { - fields[_key] = arguments[_key]; - } - - return component_createComponent(fields, this._componentCount++); - } - }, { - key: 'registerSystems', - value: function registerSystems(systems) { - var _this2 = this; - - forEach(systems, function (system) { - return _this2.registerSystem(system); - }); - } - }, { - key: 'registerSystem', - value: function registerSystem(system) { - var _this3 = this; - - assert(!this._started, 'Cannot register systems after the game was started.'); - - var query = unifyQuery(system.query); - - this._systems.push({ - query: query, - on: system.on || 'tick', - process: system.process || createProcess(system.processEntity) - }); - - forEach(query.subQueries, function (subQuery) { - return _this3._queries.push(subQuery); - }); - } - }, { - key: 'start', - value: function start(init) { - var _this4 = this; - - assert(!this._started, 'A game can only be started once!'); - this._started = true; - - init(this._proxy); - - this._onTick(function (timeDelta) { - return _this4._update(timeDelta); - }); - } - }, { - key: '_update', - value: function _update(timeDelta) { - var _this5 = this; - - this._time += timeDelta; - this._events.clear(); - this._emit('tick'); - forEach(this._systems, function (system) { - return _this5._runSystem(system); - }); - } - }, { - key: '_runSystem', - value: function _runSystem(system, timeDelta) { - var _this6 = this; - - forEach(this._events.get(system.on), function (event) { - _this6._handleChanges(); - system.process(system.query.entities, event, _this6._proxy); - }); - } - }, { - key: '_handleChanges', - value: function _handleChanges() { - forEach2(this._changed, this._queries, handleEntityChange); - this._changed.length = 0; - - forEach2(this._removed, this._queries, handleEntityRemove); - this._removed.length = 0; - } - }, { - key: '_createEntity', - value: function _createEntity(assemblage) { - assert(this._started, 'Entities cannot be created before the game is started.'); - var entity = new Entity_Entity(this._componentCount, this._onEntityChange); - if (assemblage) { - assemblage(entity); - } - return entity; - } - }, { - key: '_removeEntity', - value: function _removeEntity(entity) { - assert(this._started, 'Entities cannot be removed before the game is started.'); - this._removed.push(entity); - } - }, { - key: '_emit', - value: function _emit(event) { - this._events.emit(event, this._time); - } - }]); - - return Game; -}(); - -function createProcess(processEntity) { - return function (entities, event, game) { - for (var i = 0; i < entities.length; ++i) { - processEntity(entities[i], event, game); - } - }; -} - -function handleEntityChange(entity, query) { - query.onChange(entity); -} - -function handleEntityRemove(entity, query) { - query.onRemove(entity); -} -// CONCATENATED MODULE: ./src/index.js -/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "Game", function() { return Game_Game; }); -/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "Query", function() { return Query_Query; }); - - - -/***/ }) -/******/ ]); -}); +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("OUYO",[],t):"object"==typeof exports?exports.OUYO=t():e.OUYO=t()}("undefined"!=typeof self?self:this,function(){return function(e){function t(i){if(n[i])return n[i].exports;var r=n[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=3)}([function(e,t,n){"use strict";function i(e,t){for(var n=[],i=0;i=o;)n++,e-=o;var i=0!=(this.values[n]&u[e]);t&&!i?this.values[n]+=u[e]:!t&&i&&(this.values[n]-=u[e])}},{key:"matches",value:function(e){for(var t=0;tt&&(t=n)}),t}function o(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:l;return Array.isArray(e)?new h(e):e}n.d(t,"a",function(){return f}),t.b=o;var u=n(1),s=n(7),a=n(0),c=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:l.a;i(this,e),this._changed=[],this._removed=[],this._systems=[],this._queries=[],this._events=new a.a,this._componentCount=0,this._started=!1,this._time=0,this._onTick=n,this._onEntityChange=function(e){t._changed.push(e),e.onChangeRegistered()},this._proxy={createEntity:function(e){return t._createEntity(e)},removeEntity:function(e){return t._removeEntity(e)},emit:function(e){return t._emit(e)}}}return v(e,[{key:"createComponent",value:function(){Object(f.a)(!this._started,"Cannot create component after the game was started.");for(var e=arguments.length,t=Array(e),n=0;n= KEY_BITS) {\r\n valueIndex++\r\n index -= KEY_BITS\r\n }\r\n\r\n const previousValue = (this.values[valueIndex] & POWERS[index]) !== 0\r\n if (value && !previousValue) {\r\n this.values[valueIndex] += POWERS[index]\r\n } else if (!value && previousValue) {\r\n this.values[valueIndex] -= POWERS[index]\r\n }\r\n }\r\n\r\n matches (other) {\r\n for (let i = 0; i < other.values.length; i++) {\r\n const currentValue = this.values[i] || 0\r\n const otherValue = other.values[i]\r\n if ((currentValue & otherValue) !== otherValue) {\r\n return false\r\n }\r\n }\r\n return true\r\n }\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/Key.js","export function map (array, fn) {\n let result = []\n for (let i = 0; i < array.length; i++) {\n result[i] = fn(array[i])\n }\n return result\n}\n\nexport function filter (array, fn) {\n let result = []\n for (let i = 0; i < array.length; i++) {\n let value = array[i]\n if (fn(value)) {\n result.push(value)\n }\n }\n return result\n}\n\nexport function forEach (array, fn) {\n for (let i = 0; i < array.length; i++) {\n fn(array[i])\n }\n}\n\nexport function forEach2 (a, b, fn) {\n for (let i = 0; i < a.length; i++) {\n let aItem = a[i]\n for (let j = 0; j < b.length; j++) {\n fn(aItem, b[j])\n }\n }\n}\n\nexport function assert (condition, errorMessage) {\n if (!condition) {\n throw new Error(errorMessage)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/utils.js","import { Key } from './Key'\nimport { assert } from './utils'\n\nlet index = 0\n\nexport class Entity {\n constructor (componentCount, onKeyChanged) {\n this.id = index++\n\n this.key = new Key(componentCount)\n this._components = makeNullArray(componentCount)\n\n this._changeAnnounced = false\n this._onKeyChanged = onKeyChanged\n }\n\n add (componentInstance) {\n const index = componentInstance._id\n\n assert(!this._components[index], 'Cannot add another instance of the same component.')\n assert(index < this._components.length, 'Unknown component passed as argument.')\n\n this.key.setBit(index, true)\n this._components[index] = componentInstance\n\n this._onChange()\n return this\n }\n\n has (Component) {\n return !!this._components[Component.id]\n }\n\n get (Component) {\n const component = this._components[Component.id]\n assert(component, 'Requested component is not present.')\n return component\n }\n\n remove (Component) {\n const index = Component.id\n const component = this._components[index]\n\n assert(component, 'Cannot remove component instance, because it doesn\\'t exist on target entity.')\n\n this.key.unset(index)\n this._components[index] = null\n this._onChange()\n return this\n }\n\n _onChange () {\n if (!this._changeAnnounced) {\n this._onKeyChanged(this)\n }\n this._changeAnnounced = true\n }\n\n onChangeRegistered () {\n this._changeAnnounced = false\n }\n}\n\nfunction makeNullArray (size) {\n const array = []\n for (let i = 0; i < size; i++) {\n array[i] = null\n }\n return array\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/Entity.js","import { filter } from './utils'\n\nexport class Events {\n constructor () {\n this._events = []\n this._eventTimes = {}\n }\n\n emit (event, time) {\n if (typeof event === 'string') {\n event = { type: event }\n }\n const lastTime = safeGet(this._eventTimes[event.type], time)\n event.timeDelta = (time - lastTime) / 1000\n this._eventTimes[event.type] = time\n this._events.push(event)\n }\n\n get (eventType) {\n return filter(this._events, e => e.type === eventType)\n }\n\n clear () {\n this._events.length = 0\n }\n}\n\nfunction safeGet (value, fallback) {\n return value !== undefined ? value : fallback\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/Events.js","export class IndexedArray {\n constructor () {\n this._indices = {}\n this.elements = []\n }\n\n put (object) {\n this._indices[object.id] = this.elements.length\n this.elements.push(object)\n }\n\n has (object) {\n return this._indices[object.id] !== undefined\n }\n\n remove (object) {\n const index = this._indices[object.id]\n if (index !== undefined) {\n delete this._indices[object.id]\n const otherObject = this.elements.pop()\n if (otherObject.id !== object.id) {\n this.elements[index] = otherObject\n this._indices[otherObject.id] = index\n }\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/IndexedArray.js","import { Key } from './Key'\nimport { IndexedArray } from './IndexedArray'\nimport { forEach, map } from './utils'\n\nexport class Query {\n constructor (...components) {\n this._entities = new IndexedArray()\n this._one = false\n\n this.subQueries = [this]\n this.key = new Key(maxId(components) + 1)\n forEach(components, ({ id }) => this.key.set(id))\n }\n\n one () {\n this._one = true\n return this\n }\n\n get entities () {\n return this._one\n ? this._entities.elements[0]\n : this._entities.elements\n }\n\n onChange (entity) {\n const isInQuery = this._entities.has(entity)\n const matched = entity.key.matches(this.key)\n\n if (!isInQuery && matched) {\n this._entities.put(entity)\n } else if (isInQuery && !matched) {\n this._entities.remove(entity)\n }\n }\n\n onRemove (entity) {\n this._entities.remove(entity)\n }\n}\n\nfunction maxId (components) {\n let maxId = 0\n forEach(components, ({ id }) => id > maxId && (maxId = id))\n return maxId\n}\n\nclass QueryArray {\n constructor (queries) {\n this.subQueries = queries\n }\n\n get entities () {\n return map(this.subQueries, query => query.entities)\n }\n}\n\nconst emptyQuery = {\n entities: [],\n subQueries: []\n}\n\nexport function unifyQuery (query = emptyQuery) {\n return Array.isArray(query)\n ? new QueryArray(query)\n : query\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/Query.js","import { forEach, assert } from './utils'\n\nexport function createComponent (fields, id) {\n let body = ''\n forEach(fields, field => {\n assert(isValid(field), 'Invalid identifier: ' + field)\n body += `this.${field}=${field};`\n })\n /* eslint-disable no-new-func */\n return decorate(new Function(fields, body), id)\n}\n\nfunction isValid (field) {\n return /^[a-zA-Z]\\w*$/.exec(field)\n}\n\nfunction decorate (constructor, id) {\n constructor.id = id\n constructor.prototype._id = id\n return constructor\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/component.js","export const defaultTicker = function (update) {\n window.requestAnimationFrame(onAnimationFrame)\n let lastTime = Date.now()\n function onAnimationFrame () {\n window.requestAnimationFrame(onAnimationFrame)\n let now = Date.now()\n update(Math.min(now - lastTime, 100))\n lastTime = now\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/ticker.js","import { Entity } from './Entity'\nimport { Events } from './Events'\nimport { unifyQuery } from './Query'\nimport { assert, forEach, forEach2 } from './utils'\nimport { createComponent } from './component'\nimport { defaultTicker } from './ticker'\n\nexport class Game {\n constructor (onTick = defaultTicker) {\n this._changed = []\n this._removed = []\n\n this._systems = []\n this._queries = []\n\n this._events = new Events()\n\n this._componentCount = 0\n\n this._started = false\n this._time = 0\n this._onTick = onTick\n this._onEntityChange = entity => this._changed.push(entity)\n\n this._proxy = {\n createEntity: assemblage => this._createEntity(assemblage),\n removeEntity: entity => this._removeEntity(entity),\n emit: event => this._emit(event)\n }\n }\n\n createComponent (...fields) {\n assert(!this._started, 'Cannot create component after the game was started.')\n return createComponent(fields, this._componentCount++)\n }\n\n registerSystems (systems) {\n forEach(systems, system => this.registerSystem(system))\n }\n\n registerSystem (system) {\n assert(!this._started, 'Cannot register systems after the game was started.')\n\n const query = unifyQuery(system.query)\n\n this._systems.push({\n query,\n on: system.on || 'tick',\n process: system.process || createProcess(system.processEntity)\n })\n\n forEach(\n query.subQueries,\n subQuery => this._queries.push(subQuery)\n )\n }\n\n start (init) {\n assert(!this._started, 'A game can only be started once!')\n this._started = true\n\n init(this._proxy)\n\n this._onTick(timeDelta => this._update(timeDelta))\n }\n\n _update (timeDelta) {\n this._time += timeDelta\n this._events.clear()\n this._emit('tick')\n forEach(this._systems, system => this._runSystem(system))\n }\n\n _runSystem (system, timeDelta) {\n forEach(\n this._events.get(system.on),\n event => {\n this._handleChanges()\n system.process(system.query.entities, event, this._proxy)\n }\n )\n }\n\n _handleChanges () {\n forEach2(this._changed, this._queries, handleEntityChange)\n this._changed.length = 0\n\n forEach2(this._removed, this._queries, handleEntityRemove)\n this._removed.length = 0\n }\n\n _createEntity (assemblage) {\n assert(this._started, 'Entities cannot be created before the game is started.')\n const entity = new Entity(this._componentCount, this._onEntityChange)\n if (assemblage) {\n assemblage(entity)\n }\n return entity\n }\n\n _removeEntity (entity) {\n assert(this._started, 'Entities cannot be removed before the game is started.')\n this._removed.push(entity)\n }\n\n _emit (event) {\n this._events.emit(event, this._time)\n }\n}\n\nfunction createProcess (processEntity) {\n return function (entities, event, game) {\n for (let i = 0; i < entities.length; ++i) {\n processEntity(entities[i], event, game)\n }\n }\n}\n\nfunction handleEntityChange (entity, query) {\n query.onChange(entity)\n}\n\nfunction handleEntityRemove (entity, query) {\n query.onRemove(entity)\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/Game.js","export { Game } from './Game'\nexport { Query } from './Query'\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.js"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///ouyo.js","webpack:///webpack/bootstrap 88fd8bf3407dc35db601","webpack:///./src/utils.js","webpack:///./src/Key.js","webpack:///./src/Query.js","webpack:///./src/Game.js","webpack:///./src/Entity.js","webpack:///./src/Events.js","webpack:///./src/IndexedArray.js","webpack:///./src/component.js","webpack:///./src/ticker.js"],"names":["root","factory","exports","module","define","amd","self","this","modules","__webpack_require__","moduleId","installedModules","i","l","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","__webpack_exports__","map","array","fn","result","length","filter","value","push","forEach","forEach2","a","b","aItem","j","assert","condition","errorMessage","Error","_classCallCheck","instance","Constructor","TypeError","Key","_createClass","defineProperties","target","props","descriptor","writable","key","protoProps","staticProps","KEY_BITS","POWERS","Math","pow","values","index","setBit","valueIndex","previousValue","other","currentValue","otherValue","maxId","components","__WEBPACK_IMPORTED_MODULE_2__utils__","_ref2","id","unifyQuery","query","arguments","undefined","emptyQuery","Array","isArray","QueryArray","Query","__WEBPACK_IMPORTED_MODULE_0__Key__","__WEBPACK_IMPORTED_MODULE_1__IndexedArray__","_this","_entities","_one","subQueries","_len","_key","_ref","set","entity","isInQuery","has","matched","matches","put","remove","elements","queries","entities","__WEBPACK_IMPORTED_MODULE_0__Game__","__WEBPACK_IMPORTED_MODULE_1__Query__","createProcess","processEntity","event","game","handleEntityChange","onChange","handleEntityRemove","onRemove","Game","__WEBPACK_IMPORTED_MODULE_0__Entity__","__WEBPACK_IMPORTED_MODULE_1__Events__","__WEBPACK_IMPORTED_MODULE_2__Query__","__WEBPACK_IMPORTED_MODULE_3__utils__","__WEBPACK_IMPORTED_MODULE_4__component__","__WEBPACK_IMPORTED_MODULE_5__ticker__","onTick","_changed","_removed","_systems","_queries","_events","_componentCount","_started","_time","_onTick","_onEntityChange","onChangeRegistered","_proxy","createEntity","assemblage","_createEntity","removeEntity","_removeEntity","emit","_emit","fields","systems","_this2","system","registerSystem","_this3","on","process","subQuery","init","_this4","timeDelta","_update","_this5","clear","_runSystem","_this6","_handleChanges","makeNullArray","size","Entity","__WEBPACK_IMPORTED_MODULE_1__utils__","componentCount","onKeyChanged","_components","_changeAnnounced","_onKeyChanged","componentInstance","_id","_onChange","Component","component","unset","safeGet","fallback","Events","__WEBPACK_IMPORTED_MODULE_0__utils__","_eventTimes","time","type","lastTime","eventType","e","IndexedArray","_indices","otherObject","pop","createComponent","body","field","isValid","decorate","Function","exec","constructor","defaultTicker","update","onAnimationFrame","window","requestAnimationFrame","now","Date","min"],"mappings":"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","file":"ouyo.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"OUYO\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"OUYO\"] = factory();\n\telse\n\t\troot[\"OUYO\"] = factory();\n})(typeof self !== 'undefined' ? self : this, function() {\nreturn \n\n\n// WEBPACK FOOTER //\n// webpack/universalModuleDefinition","(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"OUYO\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"OUYO\"] = factory();\n\telse\n\t\troot[\"OUYO\"] = factory();\n})(typeof self !== 'undefined' ? self : this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 3);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (immutable) */ __webpack_exports__[\"e\"] = map;\n/* harmony export (immutable) */ __webpack_exports__[\"b\"] = filter;\n/* harmony export (immutable) */ __webpack_exports__[\"c\"] = forEach;\n/* harmony export (immutable) */ __webpack_exports__[\"d\"] = forEach2;\n/* harmony export (immutable) */ __webpack_exports__[\"a\"] = assert;\nfunction map(array, fn) {\n var result = [];\n for (var i = 0; i < array.length; i++) {\n result[i] = fn(array[i]);\n }\n return result;\n}\n\nfunction filter(array, fn) {\n var result = [];\n for (var i = 0; i < array.length; i++) {\n var value = array[i];\n if (fn(value)) {\n result.push(value);\n }\n }\n return result;\n}\n\nfunction forEach(array, fn) {\n for (var i = 0; i < array.length; i++) {\n fn(array[i]);\n }\n}\n\nfunction forEach2(a, b, fn) {\n for (var i = 0; i < a.length; i++) {\n var aItem = a[i];\n for (var j = 0; j < b.length; j++) {\n fn(aItem, b[j]);\n }\n }\n}\n\nfunction assert(condition, errorMessage) {\n if (!condition) {\n throw new Error(errorMessage);\n }\n}\n\n/***/ }),\n/* 1 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return Key; });\nvar _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; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar KEY_BITS = 31;\n\nvar POWERS = [];\nfor (var i = 0; i < KEY_BITS; i++) {\n POWERS[i] = Math.pow(2, i);\n}\n\nvar Key = function () {\n function Key(length) {\n _classCallCheck(this, Key);\n\n this.values = [];\n for (var _i = 0; _i < length / KEY_BITS; _i++) {\n this.values.push(0);\n }\n }\n\n _createClass(Key, [{\n key: \"set\",\n value: function set(index) {\n this.setBit(index, true);\n return this;\n }\n }, {\n key: \"unset\",\n value: function unset(index) {\n this.setBit(index, false);\n return this;\n }\n }, {\n key: \"setBit\",\n value: function setBit(index, value) {\n var valueIndex = 0;\n while (index >= KEY_BITS) {\n valueIndex++;\n index -= KEY_BITS;\n }\n\n var previousValue = (this.values[valueIndex] & POWERS[index]) !== 0;\n if (value && !previousValue) {\n this.values[valueIndex] += POWERS[index];\n } else if (!value && previousValue) {\n this.values[valueIndex] -= POWERS[index];\n }\n }\n }, {\n key: \"matches\",\n value: function matches(other) {\n for (var _i2 = 0; _i2 < other.values.length; _i2++) {\n var currentValue = this.values[_i2] || 0;\n var otherValue = other.values[_i2];\n if ((currentValue & otherValue) !== otherValue) {\n return false;\n }\n }\n return true;\n }\n }]);\n\n return Key;\n}();\n\n/***/ }),\n/* 2 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return Query; });\n/* harmony export (immutable) */ __webpack_exports__[\"b\"] = unifyQuery;\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Key__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__IndexedArray__ = __webpack_require__(7);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils__ = __webpack_require__(0);\nvar _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; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n\n\n\n\nvar Query = function () {\n function Query() {\n var _this = this;\n\n _classCallCheck(this, Query);\n\n this._entities = new __WEBPACK_IMPORTED_MODULE_1__IndexedArray__[\"a\" /* IndexedArray */]();\n this._one = false;\n\n this.subQueries = [this];\n\n for (var _len = arguments.length, components = Array(_len), _key = 0; _key < _len; _key++) {\n components[_key] = arguments[_key];\n }\n\n this.key = new __WEBPACK_IMPORTED_MODULE_0__Key__[\"a\" /* Key */](maxId(components) + 1);\n Object(__WEBPACK_IMPORTED_MODULE_2__utils__[\"c\" /* forEach */])(components, function (_ref) {\n var id = _ref.id;\n return _this.key.set(id);\n });\n }\n\n _createClass(Query, [{\n key: 'one',\n value: function one() {\n this._one = true;\n return this;\n }\n }, {\n key: 'onChange',\n value: function onChange(entity) {\n var isInQuery = this._entities.has(entity);\n var matched = entity.key.matches(this.key);\n\n if (!isInQuery && matched) {\n this._entities.put(entity);\n } else if (isInQuery && !matched) {\n this._entities.remove(entity);\n }\n }\n }, {\n key: 'onRemove',\n value: function onRemove(entity) {\n this._entities.remove(entity);\n }\n }, {\n key: 'entities',\n get: function get() {\n return this._one ? this._entities.elements[0] : this._entities.elements;\n }\n }]);\n\n return Query;\n}();\n\nfunction maxId(components) {\n var maxId = 0;\n Object(__WEBPACK_IMPORTED_MODULE_2__utils__[\"c\" /* forEach */])(components, function (_ref2) {\n var id = _ref2.id;\n return id > maxId && (maxId = id);\n });\n return maxId;\n}\n\nvar QueryArray = function () {\n function QueryArray(queries) {\n _classCallCheck(this, QueryArray);\n\n this.subQueries = queries;\n }\n\n _createClass(QueryArray, [{\n key: 'entities',\n get: function get() {\n return Object(__WEBPACK_IMPORTED_MODULE_2__utils__[\"e\" /* map */])(this.subQueries, function (query) {\n return query.entities;\n });\n }\n }]);\n\n return QueryArray;\n}();\n\nvar emptyQuery = {\n entities: [],\n subQueries: []\n};\n\nfunction unifyQuery() {\n var query = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : emptyQuery;\n\n return Array.isArray(query) ? new QueryArray(query) : query;\n}\n\n/***/ }),\n/* 3 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Game__ = __webpack_require__(4);\n/* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, \"Game\", function() { return __WEBPACK_IMPORTED_MODULE_0__Game__[\"a\"]; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Query__ = __webpack_require__(2);\n/* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, \"Query\", function() { return __WEBPACK_IMPORTED_MODULE_1__Query__[\"a\"]; });\n\n\n\n/***/ }),\n/* 4 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return Game; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Entity__ = __webpack_require__(5);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Events__ = __webpack_require__(6);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Query__ = __webpack_require__(2);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__utils__ = __webpack_require__(0);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__component__ = __webpack_require__(8);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__ticker__ = __webpack_require__(9);\nvar _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; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n\n\n\n\n\n\n\nvar Game = function () {\n function Game() {\n var _this = this;\n\n var onTick = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : __WEBPACK_IMPORTED_MODULE_5__ticker__[\"a\" /* defaultTicker */];\n\n _classCallCheck(this, Game);\n\n this._changed = [];\n this._removed = [];\n\n this._systems = [];\n this._queries = [];\n\n this._events = new __WEBPACK_IMPORTED_MODULE_1__Events__[\"a\" /* Events */]();\n\n this._componentCount = 0;\n\n this._started = false;\n this._time = 0;\n this._onTick = onTick;\n\n this._onEntityChange = function (entity) {\n _this._changed.push(entity);\n entity.onChangeRegistered();\n };\n\n this._proxy = {\n createEntity: function createEntity(assemblage) {\n return _this._createEntity(assemblage);\n },\n removeEntity: function removeEntity(entity) {\n return _this._removeEntity(entity);\n },\n emit: function emit(event) {\n return _this._emit(event);\n }\n };\n }\n\n _createClass(Game, [{\n key: 'createComponent',\n value: function createComponent() {\n Object(__WEBPACK_IMPORTED_MODULE_3__utils__[\"a\" /* assert */])(!this._started, 'Cannot create component after the game was started.');\n\n for (var _len = arguments.length, fields = Array(_len), _key = 0; _key < _len; _key++) {\n fields[_key] = arguments[_key];\n }\n\n return Object(__WEBPACK_IMPORTED_MODULE_4__component__[\"a\" /* createComponent */])(fields, this._componentCount++);\n }\n }, {\n key: 'registerSystems',\n value: function registerSystems(systems) {\n var _this2 = this;\n\n Object(__WEBPACK_IMPORTED_MODULE_3__utils__[\"c\" /* forEach */])(systems, function (system) {\n return _this2.registerSystem(system);\n });\n }\n }, {\n key: 'registerSystem',\n value: function registerSystem(system) {\n var _this3 = this;\n\n Object(__WEBPACK_IMPORTED_MODULE_3__utils__[\"a\" /* assert */])(!this._started, 'Cannot register systems after the game was started.');\n\n var query = Object(__WEBPACK_IMPORTED_MODULE_2__Query__[\"b\" /* unifyQuery */])(system.query);\n\n this._systems.push({\n query: query,\n on: system.on || 'tick',\n process: system.process || createProcess(system.processEntity)\n });\n\n Object(__WEBPACK_IMPORTED_MODULE_3__utils__[\"c\" /* forEach */])(query.subQueries, function (subQuery) {\n return _this3._queries.push(subQuery);\n });\n }\n }, {\n key: 'start',\n value: function start(init) {\n var _this4 = this;\n\n Object(__WEBPACK_IMPORTED_MODULE_3__utils__[\"a\" /* assert */])(!this._started, 'A game can only be started once!');\n this._started = true;\n\n init(this._proxy);\n\n this._onTick(function (timeDelta) {\n return _this4._update(timeDelta);\n });\n }\n }, {\n key: '_update',\n value: function _update(timeDelta) {\n var _this5 = this;\n\n this._time += timeDelta;\n this._events.clear();\n this._emit('tick');\n Object(__WEBPACK_IMPORTED_MODULE_3__utils__[\"c\" /* forEach */])(this._systems, function (system) {\n return _this5._runSystem(system);\n });\n }\n }, {\n key: '_runSystem',\n value: function _runSystem(system, timeDelta) {\n var _this6 = this;\n\n Object(__WEBPACK_IMPORTED_MODULE_3__utils__[\"c\" /* forEach */])(this._events.get(system.on), function (event) {\n _this6._handleChanges();\n system.process(system.query.entities, event, _this6._proxy);\n });\n }\n }, {\n key: '_handleChanges',\n value: function _handleChanges() {\n Object(__WEBPACK_IMPORTED_MODULE_3__utils__[\"d\" /* forEach2 */])(this._changed, this._queries, handleEntityChange);\n this._changed.length = 0;\n\n Object(__WEBPACK_IMPORTED_MODULE_3__utils__[\"d\" /* forEach2 */])(this._removed, this._queries, handleEntityRemove);\n this._removed.length = 0;\n }\n }, {\n key: '_createEntity',\n value: function _createEntity(assemblage) {\n Object(__WEBPACK_IMPORTED_MODULE_3__utils__[\"a\" /* assert */])(this._started, 'Entities cannot be created before the game is started.');\n var entity = new __WEBPACK_IMPORTED_MODULE_0__Entity__[\"a\" /* Entity */](this._componentCount, this._onEntityChange);\n if (assemblage) {\n assemblage(entity);\n }\n return entity;\n }\n }, {\n key: '_removeEntity',\n value: function _removeEntity(entity) {\n Object(__WEBPACK_IMPORTED_MODULE_3__utils__[\"a\" /* assert */])(this._started, 'Entities cannot be removed before the game is started.');\n this._removed.push(entity);\n }\n }, {\n key: '_emit',\n value: function _emit(event) {\n this._events.emit(event, this._time);\n }\n }]);\n\n return Game;\n}();\n\nfunction createProcess(processEntity) {\n return function (entities, event, game) {\n for (var i = 0; i < entities.length; ++i) {\n processEntity(entities[i], event, game);\n }\n };\n}\n\nfunction handleEntityChange(entity, query) {\n query.onChange(entity);\n}\n\nfunction handleEntityRemove(entity, query) {\n query.onRemove(entity);\n}\n\n/***/ }),\n/* 5 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return Entity; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Key__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils__ = __webpack_require__(0);\nvar _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; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n\n\n\nvar index = 0;\n\nvar Entity = function () {\n function Entity(componentCount, onKeyChanged) {\n _classCallCheck(this, Entity);\n\n this.id = index++;\n\n this.key = new __WEBPACK_IMPORTED_MODULE_0__Key__[\"a\" /* Key */](componentCount);\n this._components = makeNullArray(componentCount);\n\n this._changeAnnounced = false;\n this._onKeyChanged = onKeyChanged;\n }\n\n _createClass(Entity, [{\n key: 'add',\n value: function add(componentInstance) {\n var index = componentInstance._id;\n\n Object(__WEBPACK_IMPORTED_MODULE_1__utils__[\"a\" /* assert */])(!this._components[index], 'Cannot add another instance of the same component.');\n Object(__WEBPACK_IMPORTED_MODULE_1__utils__[\"a\" /* assert */])(index < this._components.length, 'Unknown component passed as argument.');\n\n this.key.setBit(index, true);\n this._components[index] = componentInstance;\n\n this._onChange();\n return this;\n }\n }, {\n key: 'has',\n value: function has(Component) {\n return !!this._components[Component.id];\n }\n }, {\n key: 'get',\n value: function get(Component) {\n var component = this._components[Component.id];\n Object(__WEBPACK_IMPORTED_MODULE_1__utils__[\"a\" /* assert */])(component, 'Requested component is not present.');\n return component;\n }\n }, {\n key: 'remove',\n value: function remove(Component) {\n var index = Component.id;\n var component = this._components[index];\n\n Object(__WEBPACK_IMPORTED_MODULE_1__utils__[\"a\" /* assert */])(component, 'Cannot remove component instance, because it doesn\\'t exist on target entity.');\n\n this.key.unset(index);\n this._components[index] = null;\n this._onChange();\n return this;\n }\n }, {\n key: '_onChange',\n value: function _onChange() {\n if (!this._changeAnnounced) {\n this._onKeyChanged(this);\n }\n this._changeAnnounced = true;\n }\n }, {\n key: 'onChangeRegistered',\n value: function onChangeRegistered() {\n this._changeAnnounced = false;\n }\n }]);\n\n return Entity;\n}();\n\nfunction makeNullArray(size) {\n var array = [];\n for (var i = 0; i < size; i++) {\n array[i] = null;\n }\n return array;\n}\n\n/***/ }),\n/* 6 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return Events; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils__ = __webpack_require__(0);\nvar _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; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n\n\nvar Events = function () {\n function Events() {\n _classCallCheck(this, Events);\n\n this._events = [];\n this._eventTimes = {};\n }\n\n _createClass(Events, [{\n key: 'emit',\n value: function emit(event, time) {\n if (typeof event === 'string') {\n event = { type: event };\n }\n var lastTime = safeGet(this._eventTimes[event.type], time);\n event.timeDelta = (time - lastTime) / 1000;\n this._eventTimes[event.type] = time;\n this._events.push(event);\n }\n }, {\n key: 'get',\n value: function get(eventType) {\n return Object(__WEBPACK_IMPORTED_MODULE_0__utils__[\"b\" /* filter */])(this._events, function (e) {\n return e.type === eventType;\n });\n }\n }, {\n key: 'clear',\n value: function clear() {\n this._events.length = 0;\n }\n }]);\n\n return Events;\n}();\n\nfunction safeGet(value, fallback) {\n return value !== undefined ? value : fallback;\n}\n\n/***/ }),\n/* 7 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return IndexedArray; });\nvar _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; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar IndexedArray = function () {\n function IndexedArray() {\n _classCallCheck(this, IndexedArray);\n\n this._indices = {};\n this.elements = [];\n }\n\n _createClass(IndexedArray, [{\n key: \"put\",\n value: function put(object) {\n this._indices[object.id] = this.elements.length;\n this.elements.push(object);\n }\n }, {\n key: \"has\",\n value: function has(object) {\n return this._indices[object.id] !== undefined;\n }\n }, {\n key: \"remove\",\n value: function remove(object) {\n var index = this._indices[object.id];\n if (index !== undefined) {\n delete this._indices[object.id];\n var otherObject = this.elements.pop();\n if (otherObject.id !== object.id) {\n this.elements[index] = otherObject;\n this._indices[otherObject.id] = index;\n }\n }\n }\n }]);\n\n return IndexedArray;\n}();\n\n/***/ }),\n/* 8 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (immutable) */ __webpack_exports__[\"a\"] = createComponent;\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils__ = __webpack_require__(0);\n\n\nfunction createComponent(fields, id) {\n var body = '';\n Object(__WEBPACK_IMPORTED_MODULE_0__utils__[\"c\" /* forEach */])(fields, function (field) {\n Object(__WEBPACK_IMPORTED_MODULE_0__utils__[\"a\" /* assert */])(isValid(field), 'Invalid identifier: ' + field);\n body += 'this.' + field + '=' + field + ';';\n });\n /* eslint-disable no-new-func */\n return decorate(new Function(fields, body), id);\n}\n\nfunction isValid(field) {\n return (/^[a-zA-Z]\\w*$/.exec(field)\n );\n}\n\nfunction decorate(constructor, id) {\n constructor.id = id;\n constructor.prototype._id = id;\n return constructor;\n}\n\n/***/ }),\n/* 9 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return defaultTicker; });\nvar defaultTicker = function defaultTicker(update) {\n window.requestAnimationFrame(onAnimationFrame);\n var lastTime = Date.now();\n function onAnimationFrame() {\n window.requestAnimationFrame(onAnimationFrame);\n var now = Date.now();\n update(Math.min(now - lastTime, 100));\n lastTime = now;\n }\n};\n\n/***/ })\n/******/ ]);\n});\n\n\n// WEBPACK FOOTER //\n// ouyo.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 88fd8bf3407dc35db601","export function map (array, fn) {\n let result = []\n for (let i = 0; i < array.length; i++) {\n result[i] = fn(array[i])\n }\n return result\n}\n\nexport function filter (array, fn) {\n let result = []\n for (let i = 0; i < array.length; i++) {\n let value = array[i]\n if (fn(value)) {\n result.push(value)\n }\n }\n return result\n}\n\nexport function forEach (array, fn) {\n for (let i = 0; i < array.length; i++) {\n fn(array[i])\n }\n}\n\nexport function forEach2 (a, b, fn) {\n for (let i = 0; i < a.length; i++) {\n let aItem = a[i]\n for (let j = 0; j < b.length; j++) {\n fn(aItem, b[j])\n }\n }\n}\n\nexport function assert (condition, errorMessage) {\n if (!condition) {\n throw new Error(errorMessage)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/utils.js","const KEY_BITS = 31\r\n\r\nconst POWERS = []\r\nfor (let i = 0; i < KEY_BITS; i++) {\r\n POWERS[i] = 2 ** i\r\n}\r\n\r\nexport class Key {\r\n constructor (length) {\r\n this.values = []\r\n for (let i = 0; i < length / KEY_BITS; i++) {\r\n this.values.push(0)\r\n }\r\n }\r\n\r\n set (index) {\r\n this.setBit(index, true)\r\n return this\r\n }\r\n\r\n unset (index) {\r\n this.setBit(index, false)\r\n return this\r\n }\r\n\r\n setBit (index, value) {\r\n let valueIndex = 0\r\n while (index >= KEY_BITS) {\r\n valueIndex++\r\n index -= KEY_BITS\r\n }\r\n\r\n const previousValue = (this.values[valueIndex] & POWERS[index]) !== 0\r\n if (value && !previousValue) {\r\n this.values[valueIndex] += POWERS[index]\r\n } else if (!value && previousValue) {\r\n this.values[valueIndex] -= POWERS[index]\r\n }\r\n }\r\n\r\n matches (other) {\r\n for (let i = 0; i < other.values.length; i++) {\r\n const currentValue = this.values[i] || 0\r\n const otherValue = other.values[i]\r\n if ((currentValue & otherValue) !== otherValue) {\r\n return false\r\n }\r\n }\r\n return true\r\n }\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/Key.js","import { Key } from './Key'\nimport { IndexedArray } from './IndexedArray'\nimport { forEach, map } from './utils'\n\nexport class Query {\n constructor (...components) {\n this._entities = new IndexedArray()\n this._one = false\n\n this.subQueries = [this]\n this.key = new Key(maxId(components) + 1)\n forEach(components, ({ id }) => this.key.set(id))\n }\n\n one () {\n this._one = true\n return this\n }\n\n get entities () {\n return this._one\n ? this._entities.elements[0]\n : this._entities.elements\n }\n\n onChange (entity) {\n const isInQuery = this._entities.has(entity)\n const matched = entity.key.matches(this.key)\n\n if (!isInQuery && matched) {\n this._entities.put(entity)\n } else if (isInQuery && !matched) {\n this._entities.remove(entity)\n }\n }\n\n onRemove (entity) {\n this._entities.remove(entity)\n }\n}\n\nfunction maxId (components) {\n let maxId = 0\n forEach(components, ({ id }) => id > maxId && (maxId = id))\n return maxId\n}\n\nclass QueryArray {\n constructor (queries) {\n this.subQueries = queries\n }\n\n get entities () {\n return map(this.subQueries, query => query.entities)\n }\n}\n\nconst emptyQuery = {\n entities: [],\n subQueries: []\n}\n\nexport function unifyQuery (query = emptyQuery) {\n return Array.isArray(query)\n ? new QueryArray(query)\n : query\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/Query.js","import { Entity } from './Entity'\nimport { Events } from './Events'\nimport { unifyQuery } from './Query'\nimport { assert, forEach, forEach2 } from './utils'\nimport { createComponent } from './component'\nimport { defaultTicker } from './ticker'\n\nexport class Game {\n constructor (onTick = defaultTicker) {\n this._changed = []\n this._removed = []\n\n this._systems = []\n this._queries = []\n\n this._events = new Events()\n\n this._componentCount = 0\n\n this._started = false\n this._time = 0\n this._onTick = onTick\n\n this._onEntityChange = entity => {\n this._changed.push(entity)\n entity.onChangeRegistered()\n }\n\n this._proxy = {\n createEntity: assemblage => this._createEntity(assemblage),\n removeEntity: entity => this._removeEntity(entity),\n emit: event => this._emit(event)\n }\n }\n\n createComponent (...fields) {\n assert(!this._started, 'Cannot create component after the game was started.')\n return createComponent(fields, this._componentCount++)\n }\n\n registerSystems (systems) {\n forEach(systems, system => this.registerSystem(system))\n }\n\n registerSystem (system) {\n assert(!this._started, 'Cannot register systems after the game was started.')\n\n const query = unifyQuery(system.query)\n\n this._systems.push({\n query,\n on: system.on || 'tick',\n process: system.process || createProcess(system.processEntity)\n })\n\n forEach(\n query.subQueries,\n subQuery => this._queries.push(subQuery)\n )\n }\n\n start (init) {\n assert(!this._started, 'A game can only be started once!')\n this._started = true\n\n init(this._proxy)\n\n this._onTick(timeDelta => this._update(timeDelta))\n }\n\n _update (timeDelta) {\n this._time += timeDelta\n this._events.clear()\n this._emit('tick')\n forEach(this._systems, system => this._runSystem(system))\n }\n\n _runSystem (system, timeDelta) {\n forEach(\n this._events.get(system.on),\n event => {\n this._handleChanges()\n system.process(system.query.entities, event, this._proxy)\n }\n )\n }\n\n _handleChanges () {\n forEach2(this._changed, this._queries, handleEntityChange)\n this._changed.length = 0\n\n forEach2(this._removed, this._queries, handleEntityRemove)\n this._removed.length = 0\n }\n\n _createEntity (assemblage) {\n assert(this._started, 'Entities cannot be created before the game is started.')\n const entity = new Entity(this._componentCount, this._onEntityChange)\n if (assemblage) {\n assemblage(entity)\n }\n return entity\n }\n\n _removeEntity (entity) {\n assert(this._started, 'Entities cannot be removed before the game is started.')\n this._removed.push(entity)\n }\n\n _emit (event) {\n this._events.emit(event, this._time)\n }\n}\n\nfunction createProcess (processEntity) {\n return function (entities, event, game) {\n for (let i = 0; i < entities.length; ++i) {\n processEntity(entities[i], event, game)\n }\n }\n}\n\nfunction handleEntityChange (entity, query) {\n query.onChange(entity)\n}\n\nfunction handleEntityRemove (entity, query) {\n query.onRemove(entity)\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/Game.js","import { Key } from './Key'\nimport { assert } from './utils'\n\nlet index = 0\n\nexport class Entity {\n constructor (componentCount, onKeyChanged) {\n this.id = index++\n\n this.key = new Key(componentCount)\n this._components = makeNullArray(componentCount)\n\n this._changeAnnounced = false\n this._onKeyChanged = onKeyChanged\n }\n\n add (componentInstance) {\n const index = componentInstance._id\n\n assert(!this._components[index], 'Cannot add another instance of the same component.')\n assert(index < this._components.length, 'Unknown component passed as argument.')\n\n this.key.setBit(index, true)\n this._components[index] = componentInstance\n\n this._onChange()\n return this\n }\n\n has (Component) {\n return !!this._components[Component.id]\n }\n\n get (Component) {\n const component = this._components[Component.id]\n assert(component, 'Requested component is not present.')\n return component\n }\n\n remove (Component) {\n const index = Component.id\n const component = this._components[index]\n\n assert(component, 'Cannot remove component instance, because it doesn\\'t exist on target entity.')\n\n this.key.unset(index)\n this._components[index] = null\n this._onChange()\n return this\n }\n\n _onChange () {\n if (!this._changeAnnounced) {\n this._onKeyChanged(this)\n }\n this._changeAnnounced = true\n }\n\n onChangeRegistered () {\n this._changeAnnounced = false\n }\n}\n\nfunction makeNullArray (size) {\n const array = []\n for (let i = 0; i < size; i++) {\n array[i] = null\n }\n return array\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/Entity.js","import { filter } from './utils'\n\nexport class Events {\n constructor () {\n this._events = []\n this._eventTimes = {}\n }\n\n emit (event, time) {\n if (typeof event === 'string') {\n event = { type: event }\n }\n const lastTime = safeGet(this._eventTimes[event.type], time)\n event.timeDelta = (time - lastTime) / 1000\n this._eventTimes[event.type] = time\n this._events.push(event)\n }\n\n get (eventType) {\n return filter(this._events, e => e.type === eventType)\n }\n\n clear () {\n this._events.length = 0\n }\n}\n\nfunction safeGet (value, fallback) {\n return value !== undefined ? value : fallback\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/Events.js","export class IndexedArray {\n constructor () {\n this._indices = {}\n this.elements = []\n }\n\n put (object) {\n this._indices[object.id] = this.elements.length\n this.elements.push(object)\n }\n\n has (object) {\n return this._indices[object.id] !== undefined\n }\n\n remove (object) {\n const index = this._indices[object.id]\n if (index !== undefined) {\n delete this._indices[object.id]\n const otherObject = this.elements.pop()\n if (otherObject.id !== object.id) {\n this.elements[index] = otherObject\n this._indices[otherObject.id] = index\n }\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/IndexedArray.js","import { forEach, assert } from './utils'\n\nexport function createComponent (fields, id) {\n let body = ''\n forEach(fields, field => {\n assert(isValid(field), 'Invalid identifier: ' + field)\n body += `this.${field}=${field};`\n })\n /* eslint-disable no-new-func */\n return decorate(new Function(fields, body), id)\n}\n\nfunction isValid (field) {\n return /^[a-zA-Z]\\w*$/.exec(field)\n}\n\nfunction decorate (constructor, id) {\n constructor.id = id\n constructor.prototype._id = id\n return constructor\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/component.js","export const defaultTicker = function (update) {\n window.requestAnimationFrame(onAnimationFrame)\n let lastTime = Date.now()\n function onAnimationFrame () {\n window.requestAnimationFrame(onAnimationFrame)\n let now = Date.now()\n update(Math.min(now - lastTime, 100))\n lastTime = now\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/ticker.js"],"sourceRoot":""} \ No newline at end of file diff --git a/src/Game.js b/src/Game.js index 7b03ed4..ca26c18 100644 --- a/src/Game.js +++ b/src/Game.js @@ -20,7 +20,11 @@ export class Game { this._started = false this._time = 0 this._onTick = onTick - this._onEntityChange = entity => this._changed.push(entity) + + this._onEntityChange = entity => { + this._changed.push(entity) + entity.onChangeRegistered() + } this._proxy = { createEntity: assemblage => this._createEntity(assemblage),