From 262e16bb88ceac7dcf0d78a7df872feab9de4c25 Mon Sep 17 00:00:00 2001 From: YHH <359807859@qq.com> Date: Mon, 8 Jun 2020 23:04:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Ecomponentlist=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=BB=84=E4=BB=B6=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/libs/framework/framework.d.ts | 38 +++++- demo/libs/framework/framework.js | 188 ++++++++++++++++++++++++-- demo/libs/framework/framework.min.js | 2 +- source/bin/framework.d.ts | 38 +++++- source/bin/framework.js | 188 ++++++++++++++++++++++++-- source/bin/framework.min.js | 2 +- source/src/ECS/Component.ts | 20 +++ source/src/ECS/Components/Camera.ts | 2 +- source/src/ECS/Entity.ts | 39 +++++- source/src/ECS/Transform.ts | 36 ++++- source/src/ECS/Utils/ComponentList.ts | 134 ++++++++++++++++++ source/src/ECS/Utils/EntityList.ts | 1 + 12 files changed, 659 insertions(+), 29 deletions(-) create mode 100644 source/src/ECS/Utils/ComponentList.ts diff --git a/demo/libs/framework/framework.d.ts b/demo/libs/framework/framework.d.ts index c9b3698c..53c9717f 100644 --- a/demo/libs/framework/framework.d.ts +++ b/demo/libs/framework/framework.d.ts @@ -24,6 +24,11 @@ declare abstract class Component { enabled: boolean; setEnabled(isEnabled: boolean): this; abstract initialize(): any; + onAddedToEntity(): void; + onRemovedFromEntity(): void; + onEnabled(): void; + onDisabled(): void; + onEntityTransformChanged(comp: ComponentTransform): void; update(): void; bind(displayRender: egret.DisplayObject): this; registerComponent(): void; @@ -33,19 +38,25 @@ declare class Entity { name: string; scene: Scene; readonly transform: Transform; - readonly components: Component[]; + readonly components: ComponentList; private _updateOrder; private _enabled; + private _isDestoryed; componentBits: BitSet; + readonly isDestoryed: boolean; enabled: boolean; setEnabled(isEnabled: boolean): this; constructor(name: string); updateOrder: number; setUpdateOrder(updateOrder: number): this; attachToScene(newScene: Scene): void; + detachFromScene(): void; addComponent(component: T): T; getComponent(type: any): T; update(): void; + onAddedToScene(): void; + onRemovedFromScene(): void; + onTransformChanged(comp: ComponentTransform): void; destory(): void; } declare class Scene extends egret.DisplayObjectContainer { @@ -85,6 +96,11 @@ declare enum DirtyType { scaleDirty = 2, rotationDirty = 3 } +declare enum ComponentTransform { + position = 0, + scale = 1, + rotation = 2 +} declare class Transform { readonly entity: Entity; private _children; @@ -119,6 +135,7 @@ declare class Transform { localPosition: Vector2; setLocalPosition(localPosition: Vector2): this; setPosition(position: Vector2): this; + setDirty(dirtyFlagType: DirtyType): void; updateTransform(): void; } declare class Camera extends Component { @@ -176,6 +193,25 @@ declare class BitSet { nextSetBit(from: number): number; set(pos: number, value?: boolean): void; } +declare class ComponentList { + private _entity; + private _components; + private _componentsToAdd; + private _componentsToRemove; + private _tempBufferList; + constructor(entity: Entity); + readonly buffer: Component[]; + add(component: Component): void; + remove(component: Component): void; + removeAllComponents(): void; + deregisterAllComponents(): void; + registerAllComponents(): void; + updateLists(): void; + private handleRemove; + getComponent(type: any, onlyReturnInitializedComponents: boolean): T; + update(): void; + onEntityTransformChanged(comp: any): void; +} declare class ComponentTypeManager { private static _componentTypesMask; static add(type: any): void; diff --git a/demo/libs/framework/framework.js b/demo/libs/framework/framework.js index 360c5edd..217ab113 100644 --- a/demo/libs/framework/framework.js +++ b/demo/libs/framework/framework.js @@ -258,6 +258,16 @@ var Component = (function () { } return this; }; + Component.prototype.onAddedToEntity = function () { + }; + Component.prototype.onRemovedFromEntity = function () { + }; + Component.prototype.onEnabled = function () { + }; + Component.prototype.onDisabled = function () { + }; + Component.prototype.onEntityTransformChanged = function (comp) { + }; Component.prototype.update = function () { }; Component.prototype.bind = function (displayRender) { @@ -280,9 +290,16 @@ var Entity = (function () { this._enabled = true; this.name = name; this.transform = new Transform(this); - this.components = []; + this.components = new ComponentList(this); this.componentBits = new BitSet(); } + Object.defineProperty(Entity.prototype, "isDestoryed", { + get: function () { + return this._isDestoryed; + }, + enumerable: true, + configurable: true + }); Object.defineProperty(Entity.prototype, "enabled", { get: function () { return this._enabled; @@ -320,25 +337,41 @@ var Entity = (function () { Entity.prototype.attachToScene = function (newScene) { this.scene = newScene; newScene.entities.add(this); - this.components.forEach(function (component) { return component.registerComponent(); }); + this.components.registerAllComponents(); for (var i = 0; i < this.transform.childCount; i++) { this.transform.getChild(i).entity.attachToScene(newScene); } }; + Entity.prototype.detachFromScene = function () { + this.scene.entities.remove(this); + this.components.deregisterAllComponents(); + for (var i = 0; i < this.transform.childCount; i++) + this.transform.getChild(i).entity.detachFromScene(); + }; Entity.prototype.addComponent = function (component) { component.entity = this; - this.components.push(component); + this.components.add(component); component.initialize(); return component; }; Entity.prototype.getComponent = function (type) { - return this.components.firstOrDefault(function (component) { return component instanceof type; }); + return this.components.getComponent(type, false); }; Entity.prototype.update = function () { - this.components.forEach(function (component) { return component.update(); }); + this.components.update(); this.transform.updateTransform(); }; + Entity.prototype.onAddedToScene = function () { + }; + Entity.prototype.onRemovedFromScene = function () { + if (this._isDestoryed) + this.components.remove; + }; + Entity.prototype.onTransformChanged = function (comp) { + this.components.onEntityTransformChanged(comp); + }; Entity.prototype.destory = function () { + this._isDestoryed = true; this.scene.entities.remove(this); this.transform.parent = null; for (var i = this.transform.childCount - 1; i >= 0; i--) { @@ -461,6 +494,12 @@ var DirtyType; DirtyType[DirtyType["scaleDirty"] = 2] = "scaleDirty"; DirtyType[DirtyType["rotationDirty"] = 3] = "rotationDirty"; })(DirtyType || (DirtyType = {})); +var ComponentTransform; +(function (ComponentTransform) { + ComponentTransform[ComponentTransform["position"] = 0] = "position"; + ComponentTransform[ComponentTransform["scale"] = 1] = "scale"; + ComponentTransform[ComponentTransform["rotation"] = 2] = "rotation"; +})(ComponentTransform || (ComponentTransform = {})); var Transform = (function () { function Transform(entity) { this._localRotation = 0; @@ -536,6 +575,7 @@ var Transform = (function () { return this; this._localPosition = localPosition; this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true; + this.setDirty(DirtyType.positionDirty); return this; }; Transform.prototype.setPosition = function (position) { @@ -548,8 +588,8 @@ var Transform = (function () { else { this.localPosition = position; } - for (var i = 0; i < this.entity.components.length; i++) { - var component = this.entity.components[i]; + for (var i = 0; i < this.entity.components.buffer.length; i++) { + var component = this.entity.components.buffer[i]; if (component.displayRender) { component.displayRender.x = this.entity.scene.camera.transformMatrix.m31 + this.position.x; component.displayRender.y = this.entity.scene.camera.transformMatrix.m32 + this.position.y; @@ -557,6 +597,27 @@ var Transform = (function () { } return this; }; + Transform.prototype.setDirty = function (dirtyFlagType) { + if ((this._hierachyDirty & dirtyFlagType) == 0) { + this._hierachyDirty |= dirtyFlagType; + switch (dirtyFlagType) { + case DirtyType.positionDirty: + this.entity.onTransformChanged(ComponentTransform.position); + break; + case DirtyType.rotationDirty: + this.entity.onTransformChanged(ComponentTransform.rotation); + break; + case DirtyType.scaleDirty: + this.entity.onTransformChanged(ComponentTransform.scale); + break; + } + if (this._children == null) + this._children = []; + for (var i = 0; i < this._children.length; i++) { + this._children[i].setDirty(dirtyFlagType); + } + } + }; Transform.prototype.updateTransform = function () { if (this._hierachyDirty != DirtyType.clean) { if (this.parent) @@ -617,7 +678,7 @@ var Camera = (function (_super) { }; Camera.prototype.update = function () { var _this = this; - SceneManager.getActiveScene().entities.buffer.forEach(function (entity) { return entity.components.forEach(function (component) { + SceneManager.getActiveScene().entities.buffer.forEach(function (entity) { return entity.components.buffer.forEach(function (component) { if (component.displayRender) { var has = _this.entity.scene.$children.indexOf(component.displayRender); if (has == -1) { @@ -826,6 +887,116 @@ var BitSet = (function () { BitSet.LONG_MASK = 0x3f; return BitSet; }()); +var ComponentList = (function () { + function ComponentList(entity) { + this._components = []; + this._componentsToAdd = []; + this._componentsToRemove = []; + this._tempBufferList = []; + this._entity = entity; + } + Object.defineProperty(ComponentList.prototype, "buffer", { + get: function () { + return this._components; + }, + enumerable: true, + configurable: true + }); + ComponentList.prototype.add = function (component) { + this._componentsToAdd.push(component); + }; + ComponentList.prototype.remove = function (component) { + if (this._componentsToAdd.contains(component)) { + this._componentsToAdd.remove(component); + return; + } + this._componentsToRemove.push(component); + }; + ComponentList.prototype.removeAllComponents = function () { + for (var i = 0; i < this._components.length; i++) { + this.handleRemove(this._components[i]); + } + this._components.length = 0; + this._componentsToAdd.length = 0; + this._componentsToRemove.length = 0; + }; + ComponentList.prototype.deregisterAllComponents = function () { + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); + this._entity.scene.entityProcessors.onComponentRemoved(this._entity); + } + }; + ComponentList.prototype.registerAllComponents = function () { + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component)); + this._entity.scene.entityProcessors.onComponentAdded(this._entity); + } + }; + ComponentList.prototype.updateLists = function () { + if (this._componentsToRemove.length > 0) { + for (var i = 0; i < this._componentsToRemove.length; i++) { + this.handleRemove(this._componentsToRemove[i]); + this._components.remove(this._componentsToRemove[i]); + } + this._componentsToRemove.length = 0; + } + if (this._componentsToAdd.length > 0) { + for (var i = 0, count = this._componentsToAdd.length; i < count; i++) { + var component = this._componentsToAdd[i]; + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component)); + this._entity.scene.entityProcessors.onComponentAdded(this._entity); + this._components.push(component); + this._tempBufferList.push(component); + } + this._componentsToAdd.length = 0; + for (var i = 0; i < this._tempBufferList.length; i++) { + var component = this._tempBufferList[i]; + component.onAddedToEntity(); + if (component.enabled) { + component.onEnabled(); + } + } + this._tempBufferList.length = 0; + } + }; + ComponentList.prototype.handleRemove = function (component) { + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); + this._entity.scene.entityProcessors.onComponentRemoved(this._entity); + component.onRemovedFromEntity(); + component.entity = null; + }; + ComponentList.prototype.getComponent = function (type, onlyReturnInitializedComponents) { + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; + if (component instanceof type) + return component; + } + if (!onlyReturnInitializedComponents) { + for (var i = 0; i < this._componentsToAdd.length; i++) { + var component = this._componentsToAdd[i]; + if (component instanceof type) + return component; + } + } + return null; + }; + ComponentList.prototype.update = function () { + this.updateLists(); + }; + ComponentList.prototype.onEntityTransformChanged = function (comp) { + for (var i = 0; i < this._components.length; i++) { + if (this._components[i].enabled) + this._components[i].onEntityTransformChanged(comp); + } + for (var i = 0; i < this._componentsToAdd.length; i++) { + if (this._componentsToAdd[i].enabled) + this._componentsToAdd[i].onEntityTransformChanged(comp); + } + }; + return ComponentList; +}()); var ComponentTypeManager = (function () { function ComponentTypeManager() { } @@ -921,6 +1092,7 @@ var EntityList = (function () { entity.scene = _this.scene; _this.scene.entityProcessors.onEntityAdded(entity); }); + this._tempEntityList.forEach(function (entity) { return entity.onAddedToScene(); }); this._tempEntityList.length = 0; } }; diff --git a/demo/libs/framework/framework.min.js b/demo/libs/framework/framework.min.js index 03168566..08e86c3f 100644 --- a/demo/libs/framework/framework.min.js +++ b/demo/libs/framework/framework.min.js @@ -1 +1 @@ -window.framework={},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 i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),Array.prototype.findIndex=function(t){return function(t,e){for(var n=0,i=t.length;n-1}(this,t)},Array.prototype.firstOrDefault=function(t){return function(t,e){var n=t.findIndex(e);return-1==n?null:t[n]}(this,t)},Array.prototype.find=function(t){return function(t,e){return t.firstOrDefault(e)}(this,t)},Array.prototype.where=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,r){return e.call(arguments[2],i,r,t)&&n.push(i),n},[]);for(var n=[],i=0,r=t.length;i=0&&t.splice(n,1)}while(n>=0)}(this,t)},Array.prototype.remove=function(t){return function(t,e){var n=t.findIndex(function(t){return t===e});return n>=0&&(t.splice(n,1),!0)}(this,t)},Array.prototype.removeAt=function(t){return function(t,e){t.splice(e,1)}(this,t)},Array.prototype.removeRange=function(t,e){return function(t,e,n){t.splice(e,n)}(this,t,e)},Array.prototype.select=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,r){return n.push(e.call(arguments[2],i,r,t)),n},[]);for(var n=[],i=0,r=t.length;io?1:-1}),t}(this,t,e)},Array.prototype.orderByDescending=function(t,e){return function(t,e,n){return t.sort(function(t,i){var r=e(t),o=e(i);return n?-n(r,o):r=0;t--){this.transform.getChild(t).entity.destory()}},t}(),Scene=function(t){function e(e){var n=t.call(this)||this;return e.stage.addChild(n),n._projectionMatrix=new Matrix2D(0,0,0,0,0,0),n.entityProcessors=new EntityProcessorList,n.entities=new EntityList(n),n.addEventListener(egret.Event.ACTIVATE,n.onActive,n),n.addEventListener(egret.Event.DEACTIVATE,n.onDeactive,n),n.addEventListener(egret.Event.ENTER_FRAME,n.update,n),n}return __extends(e,t),e.prototype.createEntity=function(t){var e=new Entity(t);return e.transform.position=new Vector2(0,0),this.addEntity(e)},e.prototype.addEntity=function(t){this.entities.add(t),t.scene=this;for(var e=0;e>6;0!=(e&t.LONG_MASK)&&n++,this._bits=new Array(n)}return t.prototype.and=function(t){for(var e,n=Math.min(this._bits.length,t._bits.length),i=0;i=0;)this._bits[e]&=~t._bits[e]},t.prototype.cardinality=function(){for(var t=0,e=this._bits.length-1;e>=0;e--){var n=this._bits[e];if(0!=n)if(-1!=n){var i=((n=((n=(n>>1&0x5555555555555400)+(0x5555555555555400&n))>>2&0x3333333333333400)+(0x3333333333333400&n))>>32)+n;t+=((i=((i=(i>>4&252645135)+(252645135&i))>>8&16711935)+(16711935&i))>>16&65535)+(65535&i)}else t+=64}return t},t.prototype.clear=function(t){if(null!=t){var e=t>>6;this.ensure(e),this._bits[e]&=~(1<=this._bits.length){var e=new Number[t+1];e=this._bits.copyWithin(0,0,this._bits.length),this._bits=e}},t.prototype.get=function(t){var e=t>>6;return!(e>=this._bits.length)&&0!=(this._bits[e]&1<=0;)if(0!=(this._bits[e]&t._bits[e]))return!0;return!1},t.prototype.isEmpty=function(){for(var t=this._bits.length-1;t>=0;t--)if(this._bits[t])return!1;return!0},t.prototype.nextSetBit=function(t){for(var e=t>>6,n=1<>6;this.ensure(n),this._bits[n]|=1<0){var e=this._entitiesToRemove;this._entitiesToRemove=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t._entities.remove(e),e.scene=null,t.scene.entityProcessors.onEntityRemoved(e)}),this._tempEntityList.length=0}if(this._entitiesToAdded.length>0){e=this._entitiesToAdded;this._entitiesToAdded=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t._entities.push(e),e.scene=t.scene,t.scene.entityProcessors.onEntityAdded(e)}),this._tempEntityList.length=0}},t}(),EntityProcessorList=function(){function t(){this._processors=[]}return t.prototype.add=function(t){this._processors.push(t)},t.prototype.remove=function(t){this._processors.remove(t)},t.prototype.onComponentAdded=function(t){this.notifyEntityChanged(t)},t.prototype.onComponentRemoved=function(t){this.notifyEntityChanged(t)},t.prototype.onEntityAdded=function(t){this.notifyEntityChanged(t)},t.prototype.onEntityRemoved=function(t){this.removeFromProcessors(t)},t.prototype.notifyEntityChanged=function(t){for(var e=0;e=0;e=this.allSet.nextSetBit(e+1))if(!t.componentBits.get(e))return!1;return!(!this.exclusionSet.isEmpty()&&this.exclusionSet.intersects(t.componentBits))&&!(!this.oneSet.isEmpty()&&!this.oneSet.intersects(t.componentBits))},t}(),Time=function(){function t(){}return t.update=function(t){var e=(t-this._lastTime)/1e3;this.deltaTime=e*this.timeScale,this.unscaledDeltaTime=e,this._lastTime=t},t.timeScale=1,t._lastTime=0,t}(),MathHelper=function(){function t(){}return t.toDegrees=function(t){return 57.29577951308232*t},t.toRadians=function(t){return.017453292519943295*t},t}(),Matrix2D=function(){function t(t,e,n,i,r,o){this.m11=0,this.m12=0,this.m21=0,this.m22=0,this.m31=0,this.m32=0,this.m11=t,this.m12=e,this.m21=n,this.m22=i,this.m31=r,this.m32=o}return Object.defineProperty(t,"identity",{get:function(){return t._identity},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"translation",{get:function(){return new Vector2(this.m31,this.m32)},set:function(t){this.m31=t.x,this.m32=t.y},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotation",{get:function(){return Math.atan2(this.m21,this.m11)},set:function(t){var e=Math.cos(t),n=Math.sin(t);this.m11=e,this.m12=n,this.m21=-n,this.m22=e},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotationDegrees",{get:function(){return MathHelper.toDegrees(this.rotation)},set:function(t){this.rotation=MathHelper.toRadians(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scale",{get:function(){return new Vector2(this.m11,this.m22)},set:function(t){this.m11=t.x,this.m12=t.y},enumerable:!0,configurable:!0}),t.add=function(t,e){return t.m11+=e.m11,t.m12+=e.m12,t.m21+=e.m21,t.m22+=e.m22,t.m31+=e.m31,t.m32+=e.m32,t},t.divide=function(t,e){return t.m11/=e.m11,t.m12/=e.m12,t.m21/=e.m21,t.m22/=e.m22,t.m31/=e.m31,t.m32/=e.m32,t},t.multiply=function(t,e){var n=t.m11*e.m11+t.m12*e.m21,i=t.m11*e.m12+t.m12*e.m22,r=t.m21*e.m11+t.m22*e.m21,o=t.m21*e.m12+t.m22*e.m22,s=t.m31*e.m11+t.m32*e.m21+e.m31,a=t.m31*e.m12+t.m32*e.m22+e.m32;return t.m11=n,t.m12=i,t.m21=r,t.m22=o,t.m31=s,t.m32=a,t},t.multiplyTranslation=function(e,n,i){var r=t.createTranslation(n,i);return t.multiply(e,r)},t.prototype.determinant=function(){return this.m11*this.m22-this.m12*this.m21},t.invert=function(t,e){var n=1/t.determinant();return e.m11=t.m22*n,e.m12=-t.m12*n,e.m21=-t.m21*n,e.m22=t.m11*n,e.m31=(t.m32*t.m21-t.m31*t.m22)*n,e.m32=-(t.m32*t.m11-t.m31*t.m12)*n,e},t.createTranslation=function(e,n,i){return void 0===i&&(i=t.identity),i.m11=1,i.m12=0,i.m21=0,i.m22=1,i.m31=e,i.m32=n,i},t.createRotation=function(e,n){n=t.identity;var i=Math.cos(e),r=Math.sin(e);return n.m11=i,n.m12=r,n.m21=-r,n.m22=i,n},t.createScale=function(e,n,i){return void 0===i&&(i=t.identity),i.m11=e,i.m12=0,i.m21=0,i.m22=n,i.m31=0,i.m32=0,i},t._identity=new t(1,0,0,1,0,0),t}(),Vector2=function(){function t(t,e){this.x=0,this.y=0,this.x=t,this.y=e}return Object.defineProperty(t,"One",{get:function(){return this.unitVector2},enumerable:!0,configurable:!0}),t.add=function(t,e){return t.x+=e.x,t.y+=e.y,t},t.divide=function(t,e){return t.x/=e.x,t.y/=e.y,t},t.multiply=function(t,e){return t.x*=e.x,t.y*=e.y,t},t.subtract=function(t,e){return t.x-=e.x,t.y-=e.y,t},t.prototype.normalize=function(){var t=1/Math.sqrt(this.x*this.x+this.y*this.y);this.x*=t,this.y*=t},t.transform=function(e,n){return new t(e.x*n.m11+e.y*n.m21,e.x*n.m12+e.y*n.m22)},t.unitVector2=new t(1,1),t}(); \ No newline at end of file +window.framework={},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 i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),Array.prototype.findIndex=function(t){return function(t,e){for(var n=0,i=t.length;n-1}(this,t)},Array.prototype.firstOrDefault=function(t){return function(t,e){var n=t.findIndex(e);return-1==n?null:t[n]}(this,t)},Array.prototype.find=function(t){return function(t,e){return t.firstOrDefault(e)}(this,t)},Array.prototype.where=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,o){return e.call(arguments[2],i,o,t)&&n.push(i),n},[]);for(var n=[],i=0,o=t.length;i=0&&t.splice(n,1)}while(n>=0)}(this,t)},Array.prototype.remove=function(t){return function(t,e){var n=t.findIndex(function(t){return t===e});return n>=0&&(t.splice(n,1),!0)}(this,t)},Array.prototype.removeAt=function(t){return function(t,e){t.splice(e,1)}(this,t)},Array.prototype.removeRange=function(t,e){return function(t,e,n){t.splice(e,n)}(this,t,e)},Array.prototype.select=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,o){return n.push(e.call(arguments[2],i,o,t)),n},[]);for(var n=[],i=0,o=t.length;ir?1:-1}),t}(this,t,e)},Array.prototype.orderByDescending=function(t,e){return function(t,e,n){return t.sort(function(t,i){var o=e(t),r=e(i);return n?-n(o,r):o=0;t--){this.transform.getChild(t).entity.destory()}},t}(),Scene=function(t){function e(e){var n=t.call(this)||this;return e.stage.addChild(n),n._projectionMatrix=new Matrix2D(0,0,0,0,0,0),n.entityProcessors=new EntityProcessorList,n.entities=new EntityList(n),n.addEventListener(egret.Event.ACTIVATE,n.onActive,n),n.addEventListener(egret.Event.DEACTIVATE,n.onDeactive,n),n.addEventListener(egret.Event.ENTER_FRAME,n.update,n),n}return __extends(e,t),e.prototype.createEntity=function(t){var e=new Entity(t);return e.transform.position=new Vector2(0,0),this.addEntity(e)},e.prototype.addEntity=function(t){this.entities.add(t),t.scene=this;for(var e=0;e>6;0!=(e&t.LONG_MASK)&&n++,this._bits=new Array(n)}return t.prototype.and=function(t){for(var e,n=Math.min(this._bits.length,t._bits.length),i=0;i=0;)this._bits[e]&=~t._bits[e]},t.prototype.cardinality=function(){for(var t=0,e=this._bits.length-1;e>=0;e--){var n=this._bits[e];if(0!=n)if(-1!=n){var i=((n=((n=(n>>1&0x5555555555555400)+(0x5555555555555400&n))>>2&0x3333333333333400)+(0x3333333333333400&n))>>32)+n;t+=((i=((i=(i>>4&252645135)+(252645135&i))>>8&16711935)+(16711935&i))>>16&65535)+(65535&i)}else t+=64}return t},t.prototype.clear=function(t){if(null!=t){var e=t>>6;this.ensure(e),this._bits[e]&=~(1<=this._bits.length){var e=new Number[t+1];e=this._bits.copyWithin(0,0,this._bits.length),this._bits=e}},t.prototype.get=function(t){var e=t>>6;return!(e>=this._bits.length)&&0!=(this._bits[e]&1<=0;)if(0!=(this._bits[e]&t._bits[e]))return!0;return!1},t.prototype.isEmpty=function(){for(var t=this._bits.length-1;t>=0;t--)if(this._bits[t])return!1;return!0},t.prototype.nextSetBit=function(t){for(var e=t>>6,n=1<>6;this.ensure(n),this._bits[n]|=1<0){for(var t=0;t0){t=0;for(var e=this._componentsToAdd.length;t0){var e=this._entitiesToRemove;this._entitiesToRemove=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t._entities.remove(e),e.scene=null,t.scene.entityProcessors.onEntityRemoved(e)}),this._tempEntityList.length=0}if(this._entitiesToAdded.length>0){e=this._entitiesToAdded;this._entitiesToAdded=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t._entities.push(e),e.scene=t.scene,t.scene.entityProcessors.onEntityAdded(e)}),this._tempEntityList.forEach(function(t){return t.onAddedToScene()}),this._tempEntityList.length=0}},t}(),EntityProcessorList=function(){function t(){this._processors=[]}return t.prototype.add=function(t){this._processors.push(t)},t.prototype.remove=function(t){this._processors.remove(t)},t.prototype.onComponentAdded=function(t){this.notifyEntityChanged(t)},t.prototype.onComponentRemoved=function(t){this.notifyEntityChanged(t)},t.prototype.onEntityAdded=function(t){this.notifyEntityChanged(t)},t.prototype.onEntityRemoved=function(t){this.removeFromProcessors(t)},t.prototype.notifyEntityChanged=function(t){for(var e=0;e=0;e=this.allSet.nextSetBit(e+1))if(!t.componentBits.get(e))return!1;return!(!this.exclusionSet.isEmpty()&&this.exclusionSet.intersects(t.componentBits))&&!(!this.oneSet.isEmpty()&&!this.oneSet.intersects(t.componentBits))},t}(),Time=function(){function t(){}return t.update=function(t){var e=(t-this._lastTime)/1e3;this.deltaTime=e*this.timeScale,this.unscaledDeltaTime=e,this._lastTime=t},t.timeScale=1,t._lastTime=0,t}(),MathHelper=function(){function t(){}return t.toDegrees=function(t){return 57.29577951308232*t},t.toRadians=function(t){return.017453292519943295*t},t}(),Matrix2D=function(){function t(t,e,n,i,o,r){this.m11=0,this.m12=0,this.m21=0,this.m22=0,this.m31=0,this.m32=0,this.m11=t,this.m12=e,this.m21=n,this.m22=i,this.m31=o,this.m32=r}return Object.defineProperty(t,"identity",{get:function(){return t._identity},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"translation",{get:function(){return new Vector2(this.m31,this.m32)},set:function(t){this.m31=t.x,this.m32=t.y},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotation",{get:function(){return Math.atan2(this.m21,this.m11)},set:function(t){var e=Math.cos(t),n=Math.sin(t);this.m11=e,this.m12=n,this.m21=-n,this.m22=e},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotationDegrees",{get:function(){return MathHelper.toDegrees(this.rotation)},set:function(t){this.rotation=MathHelper.toRadians(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scale",{get:function(){return new Vector2(this.m11,this.m22)},set:function(t){this.m11=t.x,this.m12=t.y},enumerable:!0,configurable:!0}),t.add=function(t,e){return t.m11+=e.m11,t.m12+=e.m12,t.m21+=e.m21,t.m22+=e.m22,t.m31+=e.m31,t.m32+=e.m32,t},t.divide=function(t,e){return t.m11/=e.m11,t.m12/=e.m12,t.m21/=e.m21,t.m22/=e.m22,t.m31/=e.m31,t.m32/=e.m32,t},t.multiply=function(t,e){var n=t.m11*e.m11+t.m12*e.m21,i=t.m11*e.m12+t.m12*e.m22,o=t.m21*e.m11+t.m22*e.m21,r=t.m21*e.m12+t.m22*e.m22,s=t.m31*e.m11+t.m32*e.m21+e.m31,a=t.m31*e.m12+t.m32*e.m22+e.m32;return t.m11=n,t.m12=i,t.m21=o,t.m22=r,t.m31=s,t.m32=a,t},t.multiplyTranslation=function(e,n,i){var o=t.createTranslation(n,i);return t.multiply(e,o)},t.prototype.determinant=function(){return this.m11*this.m22-this.m12*this.m21},t.invert=function(t,e){var n=1/t.determinant();return e.m11=t.m22*n,e.m12=-t.m12*n,e.m21=-t.m21*n,e.m22=t.m11*n,e.m31=(t.m32*t.m21-t.m31*t.m22)*n,e.m32=-(t.m32*t.m11-t.m31*t.m12)*n,e},t.createTranslation=function(e,n,i){return void 0===i&&(i=t.identity),i.m11=1,i.m12=0,i.m21=0,i.m22=1,i.m31=e,i.m32=n,i},t.createRotation=function(e,n){n=t.identity;var i=Math.cos(e),o=Math.sin(e);return n.m11=i,n.m12=o,n.m21=-o,n.m22=i,n},t.createScale=function(e,n,i){return void 0===i&&(i=t.identity),i.m11=e,i.m12=0,i.m21=0,i.m22=n,i.m31=0,i.m32=0,i},t._identity=new t(1,0,0,1,0,0),t}(),Vector2=function(){function t(t,e){this.x=0,this.y=0,this.x=t,this.y=e}return Object.defineProperty(t,"One",{get:function(){return this.unitVector2},enumerable:!0,configurable:!0}),t.add=function(t,e){return t.x+=e.x,t.y+=e.y,t},t.divide=function(t,e){return t.x/=e.x,t.y/=e.y,t},t.multiply=function(t,e){return t.x*=e.x,t.y*=e.y,t},t.subtract=function(t,e){return t.x-=e.x,t.y-=e.y,t},t.prototype.normalize=function(){var t=1/Math.sqrt(this.x*this.x+this.y*this.y);this.x*=t,this.y*=t},t.transform=function(e,n){return new t(e.x*n.m11+e.y*n.m21,e.x*n.m12+e.y*n.m22)},t.unitVector2=new t(1,1),t}(); \ No newline at end of file diff --git a/source/bin/framework.d.ts b/source/bin/framework.d.ts index c9b3698c..53c9717f 100644 --- a/source/bin/framework.d.ts +++ b/source/bin/framework.d.ts @@ -24,6 +24,11 @@ declare abstract class Component { enabled: boolean; setEnabled(isEnabled: boolean): this; abstract initialize(): any; + onAddedToEntity(): void; + onRemovedFromEntity(): void; + onEnabled(): void; + onDisabled(): void; + onEntityTransformChanged(comp: ComponentTransform): void; update(): void; bind(displayRender: egret.DisplayObject): this; registerComponent(): void; @@ -33,19 +38,25 @@ declare class Entity { name: string; scene: Scene; readonly transform: Transform; - readonly components: Component[]; + readonly components: ComponentList; private _updateOrder; private _enabled; + private _isDestoryed; componentBits: BitSet; + readonly isDestoryed: boolean; enabled: boolean; setEnabled(isEnabled: boolean): this; constructor(name: string); updateOrder: number; setUpdateOrder(updateOrder: number): this; attachToScene(newScene: Scene): void; + detachFromScene(): void; addComponent(component: T): T; getComponent(type: any): T; update(): void; + onAddedToScene(): void; + onRemovedFromScene(): void; + onTransformChanged(comp: ComponentTransform): void; destory(): void; } declare class Scene extends egret.DisplayObjectContainer { @@ -85,6 +96,11 @@ declare enum DirtyType { scaleDirty = 2, rotationDirty = 3 } +declare enum ComponentTransform { + position = 0, + scale = 1, + rotation = 2 +} declare class Transform { readonly entity: Entity; private _children; @@ -119,6 +135,7 @@ declare class Transform { localPosition: Vector2; setLocalPosition(localPosition: Vector2): this; setPosition(position: Vector2): this; + setDirty(dirtyFlagType: DirtyType): void; updateTransform(): void; } declare class Camera extends Component { @@ -176,6 +193,25 @@ declare class BitSet { nextSetBit(from: number): number; set(pos: number, value?: boolean): void; } +declare class ComponentList { + private _entity; + private _components; + private _componentsToAdd; + private _componentsToRemove; + private _tempBufferList; + constructor(entity: Entity); + readonly buffer: Component[]; + add(component: Component): void; + remove(component: Component): void; + removeAllComponents(): void; + deregisterAllComponents(): void; + registerAllComponents(): void; + updateLists(): void; + private handleRemove; + getComponent(type: any, onlyReturnInitializedComponents: boolean): T; + update(): void; + onEntityTransformChanged(comp: any): void; +} declare class ComponentTypeManager { private static _componentTypesMask; static add(type: any): void; diff --git a/source/bin/framework.js b/source/bin/framework.js index 360c5edd..217ab113 100644 --- a/source/bin/framework.js +++ b/source/bin/framework.js @@ -258,6 +258,16 @@ var Component = (function () { } return this; }; + Component.prototype.onAddedToEntity = function () { + }; + Component.prototype.onRemovedFromEntity = function () { + }; + Component.prototype.onEnabled = function () { + }; + Component.prototype.onDisabled = function () { + }; + Component.prototype.onEntityTransformChanged = function (comp) { + }; Component.prototype.update = function () { }; Component.prototype.bind = function (displayRender) { @@ -280,9 +290,16 @@ var Entity = (function () { this._enabled = true; this.name = name; this.transform = new Transform(this); - this.components = []; + this.components = new ComponentList(this); this.componentBits = new BitSet(); } + Object.defineProperty(Entity.prototype, "isDestoryed", { + get: function () { + return this._isDestoryed; + }, + enumerable: true, + configurable: true + }); Object.defineProperty(Entity.prototype, "enabled", { get: function () { return this._enabled; @@ -320,25 +337,41 @@ var Entity = (function () { Entity.prototype.attachToScene = function (newScene) { this.scene = newScene; newScene.entities.add(this); - this.components.forEach(function (component) { return component.registerComponent(); }); + this.components.registerAllComponents(); for (var i = 0; i < this.transform.childCount; i++) { this.transform.getChild(i).entity.attachToScene(newScene); } }; + Entity.prototype.detachFromScene = function () { + this.scene.entities.remove(this); + this.components.deregisterAllComponents(); + for (var i = 0; i < this.transform.childCount; i++) + this.transform.getChild(i).entity.detachFromScene(); + }; Entity.prototype.addComponent = function (component) { component.entity = this; - this.components.push(component); + this.components.add(component); component.initialize(); return component; }; Entity.prototype.getComponent = function (type) { - return this.components.firstOrDefault(function (component) { return component instanceof type; }); + return this.components.getComponent(type, false); }; Entity.prototype.update = function () { - this.components.forEach(function (component) { return component.update(); }); + this.components.update(); this.transform.updateTransform(); }; + Entity.prototype.onAddedToScene = function () { + }; + Entity.prototype.onRemovedFromScene = function () { + if (this._isDestoryed) + this.components.remove; + }; + Entity.prototype.onTransformChanged = function (comp) { + this.components.onEntityTransformChanged(comp); + }; Entity.prototype.destory = function () { + this._isDestoryed = true; this.scene.entities.remove(this); this.transform.parent = null; for (var i = this.transform.childCount - 1; i >= 0; i--) { @@ -461,6 +494,12 @@ var DirtyType; DirtyType[DirtyType["scaleDirty"] = 2] = "scaleDirty"; DirtyType[DirtyType["rotationDirty"] = 3] = "rotationDirty"; })(DirtyType || (DirtyType = {})); +var ComponentTransform; +(function (ComponentTransform) { + ComponentTransform[ComponentTransform["position"] = 0] = "position"; + ComponentTransform[ComponentTransform["scale"] = 1] = "scale"; + ComponentTransform[ComponentTransform["rotation"] = 2] = "rotation"; +})(ComponentTransform || (ComponentTransform = {})); var Transform = (function () { function Transform(entity) { this._localRotation = 0; @@ -536,6 +575,7 @@ var Transform = (function () { return this; this._localPosition = localPosition; this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true; + this.setDirty(DirtyType.positionDirty); return this; }; Transform.prototype.setPosition = function (position) { @@ -548,8 +588,8 @@ var Transform = (function () { else { this.localPosition = position; } - for (var i = 0; i < this.entity.components.length; i++) { - var component = this.entity.components[i]; + for (var i = 0; i < this.entity.components.buffer.length; i++) { + var component = this.entity.components.buffer[i]; if (component.displayRender) { component.displayRender.x = this.entity.scene.camera.transformMatrix.m31 + this.position.x; component.displayRender.y = this.entity.scene.camera.transformMatrix.m32 + this.position.y; @@ -557,6 +597,27 @@ var Transform = (function () { } return this; }; + Transform.prototype.setDirty = function (dirtyFlagType) { + if ((this._hierachyDirty & dirtyFlagType) == 0) { + this._hierachyDirty |= dirtyFlagType; + switch (dirtyFlagType) { + case DirtyType.positionDirty: + this.entity.onTransformChanged(ComponentTransform.position); + break; + case DirtyType.rotationDirty: + this.entity.onTransformChanged(ComponentTransform.rotation); + break; + case DirtyType.scaleDirty: + this.entity.onTransformChanged(ComponentTransform.scale); + break; + } + if (this._children == null) + this._children = []; + for (var i = 0; i < this._children.length; i++) { + this._children[i].setDirty(dirtyFlagType); + } + } + }; Transform.prototype.updateTransform = function () { if (this._hierachyDirty != DirtyType.clean) { if (this.parent) @@ -617,7 +678,7 @@ var Camera = (function (_super) { }; Camera.prototype.update = function () { var _this = this; - SceneManager.getActiveScene().entities.buffer.forEach(function (entity) { return entity.components.forEach(function (component) { + SceneManager.getActiveScene().entities.buffer.forEach(function (entity) { return entity.components.buffer.forEach(function (component) { if (component.displayRender) { var has = _this.entity.scene.$children.indexOf(component.displayRender); if (has == -1) { @@ -826,6 +887,116 @@ var BitSet = (function () { BitSet.LONG_MASK = 0x3f; return BitSet; }()); +var ComponentList = (function () { + function ComponentList(entity) { + this._components = []; + this._componentsToAdd = []; + this._componentsToRemove = []; + this._tempBufferList = []; + this._entity = entity; + } + Object.defineProperty(ComponentList.prototype, "buffer", { + get: function () { + return this._components; + }, + enumerable: true, + configurable: true + }); + ComponentList.prototype.add = function (component) { + this._componentsToAdd.push(component); + }; + ComponentList.prototype.remove = function (component) { + if (this._componentsToAdd.contains(component)) { + this._componentsToAdd.remove(component); + return; + } + this._componentsToRemove.push(component); + }; + ComponentList.prototype.removeAllComponents = function () { + for (var i = 0; i < this._components.length; i++) { + this.handleRemove(this._components[i]); + } + this._components.length = 0; + this._componentsToAdd.length = 0; + this._componentsToRemove.length = 0; + }; + ComponentList.prototype.deregisterAllComponents = function () { + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); + this._entity.scene.entityProcessors.onComponentRemoved(this._entity); + } + }; + ComponentList.prototype.registerAllComponents = function () { + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component)); + this._entity.scene.entityProcessors.onComponentAdded(this._entity); + } + }; + ComponentList.prototype.updateLists = function () { + if (this._componentsToRemove.length > 0) { + for (var i = 0; i < this._componentsToRemove.length; i++) { + this.handleRemove(this._componentsToRemove[i]); + this._components.remove(this._componentsToRemove[i]); + } + this._componentsToRemove.length = 0; + } + if (this._componentsToAdd.length > 0) { + for (var i = 0, count = this._componentsToAdd.length; i < count; i++) { + var component = this._componentsToAdd[i]; + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component)); + this._entity.scene.entityProcessors.onComponentAdded(this._entity); + this._components.push(component); + this._tempBufferList.push(component); + } + this._componentsToAdd.length = 0; + for (var i = 0; i < this._tempBufferList.length; i++) { + var component = this._tempBufferList[i]; + component.onAddedToEntity(); + if (component.enabled) { + component.onEnabled(); + } + } + this._tempBufferList.length = 0; + } + }; + ComponentList.prototype.handleRemove = function (component) { + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); + this._entity.scene.entityProcessors.onComponentRemoved(this._entity); + component.onRemovedFromEntity(); + component.entity = null; + }; + ComponentList.prototype.getComponent = function (type, onlyReturnInitializedComponents) { + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; + if (component instanceof type) + return component; + } + if (!onlyReturnInitializedComponents) { + for (var i = 0; i < this._componentsToAdd.length; i++) { + var component = this._componentsToAdd[i]; + if (component instanceof type) + return component; + } + } + return null; + }; + ComponentList.prototype.update = function () { + this.updateLists(); + }; + ComponentList.prototype.onEntityTransformChanged = function (comp) { + for (var i = 0; i < this._components.length; i++) { + if (this._components[i].enabled) + this._components[i].onEntityTransformChanged(comp); + } + for (var i = 0; i < this._componentsToAdd.length; i++) { + if (this._componentsToAdd[i].enabled) + this._componentsToAdd[i].onEntityTransformChanged(comp); + } + }; + return ComponentList; +}()); var ComponentTypeManager = (function () { function ComponentTypeManager() { } @@ -921,6 +1092,7 @@ var EntityList = (function () { entity.scene = _this.scene; _this.scene.entityProcessors.onEntityAdded(entity); }); + this._tempEntityList.forEach(function (entity) { return entity.onAddedToScene(); }); this._tempEntityList.length = 0; } }; diff --git a/source/bin/framework.min.js b/source/bin/framework.min.js index 03168566..08e86c3f 100644 --- a/source/bin/framework.min.js +++ b/source/bin/framework.min.js @@ -1 +1 @@ -window.framework={},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 i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),Array.prototype.findIndex=function(t){return function(t,e){for(var n=0,i=t.length;n-1}(this,t)},Array.prototype.firstOrDefault=function(t){return function(t,e){var n=t.findIndex(e);return-1==n?null:t[n]}(this,t)},Array.prototype.find=function(t){return function(t,e){return t.firstOrDefault(e)}(this,t)},Array.prototype.where=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,r){return e.call(arguments[2],i,r,t)&&n.push(i),n},[]);for(var n=[],i=0,r=t.length;i=0&&t.splice(n,1)}while(n>=0)}(this,t)},Array.prototype.remove=function(t){return function(t,e){var n=t.findIndex(function(t){return t===e});return n>=0&&(t.splice(n,1),!0)}(this,t)},Array.prototype.removeAt=function(t){return function(t,e){t.splice(e,1)}(this,t)},Array.prototype.removeRange=function(t,e){return function(t,e,n){t.splice(e,n)}(this,t,e)},Array.prototype.select=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,r){return n.push(e.call(arguments[2],i,r,t)),n},[]);for(var n=[],i=0,r=t.length;io?1:-1}),t}(this,t,e)},Array.prototype.orderByDescending=function(t,e){return function(t,e,n){return t.sort(function(t,i){var r=e(t),o=e(i);return n?-n(r,o):r=0;t--){this.transform.getChild(t).entity.destory()}},t}(),Scene=function(t){function e(e){var n=t.call(this)||this;return e.stage.addChild(n),n._projectionMatrix=new Matrix2D(0,0,0,0,0,0),n.entityProcessors=new EntityProcessorList,n.entities=new EntityList(n),n.addEventListener(egret.Event.ACTIVATE,n.onActive,n),n.addEventListener(egret.Event.DEACTIVATE,n.onDeactive,n),n.addEventListener(egret.Event.ENTER_FRAME,n.update,n),n}return __extends(e,t),e.prototype.createEntity=function(t){var e=new Entity(t);return e.transform.position=new Vector2(0,0),this.addEntity(e)},e.prototype.addEntity=function(t){this.entities.add(t),t.scene=this;for(var e=0;e>6;0!=(e&t.LONG_MASK)&&n++,this._bits=new Array(n)}return t.prototype.and=function(t){for(var e,n=Math.min(this._bits.length,t._bits.length),i=0;i=0;)this._bits[e]&=~t._bits[e]},t.prototype.cardinality=function(){for(var t=0,e=this._bits.length-1;e>=0;e--){var n=this._bits[e];if(0!=n)if(-1!=n){var i=((n=((n=(n>>1&0x5555555555555400)+(0x5555555555555400&n))>>2&0x3333333333333400)+(0x3333333333333400&n))>>32)+n;t+=((i=((i=(i>>4&252645135)+(252645135&i))>>8&16711935)+(16711935&i))>>16&65535)+(65535&i)}else t+=64}return t},t.prototype.clear=function(t){if(null!=t){var e=t>>6;this.ensure(e),this._bits[e]&=~(1<=this._bits.length){var e=new Number[t+1];e=this._bits.copyWithin(0,0,this._bits.length),this._bits=e}},t.prototype.get=function(t){var e=t>>6;return!(e>=this._bits.length)&&0!=(this._bits[e]&1<=0;)if(0!=(this._bits[e]&t._bits[e]))return!0;return!1},t.prototype.isEmpty=function(){for(var t=this._bits.length-1;t>=0;t--)if(this._bits[t])return!1;return!0},t.prototype.nextSetBit=function(t){for(var e=t>>6,n=1<>6;this.ensure(n),this._bits[n]|=1<0){var e=this._entitiesToRemove;this._entitiesToRemove=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t._entities.remove(e),e.scene=null,t.scene.entityProcessors.onEntityRemoved(e)}),this._tempEntityList.length=0}if(this._entitiesToAdded.length>0){e=this._entitiesToAdded;this._entitiesToAdded=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t._entities.push(e),e.scene=t.scene,t.scene.entityProcessors.onEntityAdded(e)}),this._tempEntityList.length=0}},t}(),EntityProcessorList=function(){function t(){this._processors=[]}return t.prototype.add=function(t){this._processors.push(t)},t.prototype.remove=function(t){this._processors.remove(t)},t.prototype.onComponentAdded=function(t){this.notifyEntityChanged(t)},t.prototype.onComponentRemoved=function(t){this.notifyEntityChanged(t)},t.prototype.onEntityAdded=function(t){this.notifyEntityChanged(t)},t.prototype.onEntityRemoved=function(t){this.removeFromProcessors(t)},t.prototype.notifyEntityChanged=function(t){for(var e=0;e=0;e=this.allSet.nextSetBit(e+1))if(!t.componentBits.get(e))return!1;return!(!this.exclusionSet.isEmpty()&&this.exclusionSet.intersects(t.componentBits))&&!(!this.oneSet.isEmpty()&&!this.oneSet.intersects(t.componentBits))},t}(),Time=function(){function t(){}return t.update=function(t){var e=(t-this._lastTime)/1e3;this.deltaTime=e*this.timeScale,this.unscaledDeltaTime=e,this._lastTime=t},t.timeScale=1,t._lastTime=0,t}(),MathHelper=function(){function t(){}return t.toDegrees=function(t){return 57.29577951308232*t},t.toRadians=function(t){return.017453292519943295*t},t}(),Matrix2D=function(){function t(t,e,n,i,r,o){this.m11=0,this.m12=0,this.m21=0,this.m22=0,this.m31=0,this.m32=0,this.m11=t,this.m12=e,this.m21=n,this.m22=i,this.m31=r,this.m32=o}return Object.defineProperty(t,"identity",{get:function(){return t._identity},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"translation",{get:function(){return new Vector2(this.m31,this.m32)},set:function(t){this.m31=t.x,this.m32=t.y},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotation",{get:function(){return Math.atan2(this.m21,this.m11)},set:function(t){var e=Math.cos(t),n=Math.sin(t);this.m11=e,this.m12=n,this.m21=-n,this.m22=e},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotationDegrees",{get:function(){return MathHelper.toDegrees(this.rotation)},set:function(t){this.rotation=MathHelper.toRadians(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scale",{get:function(){return new Vector2(this.m11,this.m22)},set:function(t){this.m11=t.x,this.m12=t.y},enumerable:!0,configurable:!0}),t.add=function(t,e){return t.m11+=e.m11,t.m12+=e.m12,t.m21+=e.m21,t.m22+=e.m22,t.m31+=e.m31,t.m32+=e.m32,t},t.divide=function(t,e){return t.m11/=e.m11,t.m12/=e.m12,t.m21/=e.m21,t.m22/=e.m22,t.m31/=e.m31,t.m32/=e.m32,t},t.multiply=function(t,e){var n=t.m11*e.m11+t.m12*e.m21,i=t.m11*e.m12+t.m12*e.m22,r=t.m21*e.m11+t.m22*e.m21,o=t.m21*e.m12+t.m22*e.m22,s=t.m31*e.m11+t.m32*e.m21+e.m31,a=t.m31*e.m12+t.m32*e.m22+e.m32;return t.m11=n,t.m12=i,t.m21=r,t.m22=o,t.m31=s,t.m32=a,t},t.multiplyTranslation=function(e,n,i){var r=t.createTranslation(n,i);return t.multiply(e,r)},t.prototype.determinant=function(){return this.m11*this.m22-this.m12*this.m21},t.invert=function(t,e){var n=1/t.determinant();return e.m11=t.m22*n,e.m12=-t.m12*n,e.m21=-t.m21*n,e.m22=t.m11*n,e.m31=(t.m32*t.m21-t.m31*t.m22)*n,e.m32=-(t.m32*t.m11-t.m31*t.m12)*n,e},t.createTranslation=function(e,n,i){return void 0===i&&(i=t.identity),i.m11=1,i.m12=0,i.m21=0,i.m22=1,i.m31=e,i.m32=n,i},t.createRotation=function(e,n){n=t.identity;var i=Math.cos(e),r=Math.sin(e);return n.m11=i,n.m12=r,n.m21=-r,n.m22=i,n},t.createScale=function(e,n,i){return void 0===i&&(i=t.identity),i.m11=e,i.m12=0,i.m21=0,i.m22=n,i.m31=0,i.m32=0,i},t._identity=new t(1,0,0,1,0,0),t}(),Vector2=function(){function t(t,e){this.x=0,this.y=0,this.x=t,this.y=e}return Object.defineProperty(t,"One",{get:function(){return this.unitVector2},enumerable:!0,configurable:!0}),t.add=function(t,e){return t.x+=e.x,t.y+=e.y,t},t.divide=function(t,e){return t.x/=e.x,t.y/=e.y,t},t.multiply=function(t,e){return t.x*=e.x,t.y*=e.y,t},t.subtract=function(t,e){return t.x-=e.x,t.y-=e.y,t},t.prototype.normalize=function(){var t=1/Math.sqrt(this.x*this.x+this.y*this.y);this.x*=t,this.y*=t},t.transform=function(e,n){return new t(e.x*n.m11+e.y*n.m21,e.x*n.m12+e.y*n.m22)},t.unitVector2=new t(1,1),t}(); \ No newline at end of file +window.framework={},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 i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),Array.prototype.findIndex=function(t){return function(t,e){for(var n=0,i=t.length;n-1}(this,t)},Array.prototype.firstOrDefault=function(t){return function(t,e){var n=t.findIndex(e);return-1==n?null:t[n]}(this,t)},Array.prototype.find=function(t){return function(t,e){return t.firstOrDefault(e)}(this,t)},Array.prototype.where=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,o){return e.call(arguments[2],i,o,t)&&n.push(i),n},[]);for(var n=[],i=0,o=t.length;i=0&&t.splice(n,1)}while(n>=0)}(this,t)},Array.prototype.remove=function(t){return function(t,e){var n=t.findIndex(function(t){return t===e});return n>=0&&(t.splice(n,1),!0)}(this,t)},Array.prototype.removeAt=function(t){return function(t,e){t.splice(e,1)}(this,t)},Array.prototype.removeRange=function(t,e){return function(t,e,n){t.splice(e,n)}(this,t,e)},Array.prototype.select=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,o){return n.push(e.call(arguments[2],i,o,t)),n},[]);for(var n=[],i=0,o=t.length;ir?1:-1}),t}(this,t,e)},Array.prototype.orderByDescending=function(t,e){return function(t,e,n){return t.sort(function(t,i){var o=e(t),r=e(i);return n?-n(o,r):o=0;t--){this.transform.getChild(t).entity.destory()}},t}(),Scene=function(t){function e(e){var n=t.call(this)||this;return e.stage.addChild(n),n._projectionMatrix=new Matrix2D(0,0,0,0,0,0),n.entityProcessors=new EntityProcessorList,n.entities=new EntityList(n),n.addEventListener(egret.Event.ACTIVATE,n.onActive,n),n.addEventListener(egret.Event.DEACTIVATE,n.onDeactive,n),n.addEventListener(egret.Event.ENTER_FRAME,n.update,n),n}return __extends(e,t),e.prototype.createEntity=function(t){var e=new Entity(t);return e.transform.position=new Vector2(0,0),this.addEntity(e)},e.prototype.addEntity=function(t){this.entities.add(t),t.scene=this;for(var e=0;e>6;0!=(e&t.LONG_MASK)&&n++,this._bits=new Array(n)}return t.prototype.and=function(t){for(var e,n=Math.min(this._bits.length,t._bits.length),i=0;i=0;)this._bits[e]&=~t._bits[e]},t.prototype.cardinality=function(){for(var t=0,e=this._bits.length-1;e>=0;e--){var n=this._bits[e];if(0!=n)if(-1!=n){var i=((n=((n=(n>>1&0x5555555555555400)+(0x5555555555555400&n))>>2&0x3333333333333400)+(0x3333333333333400&n))>>32)+n;t+=((i=((i=(i>>4&252645135)+(252645135&i))>>8&16711935)+(16711935&i))>>16&65535)+(65535&i)}else t+=64}return t},t.prototype.clear=function(t){if(null!=t){var e=t>>6;this.ensure(e),this._bits[e]&=~(1<=this._bits.length){var e=new Number[t+1];e=this._bits.copyWithin(0,0,this._bits.length),this._bits=e}},t.prototype.get=function(t){var e=t>>6;return!(e>=this._bits.length)&&0!=(this._bits[e]&1<=0;)if(0!=(this._bits[e]&t._bits[e]))return!0;return!1},t.prototype.isEmpty=function(){for(var t=this._bits.length-1;t>=0;t--)if(this._bits[t])return!1;return!0},t.prototype.nextSetBit=function(t){for(var e=t>>6,n=1<>6;this.ensure(n),this._bits[n]|=1<0){for(var t=0;t0){t=0;for(var e=this._componentsToAdd.length;t0){var e=this._entitiesToRemove;this._entitiesToRemove=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t._entities.remove(e),e.scene=null,t.scene.entityProcessors.onEntityRemoved(e)}),this._tempEntityList.length=0}if(this._entitiesToAdded.length>0){e=this._entitiesToAdded;this._entitiesToAdded=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t._entities.push(e),e.scene=t.scene,t.scene.entityProcessors.onEntityAdded(e)}),this._tempEntityList.forEach(function(t){return t.onAddedToScene()}),this._tempEntityList.length=0}},t}(),EntityProcessorList=function(){function t(){this._processors=[]}return t.prototype.add=function(t){this._processors.push(t)},t.prototype.remove=function(t){this._processors.remove(t)},t.prototype.onComponentAdded=function(t){this.notifyEntityChanged(t)},t.prototype.onComponentRemoved=function(t){this.notifyEntityChanged(t)},t.prototype.onEntityAdded=function(t){this.notifyEntityChanged(t)},t.prototype.onEntityRemoved=function(t){this.removeFromProcessors(t)},t.prototype.notifyEntityChanged=function(t){for(var e=0;e=0;e=this.allSet.nextSetBit(e+1))if(!t.componentBits.get(e))return!1;return!(!this.exclusionSet.isEmpty()&&this.exclusionSet.intersects(t.componentBits))&&!(!this.oneSet.isEmpty()&&!this.oneSet.intersects(t.componentBits))},t}(),Time=function(){function t(){}return t.update=function(t){var e=(t-this._lastTime)/1e3;this.deltaTime=e*this.timeScale,this.unscaledDeltaTime=e,this._lastTime=t},t.timeScale=1,t._lastTime=0,t}(),MathHelper=function(){function t(){}return t.toDegrees=function(t){return 57.29577951308232*t},t.toRadians=function(t){return.017453292519943295*t},t}(),Matrix2D=function(){function t(t,e,n,i,o,r){this.m11=0,this.m12=0,this.m21=0,this.m22=0,this.m31=0,this.m32=0,this.m11=t,this.m12=e,this.m21=n,this.m22=i,this.m31=o,this.m32=r}return Object.defineProperty(t,"identity",{get:function(){return t._identity},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"translation",{get:function(){return new Vector2(this.m31,this.m32)},set:function(t){this.m31=t.x,this.m32=t.y},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotation",{get:function(){return Math.atan2(this.m21,this.m11)},set:function(t){var e=Math.cos(t),n=Math.sin(t);this.m11=e,this.m12=n,this.m21=-n,this.m22=e},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotationDegrees",{get:function(){return MathHelper.toDegrees(this.rotation)},set:function(t){this.rotation=MathHelper.toRadians(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scale",{get:function(){return new Vector2(this.m11,this.m22)},set:function(t){this.m11=t.x,this.m12=t.y},enumerable:!0,configurable:!0}),t.add=function(t,e){return t.m11+=e.m11,t.m12+=e.m12,t.m21+=e.m21,t.m22+=e.m22,t.m31+=e.m31,t.m32+=e.m32,t},t.divide=function(t,e){return t.m11/=e.m11,t.m12/=e.m12,t.m21/=e.m21,t.m22/=e.m22,t.m31/=e.m31,t.m32/=e.m32,t},t.multiply=function(t,e){var n=t.m11*e.m11+t.m12*e.m21,i=t.m11*e.m12+t.m12*e.m22,o=t.m21*e.m11+t.m22*e.m21,r=t.m21*e.m12+t.m22*e.m22,s=t.m31*e.m11+t.m32*e.m21+e.m31,a=t.m31*e.m12+t.m32*e.m22+e.m32;return t.m11=n,t.m12=i,t.m21=o,t.m22=r,t.m31=s,t.m32=a,t},t.multiplyTranslation=function(e,n,i){var o=t.createTranslation(n,i);return t.multiply(e,o)},t.prototype.determinant=function(){return this.m11*this.m22-this.m12*this.m21},t.invert=function(t,e){var n=1/t.determinant();return e.m11=t.m22*n,e.m12=-t.m12*n,e.m21=-t.m21*n,e.m22=t.m11*n,e.m31=(t.m32*t.m21-t.m31*t.m22)*n,e.m32=-(t.m32*t.m11-t.m31*t.m12)*n,e},t.createTranslation=function(e,n,i){return void 0===i&&(i=t.identity),i.m11=1,i.m12=0,i.m21=0,i.m22=1,i.m31=e,i.m32=n,i},t.createRotation=function(e,n){n=t.identity;var i=Math.cos(e),o=Math.sin(e);return n.m11=i,n.m12=o,n.m21=-o,n.m22=i,n},t.createScale=function(e,n,i){return void 0===i&&(i=t.identity),i.m11=e,i.m12=0,i.m21=0,i.m22=n,i.m31=0,i.m32=0,i},t._identity=new t(1,0,0,1,0,0),t}(),Vector2=function(){function t(t,e){this.x=0,this.y=0,this.x=t,this.y=e}return Object.defineProperty(t,"One",{get:function(){return this.unitVector2},enumerable:!0,configurable:!0}),t.add=function(t,e){return t.x+=e.x,t.y+=e.y,t},t.divide=function(t,e){return t.x/=e.x,t.y/=e.y,t},t.multiply=function(t,e){return t.x*=e.x,t.y*=e.y,t},t.subtract=function(t,e){return t.x-=e.x,t.y-=e.y,t},t.prototype.normalize=function(){var t=1/Math.sqrt(this.x*this.x+this.y*this.y);this.x*=t,this.y*=t},t.transform=function(e,n){return new t(e.x*n.m11+e.y*n.m21,e.x*n.m12+e.y*n.m22)},t.unitVector2=new t(1,1),t}(); \ No newline at end of file diff --git a/source/src/ECS/Component.ts b/source/src/ECS/Component.ts index d919d38e..406dc67c 100644 --- a/source/src/ECS/Component.ts +++ b/source/src/ECS/Component.ts @@ -20,6 +20,26 @@ abstract class Component { public abstract initialize(); + public onAddedToEntity(){ + + } + + public onRemovedFromEntity(){ + + } + + public onEnabled(){ + + } + + public onDisabled(){ + + } + + public onEntityTransformChanged(comp: ComponentTransform){ + + } + public update(){ } diff --git a/source/src/ECS/Components/Camera.ts b/source/src/ECS/Components/Camera.ts index 30f90a13..6e44cb44 100644 --- a/source/src/ECS/Components/Camera.ts +++ b/source/src/ECS/Components/Camera.ts @@ -20,7 +20,7 @@ class Camera extends Component { } public update(){ - SceneManager.getActiveScene().entities.buffer.forEach(entity => entity.components.forEach(component => { + SceneManager.getActiveScene().entities.buffer.forEach(entity => entity.components.buffer.forEach(component => { if (component.displayRender){ let has = this.entity.scene.$children.indexOf(component.displayRender) if (has == -1){ diff --git a/source/src/ECS/Entity.ts b/source/src/ECS/Entity.ts index 08c9e3ee..63381e41 100644 --- a/source/src/ECS/Entity.ts +++ b/source/src/ECS/Entity.ts @@ -5,12 +5,17 @@ class Entity { /** 封装实体的位置/旋转/缩放,并允许设置一个高层结构 */ public readonly transform: Transform; /** 当前附加到此实体的所有组件的列表 */ - public readonly components: Component[]; + public readonly components: ComponentList; private _updateOrder: number = 0; private _enabled: boolean = true; + private _isDestoryed: boolean; public componentBits: BitSet; + public get isDestoryed(){ + return this._isDestoryed; + } + public get enabled(){ return this._enabled; } @@ -30,7 +35,7 @@ class Entity { constructor(name: string){ this.name = name; this.transform = new Transform(this); - this.components = []; + this.components = new ComponentList(this); this.componentBits = new BitSet(); } @@ -56,30 +61,52 @@ class Entity { public attachToScene(newScene: Scene){ this.scene = newScene; newScene.entities.add(this); - this.components.forEach(component => component.registerComponent()); + this.components.registerAllComponents(); for (let i = 0; i < this.transform.childCount; i ++){ this.transform.getChild(i).entity.attachToScene(newScene); } } + public detachFromScene(){ + this.scene.entities.remove(this); + this.components.deregisterAllComponents(); + + for (let i = 0; i < this.transform.childCount; i ++) + this.transform.getChild(i).entity.detachFromScene(); + } + public addComponent(component: T): T{ component.entity = this; - this.components.push(component); + this.components.add(component); component.initialize(); return component; } public getComponent(type): T{ - return this.components.firstOrDefault(component => component instanceof type) as T; + return this.components.getComponent(type, false) as T; } public update(){ - this.components.forEach(component => component.update()); + this.components.update(); this.transform.updateTransform(); } + public onAddedToScene(){ + + } + + public onRemovedFromScene(){ + if (this._isDestoryed) + this.components.remove + } + + public onTransformChanged(comp: ComponentTransform){ + this.components.onEntityTransformChanged(comp); + } + public destory(){ + this._isDestoryed = true; this.scene.entities.remove(this); this.transform.parent = null; diff --git a/source/src/ECS/Transform.ts b/source/src/ECS/Transform.ts index 9258f56c..6f0b1590 100644 --- a/source/src/ECS/Transform.ts +++ b/source/src/ECS/Transform.ts @@ -5,6 +5,12 @@ enum DirtyType{ rotationDirty, } +enum ComponentTransform{ + position, + scale, + rotation +} + class Transform { /** 相关联的实体 */ public readonly entity: Entity; @@ -105,6 +111,7 @@ class Transform { this._localPosition = localPosition; this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true; + this.setDirty(DirtyType.positionDirty); return this; } @@ -120,8 +127,8 @@ class Transform { this.localPosition = position; } - for (let i = 0; i < this.entity.components.length; i ++){ - let component = this.entity.components[i]; + for (let i = 0; i < this.entity.components.buffer.length; i ++){ + let component = this.entity.components.buffer[i]; if (component.displayRender){ component.displayRender.x = this.entity.scene.camera.transformMatrix.m31 + this.position.x; component.displayRender.y = this.entity.scene.camera.transformMatrix.m32 + this.position.y; @@ -131,6 +138,31 @@ class Transform { return this; } + public setDirty(dirtyFlagType: DirtyType){ + if ((this._hierachyDirty & dirtyFlagType) == 0){ + this._hierachyDirty |= dirtyFlagType; + + switch (dirtyFlagType){ + case DirtyType.positionDirty: + this.entity.onTransformChanged(ComponentTransform.position); + break; + case DirtyType.rotationDirty: + this.entity.onTransformChanged(ComponentTransform.rotation); + break; + case DirtyType.scaleDirty: + this.entity.onTransformChanged(ComponentTransform.scale); + break; + } + + if (this._children == null) + this._children = []; + + for (let i = 0; i < this._children.length; i ++){ + this._children[i].setDirty(dirtyFlagType); + } + } + } + public updateTransform(){ if (this._hierachyDirty != DirtyType.clean){ if (this.parent) diff --git a/source/src/ECS/Utils/ComponentList.ts b/source/src/ECS/Utils/ComponentList.ts new file mode 100644 index 00000000..a0b7b95e --- /dev/null +++ b/source/src/ECS/Utils/ComponentList.ts @@ -0,0 +1,134 @@ +class ComponentList { + private _entity: Entity; + private _components: Component[] = []; + private _componentsToAdd: Component[] = []; + private _componentsToRemove: Component[] = []; + private _tempBufferList: Component[] = []; + + constructor(entity: Entity){ + this._entity = entity; + } + + public get buffer(){ + return this._components; + } + + public add(component: Component){ + this._componentsToAdd.push(component); + } + + public remove(component: Component){ + if (this._componentsToAdd.contains(component)){ + this._componentsToAdd.remove(component); + return; + } + + this._componentsToRemove.push(component); + } + + public removeAllComponents(){ + for (let i = 0; i < this._components.length; i ++){ + this.handleRemove(this._components[i]); + } + + this._components.length = 0; + this._componentsToAdd.length = 0; + this._componentsToRemove.length = 0; + } + + public deregisterAllComponents(){ + for (let i = 0; i < this._components.length; i ++){ + let component = this._components[i]; + + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); + this._entity.scene.entityProcessors.onComponentRemoved(this._entity); + } + } + + public registerAllComponents(){ + for (let i = 0; i < this._components.length; i ++){ + let component = this._components[i]; + + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component)); + this._entity.scene.entityProcessors.onComponentAdded(this._entity); + } + } + + public updateLists(){ + if (this._componentsToRemove.length > 0){ + for (let i = 0; i < this._componentsToRemove.length; i ++){ + this.handleRemove(this._componentsToRemove[i]); + this._components.remove(this._componentsToRemove[i]); + } + + this._componentsToRemove.length = 0; + } + + if (this._componentsToAdd.length > 0){ + for (let i = 0, count = this._componentsToAdd.length; i < count; i ++){ + let component = this._componentsToAdd[i]; + + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component)); + this._entity.scene.entityProcessors.onComponentAdded(this._entity); + + this._components.push(component); + this._tempBufferList.push(component); + } + + this._componentsToAdd.length = 0; + + for (let i = 0; i < this._tempBufferList.length; i++){ + let component = this._tempBufferList[i]; + component.onAddedToEntity(); + + if (component.enabled){ + component.onEnabled(); + } + } + + this._tempBufferList.length = 0; + } + } + + private handleRemove(component: Component){ + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); + this._entity.scene.entityProcessors.onComponentRemoved(this._entity); + + component.onRemovedFromEntity(); + component.entity = null; + } + + public getComponent(type, onlyReturnInitializedComponents: boolean): T{ + for (let i = 0; i < this._components.length; i ++){ + let component = this._components[i]; + if (component instanceof type) + return component as T; + } + + if (!onlyReturnInitializedComponents){ + for (let i = 0; i < this._componentsToAdd.length; i ++){ + let component = this._componentsToAdd[i]; + if (component instanceof type) + return component as T; + } + } + + return null; + } + + public update(){ + this.updateLists(); + } + + public onEntityTransformChanged(comp){ + for (let i = 0; i < this._components.length; i++){ + if (this._components[i].enabled) + this._components[i].onEntityTransformChanged(comp); + } + + for (let i = 0; i < this._componentsToAdd.length; i ++){ + if (this._componentsToAdd[i].enabled) + this._componentsToAdd[i].onEntityTransformChanged(comp); + } + } +} \ No newline at end of file diff --git a/source/src/ECS/Utils/EntityList.ts b/source/src/ECS/Utils/EntityList.ts index 909a3dca..d3e20f73 100644 --- a/source/src/ECS/Utils/EntityList.ts +++ b/source/src/ECS/Utils/EntityList.ts @@ -86,6 +86,7 @@ class EntityList{ this.scene.entityProcessors.onEntityAdded(entity) }); + this._tempEntityList.forEach(entity => entity.onAddedToScene()); this._tempEntityList.length = 0; } }