From 0cfa3573f356ea663b42e44b2e8c88ebf9d62a9e Mon Sep 17 00:00:00 2001 From: YHH <359807859@qq.com> Date: Wed, 10 May 2023 22:25:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=B1=BB=E5=9E=8B=E5=88=AB?= =?UTF-8?q?=E5=90=8D=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81=20|=20=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E6=94=B9=E8=BF=9B=20|=20=E4=BD=BF=E7=94=A8=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E5=AD=97=E7=AC=A6=E4=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/bin/gs.d.ts | 20 +++++++++------- source/bin/gs.js | 20 +++++++++++++++- source/bin/gs.min.js | 2 +- source/src/Core/Entity.ts | 5 ++++ source/src/Manager/ComponentManager.ts | 4 +--- source/src/Manager/EntityManager.ts | 32 +++++++++++++++++++------- 6 files changed, 62 insertions(+), 21 deletions(-) diff --git a/source/bin/gs.d.ts b/source/bin/gs.d.ts index dafc069..ee385ea 100644 --- a/source/bin/gs.d.ts +++ b/source/bin/gs.d.ts @@ -327,9 +327,7 @@ declare module gs { } } declare module gs { - type ComponentConstructor = { - new (): T; - }; + type ComponentConstructor = new (...args: any[]) => T; /** * 组件管理器 */ @@ -390,13 +388,13 @@ declare module gs { private queryCache; private tagCache; systemManager?: SystemManager; - constructor(componentClasses?: Array>, systemManager?: SystemManager); + constructor(componentClasses?: Array>, systemManager?: SystemManager); setSystemManager(systemManager: SystemManager): void; /** * 添加组件管理器 * @param componentClass 要添加的组件类 */ - addComponentManager(componentClass: new (...args: any[]) => T): void; + addComponentManager(componentClass: ComponentConstructor): void; updateFrameNumber(): void; getCurrentFrameNumber(): number; getInputManager(): InputManager; @@ -422,13 +420,13 @@ declare module gs { * @param componentClass 要检查的组件类 * @returns 具有指定组件的实体数组 */ - getEntitiesWithComponent(componentClass: new (...args: any[]) => T): Entity[]; + getEntitiesWithComponent(componentClass: ComponentConstructor): Entity[]; /** * 查找具有指定组件的实体 * @param componentClasses * @returns */ - getEntitiesWithComponents(componentClasses: Array T>): Entity[]; + getEntitiesWithComponents(componentClasses: ComponentConstructor[]): Entity[]; /** * 获取所有实体 * @returns @@ -445,7 +443,7 @@ declare module gs { * @param components 要查询的组件数组 * @returns 符合查询条件的实体数组 */ - queryComponents(components: (new (entityId: number) => Component)[]): Entity[]; + queryComponents(components: ComponentConstructor[]): Entity[]; private performQuery; /** * 创建当前游戏状态的快照 @@ -468,6 +466,12 @@ declare module gs { * @param factor */ applyInterpolation(factor: number): void; + /** + * 清除指定组件或标签的缓存 + * @param componentClass + * @param tag + */ + invalidateCache(componentClass?: ComponentConstructor, tag?: string): void; } } declare module gs { diff --git a/source/bin/gs.js b/source/bin/gs.js index e11bca2..14b5d1d 100644 --- a/source/bin/gs.js +++ b/source/bin/gs.js @@ -327,6 +327,7 @@ var gs; if (this.entityManager.systemManager) { this.entityManager.systemManager.notifyComponentAdded(this); } + this.entityManager.invalidateCache(componentType); return component; }; /** @@ -382,6 +383,7 @@ var gs; this.componentBits.clear(componentIndex); // 移除组件缓存 this.componentCache.delete(componentType); + this.entityManager.invalidateCache(componentType); }; /** * 是否有组件 @@ -404,6 +406,7 @@ var gs; */ Entity.prototype.addTag = function (tag) { this.tags.add(tag); + this.entityManager.invalidateCache(undefined, tag); }; /** * 获取标签 @@ -418,6 +421,7 @@ var gs; */ Entity.prototype.removeTag = function (tag) { this.tags.delete(tag); + this.entityManager.invalidateCache(undefined, tag); }; /** * 检查是否具有指定标签 @@ -1003,7 +1007,7 @@ var gs; * @returns 符合查询条件的实体数组 */ EntityManager.prototype.queryComponents = function (components) { - var key = components.map(function (c) { return c.name; }).sort().join('|'); + var key = "" + components.map(function (c) { return c.name; }).sort().join('|'); if (!this.queryCache.has(key)) { var result = this.performQuery(components); this.queryCache.set(key, result); @@ -1155,6 +1159,20 @@ var gs; finally { if (e_14) throw e_14.error; } } }; + /** + * 清除指定组件或标签的缓存 + * @param componentClass + * @param tag + */ + EntityManager.prototype.invalidateCache = function (componentClass, tag) { + if (componentClass) { + var key = componentClass.name; + this.queryCache.delete(key); + } + if (tag) { + this.tagCache.delete(tag); + } + }; return EntityManager; }()); gs.EntityManager = EntityManager; diff --git a/source/bin/gs.min.js b/source/bin/gs.min.js index 59daa45..90cd1c4 100644 --- a/source/bin/gs.min.js +++ b/source/bin/gs.min.js @@ -1 +1 @@ -window.gs={},window.__extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function r(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();var __values=this&&this.__values||function(t){var e="function"==typeof Symbol&&t[Symbol.iterator],n=0;return e?e.call(t):{next:function(){return t&&n>=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}}},__read=this&&this.__read||function(t,e){var n="function"==typeof Symbol&&t[Symbol.iterator];if(!n)return t;var r,o,i=n.call(t),s=[];try{for(;(void 0===e||e-- >0)&&!(r=i.next()).done;)s.push(r.value)}catch(t){o={error:t}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return s},__spread=this&&this.__spread||function(){for(var t=[],e=0;e0){var t=this.pool.pop();return this.resetFn(t),t}return this.createFn()},t.prototype.release=function(t){this.pool.push(t)},t}();t.ObjectPool=e}(gs||(gs={})),function(t){var e=function(e){function n(){return e.call(this,function(){return new t.Event("",null)},function(t){t.type="",t.data=null})||this}return __extends(n,e),n}(t.ObjectPool);t.EventPool=e}(gs||(gs={})),function(t){var e=function(){function e(){this.listeners=new Map,this.eventPool=new t.EventPool}return e.prototype.on=function(t,e){this.listeners.has(t)||this.listeners.set(t,[]);var n=this.listeners.get(t);n&&n.push(e)},e.prototype.once=function(t,e){var n=this,r=function(o){n.off(t,r),e(o)};this.on(t,r)},e.prototype.off=function(t,e){var n=this.listeners.get(t);if(n){var r=n.indexOf(e);r>-1&&n.splice(r,1)}},e.prototype.emit=function(t,e){var n,r,o=this.eventPool.acquire();o.type=t,o.data=e;var i=this.listeners[t];if(i)try{for(var s=__values(i),a=s.next();!a.done;a=s.next()){(0,a.value)(o)}}catch(t){n={error:t}}finally{try{a&&!a.done&&(r=s.return)&&r.call(s)}finally{if(n)throw n.error}}this.eventPool.release(o)},e}();t.EventEmitter=e}(gs||(gs={})),function(t){t.GlobalEventEmitter=new t.EventEmitter}(gs||(gs={})),function(t){var e=function(){function t(){this._entityId=null,this._version=0}return t.prototype.setEntityId=function(t,e){this._entityId=t,this._entityManager=e},t.prototype.getEntityId=function(){return this._entityId},Object.defineProperty(t.prototype,"entityId",{get:function(){if(null===this._entityId)throw new Error("Entity ID 还未被设置");return this._entityId},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"entity",{get:function(){if(null===this._entityId)throw new Error("Entity ID 还未被设置");return this._entityManager.getEntity(this._entityId)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"version",{get:function(){return this._version},enumerable:!0,configurable:!0}),t.prototype.markUpdated=function(){this._version++},t.prototype.reinitialize=function(t,e){},t.prototype.onInitialize=function(){for(var t=[],e=0;et&&(o.components[u.name]=p.serialize(),r=!0)}}catch(t){e={error:t}}finally{try{s&&!s.done&&(n=i.return)&&n.call(i)}finally{if(e)throw e.error}}return r?o:null},e.prototype.deserialize=function(t){var e,n;for(var r in t.components)try{for(var o=__values(this.componentManagers),i=o.next();!i.done;i=o.next()){var s=__read(i.value,2),a=s[0],u=s[1];if(a.name===r){var p=u.get(this.id);p&&p.deserialize(t.components[r]);break}}}catch(t){e={error:t}}finally{try{i&&!i.done&&(n=o.return)&&n.call(o)}finally{if(e)throw e.error}}},e.prototype.onCreate=function(){},e.prototype.onDestroy=function(){},e.prototype.on=function(t,e){this.eventEmitter.on(t,e)},e.prototype.once=function(t,e){this.eventEmitter.once(t,e)},e.prototype.off=function(t,e){this.eventEmitter.off(t,e)},e.prototype.emit=function(t,e){this.eventEmitter.emit(t,e)},e}();t.Entity=e}(gs||(gs={})),function(t){var e=function(){function e(e,n,r,o){this._paused=!1,this._enabled=!0,this.entityManager=e,this.priority=n,this.workerScript=o,this.matcher=r||t.Matcher.empty()}return Object.defineProperty(e.prototype,"paused",{get:function(){return this._paused},set:function(t){this._paused=t},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this._enabled=t},enumerable:!0,configurable:!0}),e.prototype.isPaused=function(){return this.paused},e.prototype.isEnabled=function(){return this.enabled},e.prototype.entityFilter=function(t){return!0},e.prototype.filterEntities=function(t){var e=this;return t.reduce(function(t,n){return e.matcher.isInterestedEntity(n)&&e.entityFilter(n)&&t.push(n),t},[])},e.prototype.handleComponentChange=function(t,e){this.matcher.isInterestedEntity(t)&&(e?this.onComponentAdded(t):this.onComponentRemoved(t))},e.prototype.onComponentAdded=function(t){},e.prototype.onComponentRemoved=function(t){},e.prototype.onRegister=function(){},e.prototype.onUnregister=function(){},e}();t.System=e}(gs||(gs={})),function(t){var e=function(){return function(t,e){this.type=t,this.data=e}}();t.Event=e}(gs||(gs={})),function(t){var e=function(){function t(t){this.inputManager=t}return t.prototype.sendInputToManager=function(t){this.inputManager.sendInput(t)},t}();t.InputAdapter=e}(gs||(gs={})),function(t){var e=function(){function t(){this.buffer=[]}return t.prototype.addEvent=function(t){this.buffer.push(t)},t.prototype.hasEvents=function(){return this.buffer.length>0},t.prototype.getEvents=function(){return this.buffer},t.prototype.consumeEvent=function(){if(0===this.buffer.length)return null;var t=this.buffer[0];return this.buffer.shift(),t},t.prototype.clear=function(){this.buffer=[]},t}();t.InputBuffer=e}(gs||(gs={})),function(t){var e=function(){function e(e){this.inputHistory=[],this.historySizeThreshold=1e3,this.eventListeners=[],this.entityManager=e,this.inputBuffer=new t.InputBuffer}return e.prototype.setHistorySizeThreshold=function(t){this.historySizeThreshold=t},e.prototype.addEventListener=function(t){this.eventListeners.push(t)},e.prototype.setAdapter=function(t){this.adapter=t},e.prototype.sendInput=function(t){this.handleInput(t)},e.prototype.handleInput=function(t){this.inputBuffer.addEvent(t),this.inputHistory.push({frameNumber:this.getCurrentFrameNumber(),input:t}),this.eventListeners.forEach(function(e){return e(t)}),this.inputHistory.length>this.historySizeThreshold&&this.inputHistory.splice(0,this.inputHistory.length-this.historySizeThreshold)},e.prototype.getCurrentFrameNumber=function(){return this.entityManager.getCurrentFrameNumber()},e.prototype.getInputBuffer=function(){return this.inputBuffer},e.prototype.getInputHistory=function(){return this.inputHistory},e}();t.InputManager=e}(gs||(gs={})),function(t){var e=function(){function e(e){this.componentPool=[],this.componentType=e,this.components=new t.SparseSet,this.preallocate(10)}return e.prototype.create=function(t,e){var n;return this.componentPool.length>0?(n=this.componentPool.pop()).reinitialize(t,e):n=new this.componentType,n.setEntityId(t,e),this.components.add(t,n),n},e.prototype.get=function(t){return this.components.get(t)},e.prototype.has=function(t){return this.components.has(t)},e.prototype.remove=function(t){var e=this.components.get(t);e&&(e.reset(),this.componentPool.push(e)),this.components.remove(t)},e.prototype.preallocate=function(t){for(var e=0;e-1&&a.splice(u,1)}}}catch(t){e={error:t}}finally{try{i&&!i.done&&(n=o.return)&&n.call(o)}finally{if(e)throw e.error}}}},e.prototype.getEntity=function(t){return this.entities.has(t)?this.entities.get(t):null},e.prototype.getEntitiesWithComponent=function(t){return this.queryComponents([t])},e.prototype.getEntitiesWithComponents=function(t){return this.queryComponents(t)},e.prototype.getEntities=function(){return Array.from(this.entities.values())},e.prototype.getEntitiesWithTag=function(t){var e,n;if(!this.tagCache.has(t)){var r=[];try{for(var o=__values(this.getEntities()),i=o.next();!i.done;i=o.next()){var s=i.value;s.hasTag(t)&&r.push(s)}}catch(t){e={error:t}}finally{try{i&&!i.done&&(n=o.return)&&n.call(o)}finally{if(e)throw e.error}}this.tagCache.set(t,r)}return this.tagCache.get(t)},e.prototype.queryComponents=function(t){var e=t.map(function(t){return t.name}).sort().join("|");if(!this.queryCache.has(e)){var n=this.performQuery(t);this.queryCache.set(e,n)}return this.queryCache.get(e)},e.prototype.performQuery=function(t){var e,n,r=[],o=function(e){t.every(function(t){return e.hasComponent(t)})&&r.push(e)};try{for(var i=__values(this.getEntities()),s=i.next();!s.done;s=i.next()){o(s.value)}}catch(t){e={error:t}}finally{try{s&&!s.done&&(n=i.return)&&n.call(i)}finally{if(e)throw e.error}}return r},e.prototype.createStateSnapshot=function(){var t,e,n={entities:[]};try{for(var r=__values(this.getEntities()),o=r.next();!o.done;o=r.next()){var i=o.value;n.entities.push(i.serialize())}}catch(e){t={error:e}}finally{try{o&&!o.done&&(e=r.return)&&e.call(r)}finally{if(t)throw t.error}}return n},e.prototype.createIncrementalStateSnapshot=function(t){var e,n,r={entities:[]};try{for(var o=__values(this.getEntities()),i=o.next();!i.done;i=o.next()){var s=i.value.serializeIncremental(t);s&&r.entities.push(s)}}catch(t){e={error:t}}finally{try{i&&!i.done&&(n=o.return)&&n.call(o)}finally{if(e)throw e.error}}return r},e.prototype.updateStateFromSnapshot=function(e){var n,r,o=new Map;try{for(var i=__values(e.entities),s=i.next();!s.done;s=i.next()){var a=s.value,u=a.id,p=this.getEntity(u);p||(p=new t.Entity(u,this,this.componentManagers)).onCreate(),p.deserialize(a),o.set(u,p)}}catch(t){n={error:t}}finally{try{s&&!s.done&&(r=i.return)&&r.call(i)}finally{if(n)throw n.error}}this.entities=o},e.prototype.applyInterpolation=function(e){var n,r,o,i;try{for(var s=__values(this.getEntities()),a=s.next();!a.done;a=s.next()){var u=a.value;try{for(var p=__values(this.componentManagers),h=p.next();!h.done;h=p.next()){var c=__read(h.value,2),f=c[0],l=(c[1],u.getComponent(f));l instanceof t.Component&&"savePreviousState"in l&&"applyInterpolation"in l&&l.applyInterpolation(e)}}catch(t){o={error:t}}finally{try{h&&!h.done&&(i=p.return)&&i.call(p)}finally{if(o)throw o.error}}}}catch(t){n={error:t}}finally{try{a&&!a.done&&(r=s.return)&&r.call(s)}finally{if(n)throw n.error}}},e}();t.EntityManager=e}(gs||(gs={})),function(t){var e=function(){function t(t){this.systemWorkers=new Map,this.entityCache=new Map,this.systems=[],this.entityManager=t,t.setSystemManager(this)}return t.prototype.registerSystem=function(t){var e=this;if(t.onRegister(),this.systems.push(t),this.systems.sort(function(t,e){return t.priority-e.priority}),t.workerScript)if("undefined"==typeof Worker)console.warn("Web Workers 在当前环境中不受支持。系统将在主线程中运行");else{var n=new Worker(t.workerScript);n.onmessage=function(t){var n,r,o=t.data.entities;try{for(var i=__values(o),s=i.next();!s.done;s=i.next()){var a=s.value,u=e.entityManager.getEntity(a.id);u&&u.deserialize(a)}}catch(t){n={error:t}}finally{try{s&&!s.done&&(r=i.return)&&r.call(i)}finally{if(n)throw n.error}}},this.systemWorkers.set(t,n)}},t.prototype.unregisterSystem=function(t){t.onUnregister();var e=this.systems.indexOf(t);e>-1&&this.systems.splice(e,1),this.systemWorkers.delete(t),this.entityCache.delete(t)},t.prototype.notifyComponentAdded=function(t){var e,n;try{for(var r=__values(this.systems),o=r.next();!o.done;o=r.next()){var i=o.value;i.handleComponentChange(t,!0),this.entityCache.delete(i)}}catch(t){e={error:t}}finally{try{o&&!o.done&&(n=r.return)&&n.call(r)}finally{if(e)throw e.error}}},t.prototype.notifyComponentRemoved=function(t){var e,n;try{for(var r=__values(this.systems),o=r.next();!o.done;o=r.next()){var i=o.value;i.handleComponentChange(t,!1),this.entityCache.delete(i)}}catch(t){e={error:t}}finally{try{o&&!o.done&&(n=r.return)&&n.call(r)}finally{if(e)throw e.error}}},t.prototype.invalidateEntityCacheForSystem=function(t){this.entityCache.delete(t)},t.prototype.update=function(){var t,e,n=this.entityManager.getEntities();try{for(var r=__values(this.systems),o=r.next();!o.done;o=r.next()){var i=o.value;if(i.isEnabled()&&!i.isPaused()){var s=this.entityCache.get(i);s||(s=i.filterEntities(n),this.entityCache.set(i,s));var a=this.systemWorkers.get(i);if(a){var u={entities:s.map(function(t){return t.serialize()})};a.postMessage(u)}else i.update(s)}}}catch(e){t={error:e}}finally{try{o&&!o.done&&(e=r.return)&&e.call(r)}finally{if(t)throw t.error}}},t}();t.SystemManager=e}(gs||(gs={})),function(t){var e=function(){function t(){this.deltaTime=0,this.timeScale=1,this.totalTime=0}return t.getInstance=function(){return t.instance||(t.instance=new t),t.instance},t.prototype.update=function(t){this.deltaTime=t*this.timeScale,this.totalTime+=this.deltaTime},t}();t.TimeManager=e}(gs||(gs={})),function(t){var e=function(){function t(){this.networkAdapter=null}return t.prototype.setNetworkAdapter=function(t){this.networkAdapter=t},t.prototype.getNetworkAdpater=function(){return this.networkAdapter},t}();t.NetworkManager=e}(gs||(gs={})),function(t){var e=function(){function e(){this.snapshotQueue=[]}return e.prototype.sendState=function(t){},e.prototype.receiveState=function(t){this.snapshotQueue.push(t)},e.prototype.handleStateUpdate=function(e){if(!(this.snapshotQueue.length<2)){var n=this.snapshotQueue[0],r=this.snapshotQueue[1],o=t.TimeManager.getInstance().deltaTime,i=(o-n.timestamp)/(r.timestamp-n.timestamp);this.interpolateAndUpdateGameState(n,r,i),o>=r.timestamp&&this.snapshotQueue.shift()}},e.prototype.interpolateAndUpdateGameState=function(t,e,n){this.onInterpolation&&this.onInterpolation(t,e,n)},e}();t.SnapshotInterpolationStrategy=e}(gs||(gs={})),function(t){var e=function(){function t(){this.handleStateUpdate=function(){}}return t.prototype.sendState=function(t){var e=t;this.onCompressState&&(e=this.onCompressState(t)),this.onSendState&&this.onSendState(e)},t.prototype.receiveState=function(t){var e=t;this.onDecompressState&&(e=this.onDecompressState(t)),this.onReceiveState&&this.onReceiveState(e),this.handleStateUpdate(e)},t}();t.StateCompressionStrategy=e}(gs||(gs={})),function(t){var e=function(){function t(t){this.strategy=t}return t.prototype.sendState=function(t){this.strategy.sendState(t)},t.prototype.receiveState=function(t){this.strategy.receiveState(t)},t.prototype.handleStateUpdate=function(t){this.strategy.handleStateUpdate(t)},t.prototype.setStrategy=function(t){this.strategy=t},t}();t.SyncStrategyManager=e}(gs||(gs={})),function(t){var e=function(){function t(){this.currentState=null,this.states=new Map}return t.prototype.addState=function(t,e){this.states.set(t,e)},t.prototype.changeState=function(t){if(this.states.has(t)){var e=this.states.get(t);this.currentState&&this.currentState.exit&&this.currentState.exit(),this.currentState=e,this.currentState.enter&&this.currentState.enter()}else console.warn('状态 "'+t+'" 不存在.')},t.prototype.update=function(){this.currentState&&this.currentState.update&&this.currentState.update()},t}();t.StateMachine=e}(gs||(gs={})),function(t){var e=function(e){function n(){var n=e.call(this)||this;return n.stateMachine=new t.StateMachine,n}return __extends(n,e),n.prototype.reset=function(){this.stateMachine=new t.StateMachine},n}(t.Component);t.StateMachineComponent=e}(gs||(gs={})),function(t){var e=function(e){function n(t){return e.call(this,t,1)||this}return __extends(n,e),n.prototype.entityFilter=function(e){return e.hasComponent(t.StateMachineComponent)},n.prototype.update=function(e){var n,r;try{for(var o=__values(e),i=o.next();!i.done;i=o.next()){i.value.getComponent(t.StateMachineComponent).stateMachine.update()}}catch(t){n={error:t}}finally{try{i&&!i.done&&(r=o.return)&&r.call(o)}finally{if(n)throw n.error}}},n}(t.System);t.StateMachineSystem=e}(gs||(gs={})),function(t){var e=function(){function t(t){void 0===t&&(t=32),this.data=new Uint32Array(Math.ceil(t/32))}return t.prototype.set=function(t){var e=Math.floor(t/32),n=t%32;this.data[e]|=1<=this.sparse.length&&(this.sparse.length=t+1),this.sparse[t]=this.count,this.dense[this.count]=t,this.items[this.count]=e,this.count++},t.prototype.remove=function(t){var e=this.sparse[t],n=this.count-1,r=this.dense[n],o=this.items[n];this.dense[e]=r,this.items[e]=o,this.sparse[r]=e,this.count--},t.prototype.has=function(t){return this.sparse[t]=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}}},__read=this&&this.__read||function(t,e){var n="function"==typeof Symbol&&t[Symbol.iterator];if(!n)return t;var r,o,i=n.call(t),a=[];try{for(;(void 0===e||e-- >0)&&!(r=i.next()).done;)a.push(r.value)}catch(t){o={error:t}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a},__spread=this&&this.__spread||function(){for(var t=[],e=0;e0){var t=this.pool.pop();return this.resetFn(t),t}return this.createFn()},t.prototype.release=function(t){this.pool.push(t)},t}();t.ObjectPool=e}(gs||(gs={})),function(t){var e=function(e){function n(){return e.call(this,function(){return new t.Event("",null)},function(t){t.type="",t.data=null})||this}return __extends(n,e),n}(t.ObjectPool);t.EventPool=e}(gs||(gs={})),function(t){var e=function(){function e(){this.listeners=new Map,this.eventPool=new t.EventPool}return e.prototype.on=function(t,e){this.listeners.has(t)||this.listeners.set(t,[]);var n=this.listeners.get(t);n&&n.push(e)},e.prototype.once=function(t,e){var n=this,r=function(o){n.off(t,r),e(o)};this.on(t,r)},e.prototype.off=function(t,e){var n=this.listeners.get(t);if(n){var r=n.indexOf(e);r>-1&&n.splice(r,1)}},e.prototype.emit=function(t,e){var n,r,o=this.eventPool.acquire();o.type=t,o.data=e;var i=this.listeners[t];if(i)try{for(var a=__values(i),s=a.next();!s.done;s=a.next()){(0,s.value)(o)}}catch(t){n={error:t}}finally{try{s&&!s.done&&(r=a.return)&&r.call(a)}finally{if(n)throw n.error}}this.eventPool.release(o)},e}();t.EventEmitter=e}(gs||(gs={})),function(t){t.GlobalEventEmitter=new t.EventEmitter}(gs||(gs={})),function(t){var e=function(){function t(){this._entityId=null,this._version=0}return t.prototype.setEntityId=function(t,e){this._entityId=t,this._entityManager=e},t.prototype.getEntityId=function(){return this._entityId},Object.defineProperty(t.prototype,"entityId",{get:function(){if(null===this._entityId)throw new Error("Entity ID 还未被设置");return this._entityId},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"entity",{get:function(){if(null===this._entityId)throw new Error("Entity ID 还未被设置");return this._entityManager.getEntity(this._entityId)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"version",{get:function(){return this._version},enumerable:!0,configurable:!0}),t.prototype.markUpdated=function(){this._version++},t.prototype.reinitialize=function(t,e){},t.prototype.onInitialize=function(){for(var t=[],e=0;et&&(o.components[u.name]=p.serialize(),r=!0)}}catch(t){e={error:t}}finally{try{a&&!a.done&&(n=i.return)&&n.call(i)}finally{if(e)throw e.error}}return r?o:null},e.prototype.deserialize=function(t){var e,n;for(var r in t.components)try{for(var o=__values(this.componentManagers),i=o.next();!i.done;i=o.next()){var a=__read(i.value,2),s=a[0],u=a[1];if(s.name===r){var p=u.get(this.id);p&&p.deserialize(t.components[r]);break}}}catch(t){e={error:t}}finally{try{i&&!i.done&&(n=o.return)&&n.call(o)}finally{if(e)throw e.error}}},e.prototype.onCreate=function(){},e.prototype.onDestroy=function(){},e.prototype.on=function(t,e){this.eventEmitter.on(t,e)},e.prototype.once=function(t,e){this.eventEmitter.once(t,e)},e.prototype.off=function(t,e){this.eventEmitter.off(t,e)},e.prototype.emit=function(t,e){this.eventEmitter.emit(t,e)},e}();t.Entity=e}(gs||(gs={})),function(t){var e=function(){function e(e,n,r,o){this._paused=!1,this._enabled=!0,this.entityManager=e,this.priority=n,this.workerScript=o,this.matcher=r||t.Matcher.empty()}return Object.defineProperty(e.prototype,"paused",{get:function(){return this._paused},set:function(t){this._paused=t},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this._enabled=t},enumerable:!0,configurable:!0}),e.prototype.isPaused=function(){return this.paused},e.prototype.isEnabled=function(){return this.enabled},e.prototype.entityFilter=function(t){return!0},e.prototype.filterEntities=function(t){var e=this;return t.reduce(function(t,n){return e.matcher.isInterestedEntity(n)&&e.entityFilter(n)&&t.push(n),t},[])},e.prototype.handleComponentChange=function(t,e){this.matcher.isInterestedEntity(t)&&(e?this.onComponentAdded(t):this.onComponentRemoved(t))},e.prototype.onComponentAdded=function(t){},e.prototype.onComponentRemoved=function(t){},e.prototype.onRegister=function(){},e.prototype.onUnregister=function(){},e}();t.System=e}(gs||(gs={})),function(t){var e=function(){return function(t,e){this.type=t,this.data=e}}();t.Event=e}(gs||(gs={})),function(t){var e=function(){function t(t){this.inputManager=t}return t.prototype.sendInputToManager=function(t){this.inputManager.sendInput(t)},t}();t.InputAdapter=e}(gs||(gs={})),function(t){var e=function(){function t(){this.buffer=[]}return t.prototype.addEvent=function(t){this.buffer.push(t)},t.prototype.hasEvents=function(){return this.buffer.length>0},t.prototype.getEvents=function(){return this.buffer},t.prototype.consumeEvent=function(){if(0===this.buffer.length)return null;var t=this.buffer[0];return this.buffer.shift(),t},t.prototype.clear=function(){this.buffer=[]},t}();t.InputBuffer=e}(gs||(gs={})),function(t){var e=function(){function e(e){this.inputHistory=[],this.historySizeThreshold=1e3,this.eventListeners=[],this.entityManager=e,this.inputBuffer=new t.InputBuffer}return e.prototype.setHistorySizeThreshold=function(t){this.historySizeThreshold=t},e.prototype.addEventListener=function(t){this.eventListeners.push(t)},e.prototype.setAdapter=function(t){this.adapter=t},e.prototype.sendInput=function(t){this.handleInput(t)},e.prototype.handleInput=function(t){this.inputBuffer.addEvent(t),this.inputHistory.push({frameNumber:this.getCurrentFrameNumber(),input:t}),this.eventListeners.forEach(function(e){return e(t)}),this.inputHistory.length>this.historySizeThreshold&&this.inputHistory.splice(0,this.inputHistory.length-this.historySizeThreshold)},e.prototype.getCurrentFrameNumber=function(){return this.entityManager.getCurrentFrameNumber()},e.prototype.getInputBuffer=function(){return this.inputBuffer},e.prototype.getInputHistory=function(){return this.inputHistory},e}();t.InputManager=e}(gs||(gs={})),function(t){var e=function(){function e(e){this.componentPool=[],this.componentType=e,this.components=new t.SparseSet,this.preallocate(10)}return e.prototype.create=function(t,e){var n;return this.componentPool.length>0?(n=this.componentPool.pop()).reinitialize(t,e):n=new this.componentType,n.setEntityId(t,e),this.components.add(t,n),n},e.prototype.get=function(t){return this.components.get(t)},e.prototype.has=function(t){return this.components.has(t)},e.prototype.remove=function(t){var e=this.components.get(t);e&&(e.reset(),this.componentPool.push(e)),this.components.remove(t)},e.prototype.preallocate=function(t){for(var e=0;e-1&&s.splice(u,1)}}}catch(t){e={error:t}}finally{try{i&&!i.done&&(n=o.return)&&n.call(o)}finally{if(e)throw e.error}}}},e.prototype.getEntity=function(t){return this.entities.has(t)?this.entities.get(t):null},e.prototype.getEntitiesWithComponent=function(t){return this.queryComponents([t])},e.prototype.getEntitiesWithComponents=function(t){return this.queryComponents(t)},e.prototype.getEntities=function(){return Array.from(this.entities.values())},e.prototype.getEntitiesWithTag=function(t){var e,n;if(!this.tagCache.has(t)){var r=[];try{for(var o=__values(this.getEntities()),i=o.next();!i.done;i=o.next()){var a=i.value;a.hasTag(t)&&r.push(a)}}catch(t){e={error:t}}finally{try{i&&!i.done&&(n=o.return)&&n.call(o)}finally{if(e)throw e.error}}this.tagCache.set(t,r)}return this.tagCache.get(t)},e.prototype.queryComponents=function(t){var e=""+t.map(function(t){return t.name}).sort().join("|");if(!this.queryCache.has(e)){var n=this.performQuery(t);this.queryCache.set(e,n)}return this.queryCache.get(e)},e.prototype.performQuery=function(t){var e,n,r=[],o=function(e){t.every(function(t){return e.hasComponent(t)})&&r.push(e)};try{for(var i=__values(this.getEntities()),a=i.next();!a.done;a=i.next()){o(a.value)}}catch(t){e={error:t}}finally{try{a&&!a.done&&(n=i.return)&&n.call(i)}finally{if(e)throw e.error}}return r},e.prototype.createStateSnapshot=function(){var t,e,n={entities:[]};try{for(var r=__values(this.getEntities()),o=r.next();!o.done;o=r.next()){var i=o.value;n.entities.push(i.serialize())}}catch(e){t={error:e}}finally{try{o&&!o.done&&(e=r.return)&&e.call(r)}finally{if(t)throw t.error}}return n},e.prototype.createIncrementalStateSnapshot=function(t){var e,n,r={entities:[]};try{for(var o=__values(this.getEntities()),i=o.next();!i.done;i=o.next()){var a=i.value.serializeIncremental(t);a&&r.entities.push(a)}}catch(t){e={error:t}}finally{try{i&&!i.done&&(n=o.return)&&n.call(o)}finally{if(e)throw e.error}}return r},e.prototype.updateStateFromSnapshot=function(e){var n,r,o=new Map;try{for(var i=__values(e.entities),a=i.next();!a.done;a=i.next()){var s=a.value,u=s.id,p=this.getEntity(u);p||(p=new t.Entity(u,this,this.componentManagers)).onCreate(),p.deserialize(s),o.set(u,p)}}catch(t){n={error:t}}finally{try{a&&!a.done&&(r=i.return)&&r.call(i)}finally{if(n)throw n.error}}this.entities=o},e.prototype.applyInterpolation=function(e){var n,r,o,i;try{for(var a=__values(this.getEntities()),s=a.next();!s.done;s=a.next()){var u=s.value;try{for(var p=__values(this.componentManagers),h=p.next();!h.done;h=p.next()){var c=__read(h.value,2),f=c[0],l=(c[1],u.getComponent(f));l instanceof t.Component&&"savePreviousState"in l&&"applyInterpolation"in l&&l.applyInterpolation(e)}}catch(t){o={error:t}}finally{try{h&&!h.done&&(i=p.return)&&i.call(p)}finally{if(o)throw o.error}}}}catch(t){n={error:t}}finally{try{s&&!s.done&&(r=a.return)&&r.call(a)}finally{if(n)throw n.error}}},e.prototype.invalidateCache=function(t,e){if(t){var n=t.name;this.queryCache.delete(n)}e&&this.tagCache.delete(e)},e}();t.EntityManager=e}(gs||(gs={})),function(t){var e=function(){function t(t){this.systemWorkers=new Map,this.entityCache=new Map,this.systems=[],this.entityManager=t,t.setSystemManager(this)}return t.prototype.registerSystem=function(t){var e=this;if(t.onRegister(),this.systems.push(t),this.systems.sort(function(t,e){return t.priority-e.priority}),t.workerScript)if("undefined"==typeof Worker)console.warn("Web Workers 在当前环境中不受支持。系统将在主线程中运行");else{var n=new Worker(t.workerScript);n.onmessage=function(t){var n,r,o=t.data.entities;try{for(var i=__values(o),a=i.next();!a.done;a=i.next()){var s=a.value,u=e.entityManager.getEntity(s.id);u&&u.deserialize(s)}}catch(t){n={error:t}}finally{try{a&&!a.done&&(r=i.return)&&r.call(i)}finally{if(n)throw n.error}}},this.systemWorkers.set(t,n)}},t.prototype.unregisterSystem=function(t){t.onUnregister();var e=this.systems.indexOf(t);e>-1&&this.systems.splice(e,1),this.systemWorkers.delete(t),this.entityCache.delete(t)},t.prototype.notifyComponentAdded=function(t){var e,n;try{for(var r=__values(this.systems),o=r.next();!o.done;o=r.next()){var i=o.value;i.handleComponentChange(t,!0),this.entityCache.delete(i)}}catch(t){e={error:t}}finally{try{o&&!o.done&&(n=r.return)&&n.call(r)}finally{if(e)throw e.error}}},t.prototype.notifyComponentRemoved=function(t){var e,n;try{for(var r=__values(this.systems),o=r.next();!o.done;o=r.next()){var i=o.value;i.handleComponentChange(t,!1),this.entityCache.delete(i)}}catch(t){e={error:t}}finally{try{o&&!o.done&&(n=r.return)&&n.call(r)}finally{if(e)throw e.error}}},t.prototype.invalidateEntityCacheForSystem=function(t){this.entityCache.delete(t)},t.prototype.update=function(){var t,e,n=this.entityManager.getEntities();try{for(var r=__values(this.systems),o=r.next();!o.done;o=r.next()){var i=o.value;if(i.isEnabled()&&!i.isPaused()){var a=this.entityCache.get(i);a||(a=i.filterEntities(n),this.entityCache.set(i,a));var s=this.systemWorkers.get(i);if(s){var u={entities:a.map(function(t){return t.serialize()})};s.postMessage(u)}else i.update(a)}}}catch(e){t={error:e}}finally{try{o&&!o.done&&(e=r.return)&&e.call(r)}finally{if(t)throw t.error}}},t}();t.SystemManager=e}(gs||(gs={})),function(t){var e=function(){function t(){this.deltaTime=0,this.timeScale=1,this.totalTime=0}return t.getInstance=function(){return t.instance||(t.instance=new t),t.instance},t.prototype.update=function(t){this.deltaTime=t*this.timeScale,this.totalTime+=this.deltaTime},t}();t.TimeManager=e}(gs||(gs={})),function(t){var e=function(){function t(){this.networkAdapter=null}return t.prototype.setNetworkAdapter=function(t){this.networkAdapter=t},t.prototype.getNetworkAdpater=function(){return this.networkAdapter},t}();t.NetworkManager=e}(gs||(gs={})),function(t){var e=function(){function e(){this.snapshotQueue=[]}return e.prototype.sendState=function(t){},e.prototype.receiveState=function(t){this.snapshotQueue.push(t)},e.prototype.handleStateUpdate=function(e){if(!(this.snapshotQueue.length<2)){var n=this.snapshotQueue[0],r=this.snapshotQueue[1],o=t.TimeManager.getInstance().deltaTime,i=(o-n.timestamp)/(r.timestamp-n.timestamp);this.interpolateAndUpdateGameState(n,r,i),o>=r.timestamp&&this.snapshotQueue.shift()}},e.prototype.interpolateAndUpdateGameState=function(t,e,n){this.onInterpolation&&this.onInterpolation(t,e,n)},e}();t.SnapshotInterpolationStrategy=e}(gs||(gs={})),function(t){var e=function(){function t(){this.handleStateUpdate=function(){}}return t.prototype.sendState=function(t){var e=t;this.onCompressState&&(e=this.onCompressState(t)),this.onSendState&&this.onSendState(e)},t.prototype.receiveState=function(t){var e=t;this.onDecompressState&&(e=this.onDecompressState(t)),this.onReceiveState&&this.onReceiveState(e),this.handleStateUpdate(e)},t}();t.StateCompressionStrategy=e}(gs||(gs={})),function(t){var e=function(){function t(t){this.strategy=t}return t.prototype.sendState=function(t){this.strategy.sendState(t)},t.prototype.receiveState=function(t){this.strategy.receiveState(t)},t.prototype.handleStateUpdate=function(t){this.strategy.handleStateUpdate(t)},t.prototype.setStrategy=function(t){this.strategy=t},t}();t.SyncStrategyManager=e}(gs||(gs={})),function(t){var e=function(){function t(){this.currentState=null,this.states=new Map}return t.prototype.addState=function(t,e){this.states.set(t,e)},t.prototype.changeState=function(t){if(this.states.has(t)){var e=this.states.get(t);this.currentState&&this.currentState.exit&&this.currentState.exit(),this.currentState=e,this.currentState.enter&&this.currentState.enter()}else console.warn('状态 "'+t+'" 不存在.')},t.prototype.update=function(){this.currentState&&this.currentState.update&&this.currentState.update()},t}();t.StateMachine=e}(gs||(gs={})),function(t){var e=function(e){function n(){var n=e.call(this)||this;return n.stateMachine=new t.StateMachine,n}return __extends(n,e),n.prototype.reset=function(){this.stateMachine=new t.StateMachine},n}(t.Component);t.StateMachineComponent=e}(gs||(gs={})),function(t){var e=function(e){function n(t){return e.call(this,t,1)||this}return __extends(n,e),n.prototype.entityFilter=function(e){return e.hasComponent(t.StateMachineComponent)},n.prototype.update=function(e){var n,r;try{for(var o=__values(e),i=o.next();!i.done;i=o.next()){i.value.getComponent(t.StateMachineComponent).stateMachine.update()}}catch(t){n={error:t}}finally{try{i&&!i.done&&(r=o.return)&&r.call(o)}finally{if(n)throw n.error}}},n}(t.System);t.StateMachineSystem=e}(gs||(gs={})),function(t){var e=function(){function t(t){void 0===t&&(t=32),this.data=new Uint32Array(Math.ceil(t/32))}return t.prototype.set=function(t){var e=Math.floor(t/32),n=t%32;this.data[e]|=1<=this.sparse.length&&(this.sparse.length=t+1),this.sparse[t]=this.count,this.dense[this.count]=t,this.items[this.count]=e,this.count++},t.prototype.remove=function(t){var e=this.sparse[t],n=this.count-1,r=this.dense[n],o=this.items[n];this.dense[e]=r,this.items[e]=o,this.sparse[r]=e,this.count--},t.prototype.has=function(t){return this.sparse[t] = { - new(): T; - }; + export type ComponentConstructor = new (...args: any[]) => T; /** * 组件管理器 diff --git a/source/src/Manager/EntityManager.ts b/source/src/Manager/EntityManager.ts index b162efc..be95a3c 100644 --- a/source/src/Manager/EntityManager.ts +++ b/source/src/Manager/EntityManager.ts @@ -2,7 +2,7 @@ module gs { export class EntityManager { private entities: Map; private entityIdAllocator: EntityIdAllocator; - private componentManagers: Map, ComponentManager>; + private componentManagers: Map, ComponentManager>; /** 当前帧编号属性 */ private currentFrameNumber: number; private inputManager: InputManager; @@ -12,7 +12,7 @@ module gs { private tagCache: Map = new Map(); public systemManager?: SystemManager; - constructor(componentClasses: Array> = null, systemManager?: SystemManager) { + constructor(componentClasses: Array> = null, systemManager?: SystemManager) { this.entities = new Map(); this.entityIdAllocator = new EntityIdAllocator(); this.inputManager = new InputManager(this); @@ -36,7 +36,7 @@ module gs { * 添加组件管理器 * @param componentClass 要添加的组件类 */ - public addComponentManager(componentClass: new (...args: any[]) => T): void { + public addComponentManager(componentClass: ComponentConstructor): void { const componentManager = new ComponentManager(componentClass); this.componentManagers.set(componentClass, componentManager); } @@ -116,7 +116,7 @@ module gs { * @param componentClass 要检查的组件类 * @returns 具有指定组件的实体数组 */ - public getEntitiesWithComponent(componentClass: new (...args: any[]) => T): Entity[] { + public getEntitiesWithComponent(componentClass: ComponentConstructor): Entity[] { return this.queryComponents([componentClass]); } @@ -125,7 +125,7 @@ module gs { * @param componentClasses * @returns */ - public getEntitiesWithComponents(componentClasses: Array T>): Entity[] { + public getEntitiesWithComponents(componentClasses: ComponentConstructor[]): Entity[] { return this.queryComponents(componentClasses); } @@ -164,8 +164,8 @@ module gs { * @param components 要查询的组件数组 * @returns 符合查询条件的实体数组 */ - public queryComponents(components: (new (entityId: number) => Component)[]): Entity[] { - const key = components.map(c => c.name).sort().join('|'); + public queryComponents(components: ComponentConstructor[]): Entity[] { + const key = `${components.map(c => c.name).sort().join('|')}`; if (!this.queryCache.has(key)) { const result = this.performQuery(components); this.queryCache.set(key, result); @@ -173,7 +173,7 @@ module gs { return this.queryCache.get(key); } - private performQuery(components: (new (entityId: number) => Component)[]): Entity[] { + private performQuery(components: ComponentConstructor[]): Entity[] { const result: Entity[] = []; // 遍历所有实体 @@ -266,5 +266,21 @@ module gs { } } } + + /** + * 清除指定组件或标签的缓存 + * @param componentClass + * @param tag + */ + public invalidateCache(componentClass?: ComponentConstructor, tag?: string): void { + if (componentClass) { + const key = componentClass.name; + this.queryCache.delete(key); + } + + if (tag) { + this.tagCache.delete(tag); + } + } } } \ No newline at end of file