新增entitylist用于管理实体
This commit is contained in:
51
demo/libs/framework/framework.d.ts
vendored
51
demo/libs/framework/framework.d.ts
vendored
@@ -26,6 +26,7 @@ declare abstract class Component {
|
|||||||
abstract initialize(): any;
|
abstract initialize(): any;
|
||||||
update(): void;
|
update(): void;
|
||||||
bind(displayRender: egret.DisplayObject): this;
|
bind(displayRender: egret.DisplayObject): this;
|
||||||
|
registerComponent(): void;
|
||||||
}
|
}
|
||||||
declare class Entity {
|
declare class Entity {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -34,6 +35,7 @@ declare class Entity {
|
|||||||
readonly components: Component[];
|
readonly components: Component[];
|
||||||
private _updateOrder;
|
private _updateOrder;
|
||||||
private _enabled;
|
private _enabled;
|
||||||
|
componentBits: BitSet;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
setEnabled(isEnabled: boolean): this;
|
setEnabled(isEnabled: boolean): this;
|
||||||
constructor(name: string);
|
constructor(name: string);
|
||||||
@@ -47,7 +49,7 @@ declare class Entity {
|
|||||||
}
|
}
|
||||||
declare class Scene extends egret.DisplayObjectContainer {
|
declare class Scene extends egret.DisplayObjectContainer {
|
||||||
camera: Camera;
|
camera: Camera;
|
||||||
entities: Entity[];
|
readonly entities: EntityList;
|
||||||
private _projectionMatrix;
|
private _projectionMatrix;
|
||||||
private _transformMatrix;
|
private _transformMatrix;
|
||||||
private _matrixTransformMatrix;
|
private _matrixTransformMatrix;
|
||||||
@@ -55,7 +57,7 @@ declare class Scene extends egret.DisplayObjectContainer {
|
|||||||
constructor(displayObject: egret.DisplayObject);
|
constructor(displayObject: egret.DisplayObject);
|
||||||
createEntity(name: string): Entity;
|
createEntity(name: string): Entity;
|
||||||
addEntity(entity: Entity): Entity;
|
addEntity(entity: Entity): Entity;
|
||||||
destoryAllEntities(): void;
|
destroyAllEntities(): void;
|
||||||
findEntity(name: string): Entity;
|
findEntity(name: string): Entity;
|
||||||
addEntityProcessor(processor: EntitySystem): EntitySystem;
|
addEntityProcessor(processor: EntitySystem): EntitySystem;
|
||||||
removeEntityProcessor(processor: EntitySystem): void;
|
removeEntityProcessor(processor: EntitySystem): void;
|
||||||
@@ -139,6 +141,11 @@ declare class EntitySystem {
|
|||||||
scene: Scene;
|
scene: Scene;
|
||||||
constructor(matcher?: Matcher);
|
constructor(matcher?: Matcher);
|
||||||
initialize(): void;
|
initialize(): void;
|
||||||
|
onChanged(entity: Entity): void;
|
||||||
|
add(entity: Entity): void;
|
||||||
|
onAdded(entity: Entity): void;
|
||||||
|
remove(entity: Entity): void;
|
||||||
|
onRemoved(entity: Entity): void;
|
||||||
update(): void;
|
update(): void;
|
||||||
lateUpdate(): void;
|
lateUpdate(): void;
|
||||||
protected begin(): void;
|
protected begin(): void;
|
||||||
@@ -153,8 +160,48 @@ declare abstract class EntityProcessingSystem extends EntitySystem {
|
|||||||
protected process(entities: Entity[]): void;
|
protected process(entities: Entity[]): void;
|
||||||
protected lateProcess(entities: Entity[]): void;
|
protected lateProcess(entities: Entity[]): void;
|
||||||
}
|
}
|
||||||
|
declare class BitSet {
|
||||||
|
private static LONG_MASK;
|
||||||
|
private _bits;
|
||||||
|
constructor(nbits?: number);
|
||||||
|
and(bs: BitSet): void;
|
||||||
|
andNot(bs: BitSet): void;
|
||||||
|
cardinality(): number;
|
||||||
|
clear(pos?: number): void;
|
||||||
|
private ensure;
|
||||||
|
get(pos: number): boolean;
|
||||||
|
intersects(set: BitSet): boolean;
|
||||||
|
isEmpty(): boolean;
|
||||||
|
nextSetBit(from: number): number;
|
||||||
|
set(pos: number): void;
|
||||||
|
}
|
||||||
|
declare class ComponentTypeManager {
|
||||||
|
private static _componentTypesMask;
|
||||||
|
static add(type: any): void;
|
||||||
|
static getIndexFor(type: any): number;
|
||||||
|
}
|
||||||
|
declare class EntityList {
|
||||||
|
scene: Scene;
|
||||||
|
private _entitiesToRemove;
|
||||||
|
private _entitiesToAdded;
|
||||||
|
private _tempEntityList;
|
||||||
|
private _entities;
|
||||||
|
constructor(scene: Scene);
|
||||||
|
readonly count: number;
|
||||||
|
readonly buffer: Entity[];
|
||||||
|
add(entity: Entity): void;
|
||||||
|
remove(entity: Entity): void;
|
||||||
|
findEntity(name: string): Entity;
|
||||||
|
update(): void;
|
||||||
|
removeAllEntities(): void;
|
||||||
|
updateLists(): void;
|
||||||
|
}
|
||||||
declare class Matcher {
|
declare class Matcher {
|
||||||
|
protected allSet: BitSet;
|
||||||
|
protected exclusionSet: BitSet;
|
||||||
|
protected oneSet: BitSet;
|
||||||
static empty(): Matcher;
|
static empty(): Matcher;
|
||||||
|
IsIntersted(e: Entity): boolean;
|
||||||
}
|
}
|
||||||
declare class MathHelper {
|
declare class MathHelper {
|
||||||
static toDegrees(radians: number): number;
|
static toDegrees(radians: number): number;
|
||||||
|
|||||||
@@ -264,6 +264,11 @@ var Component = (function () {
|
|||||||
this.displayRender = displayRender;
|
this.displayRender = displayRender;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
Component.prototype.registerComponent = function () {
|
||||||
|
var _this = this;
|
||||||
|
this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this));
|
||||||
|
this.entity.scene.entityProcessors.forEach(function (processor) { return processor.onChanged(_this.entity); });
|
||||||
|
};
|
||||||
return Component;
|
return Component;
|
||||||
}());
|
}());
|
||||||
var Entity = (function () {
|
var Entity = (function () {
|
||||||
@@ -273,6 +278,7 @@ var Entity = (function () {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
this.transform = new Transform(this);
|
this.transform = new Transform(this);
|
||||||
this.components = [];
|
this.components = [];
|
||||||
|
this.componentBits = new BitSet();
|
||||||
}
|
}
|
||||||
Object.defineProperty(Entity.prototype, "enabled", {
|
Object.defineProperty(Entity.prototype, "enabled", {
|
||||||
get: function () {
|
get: function () {
|
||||||
@@ -310,7 +316,8 @@ var Entity = (function () {
|
|||||||
};
|
};
|
||||||
Entity.prototype.attachToScene = function (newScene) {
|
Entity.prototype.attachToScene = function (newScene) {
|
||||||
this.scene = newScene;
|
this.scene = newScene;
|
||||||
newScene.entities.push(this);
|
newScene.entities.add(this);
|
||||||
|
this.components.forEach(function (component) { return component.registerComponent(); });
|
||||||
for (var i = 0; i < this.transform.childCount; i++) {
|
for (var i = 0; i < this.transform.childCount; i++) {
|
||||||
this.transform.getChild(i).entity.attachToScene(newScene);
|
this.transform.getChild(i).entity.attachToScene(newScene);
|
||||||
}
|
}
|
||||||
@@ -342,10 +349,10 @@ var Scene = (function (_super) {
|
|||||||
__extends(Scene, _super);
|
__extends(Scene, _super);
|
||||||
function Scene(displayObject) {
|
function Scene(displayObject) {
|
||||||
var _this = _super.call(this) || this;
|
var _this = _super.call(this) || this;
|
||||||
_this.entities = [];
|
|
||||||
displayObject.stage.addChild(_this);
|
displayObject.stage.addChild(_this);
|
||||||
_this._projectionMatrix = new Matrix2D(0, 0, 0, 0, 0, 0);
|
_this._projectionMatrix = new Matrix2D(0, 0, 0, 0, 0, 0);
|
||||||
_this.entityProcessors = [];
|
_this.entityProcessors = [];
|
||||||
|
_this.entities = new EntityList(_this);
|
||||||
_this.addEventListener(egret.Event.ACTIVATE, _this.onActive, _this);
|
_this.addEventListener(egret.Event.ACTIVATE, _this.onActive, _this);
|
||||||
_this.addEventListener(egret.Event.DEACTIVATE, _this.onDeactive, _this);
|
_this.addEventListener(egret.Event.DEACTIVATE, _this.onDeactive, _this);
|
||||||
_this.addEventListener(egret.Event.ENTER_FRAME, _this.update, _this);
|
_this.addEventListener(egret.Event.ENTER_FRAME, _this.update, _this);
|
||||||
@@ -357,15 +364,19 @@ var Scene = (function (_super) {
|
|||||||
return this.addEntity(entity);
|
return this.addEntity(entity);
|
||||||
};
|
};
|
||||||
Scene.prototype.addEntity = function (entity) {
|
Scene.prototype.addEntity = function (entity) {
|
||||||
this.entities.push(entity);
|
this.entities.add(entity);
|
||||||
entity.scene = this;
|
entity.scene = this;
|
||||||
|
for (var i = 0; i < entity.transform.childCount; i++)
|
||||||
|
this.addEntity(entity.transform.getChild(i).entity);
|
||||||
return entity;
|
return entity;
|
||||||
};
|
};
|
||||||
Scene.prototype.destoryAllEntities = function () {
|
Scene.prototype.destroyAllEntities = function () {
|
||||||
this.entities.forEach(function (entity) { return entity.destory(); });
|
for (var i = 0; i < this.entities.count; i++) {
|
||||||
|
this.entities.buffer[i].destory();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Scene.prototype.findEntity = function (name) {
|
Scene.prototype.findEntity = function (name) {
|
||||||
return this.entities.firstOrDefault(function (entity) { return entity.name == name; });
|
return this.entities.findEntity(name);
|
||||||
};
|
};
|
||||||
Scene.prototype.addEntityProcessor = function (processor) {
|
Scene.prototype.addEntityProcessor = function (processor) {
|
||||||
processor.scene = this;
|
processor.scene = this;
|
||||||
@@ -391,8 +402,9 @@ var Scene = (function (_super) {
|
|||||||
Scene.prototype.onDeactive = function () {
|
Scene.prototype.onDeactive = function () {
|
||||||
};
|
};
|
||||||
Scene.prototype.update = function () {
|
Scene.prototype.update = function () {
|
||||||
|
this.entities.updateLists();
|
||||||
this.entityProcessors.forEach(function (processor) { return processor.update(); });
|
this.entityProcessors.forEach(function (processor) { return processor.update(); });
|
||||||
this.entities.forEach(function (entity) { return entity.update(); });
|
this.entities.update();
|
||||||
this.entityProcessors.forEach(function (processor) { return processor.lateUpdate(); });
|
this.entityProcessors.forEach(function (processor) { return processor.lateUpdate(); });
|
||||||
};
|
};
|
||||||
Scene.prototype.prepRenderState = function () {
|
Scene.prototype.prepRenderState = function () {
|
||||||
@@ -406,8 +418,7 @@ var Scene = (function (_super) {
|
|||||||
this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
||||||
this.camera.destory();
|
this.camera.destory();
|
||||||
this.camera = null;
|
this.camera = null;
|
||||||
this.entities.forEach(function (entity) { return entity.destory(); });
|
this.entities.removeAllEntities();
|
||||||
this.entities.length = 0;
|
|
||||||
};
|
};
|
||||||
return Scene;
|
return Scene;
|
||||||
}(egret.DisplayObjectContainer));
|
}(egret.DisplayObjectContainer));
|
||||||
@@ -599,7 +610,7 @@ var Camera = (function (_super) {
|
|||||||
};
|
};
|
||||||
Camera.prototype.update = function () {
|
Camera.prototype.update = function () {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
SceneManager.getActiveScene().entities.forEach(function (entity) { return entity.components.forEach(function (component) {
|
SceneManager.getActiveScene().entities.buffer.forEach(function (entity) { return entity.components.forEach(function (component) {
|
||||||
if (component.displayRender) {
|
if (component.displayRender) {
|
||||||
var has = _this.entity.scene.$children.indexOf(component.displayRender);
|
var has = _this.entity.scene.$children.indexOf(component.displayRender);
|
||||||
if (has == -1) {
|
if (has == -1) {
|
||||||
@@ -644,6 +655,26 @@ var EntitySystem = (function () {
|
|||||||
});
|
});
|
||||||
EntitySystem.prototype.initialize = function () {
|
EntitySystem.prototype.initialize = function () {
|
||||||
};
|
};
|
||||||
|
EntitySystem.prototype.onChanged = function (entity) {
|
||||||
|
var contains = this._entities.contains(entity);
|
||||||
|
var interest = this._matcher.IsIntersted(entity);
|
||||||
|
if (interest && !contains)
|
||||||
|
this.add(entity);
|
||||||
|
else if (!interest && contains)
|
||||||
|
this.remove(entity);
|
||||||
|
};
|
||||||
|
EntitySystem.prototype.add = function (entity) {
|
||||||
|
this._entities.push(entity);
|
||||||
|
this.onAdded(entity);
|
||||||
|
};
|
||||||
|
EntitySystem.prototype.onAdded = function (entity) {
|
||||||
|
};
|
||||||
|
EntitySystem.prototype.remove = function (entity) {
|
||||||
|
this._entities.remove(entity);
|
||||||
|
this.onRemoved(entity);
|
||||||
|
};
|
||||||
|
EntitySystem.prototype.onRemoved = function (entity) {
|
||||||
|
};
|
||||||
EntitySystem.prototype.update = function () {
|
EntitySystem.prototype.update = function () {
|
||||||
this.begin();
|
this.begin();
|
||||||
this.process(this._entities);
|
this.process(this._entities);
|
||||||
@@ -679,12 +710,231 @@ var EntityProcessingSystem = (function (_super) {
|
|||||||
};
|
};
|
||||||
return EntityProcessingSystem;
|
return EntityProcessingSystem;
|
||||||
}(EntitySystem));
|
}(EntitySystem));
|
||||||
|
var BitSet = (function () {
|
||||||
|
function BitSet(nbits) {
|
||||||
|
if (nbits === void 0) { nbits = 64; }
|
||||||
|
var length = nbits >> 6;
|
||||||
|
if ((nbits & BitSet.LONG_MASK) != 0)
|
||||||
|
length++;
|
||||||
|
this._bits = new Array(length);
|
||||||
|
}
|
||||||
|
BitSet.prototype.and = function (bs) {
|
||||||
|
var max = Math.min(this._bits.length, bs._bits.length);
|
||||||
|
var i;
|
||||||
|
for (var i_1 = 0; i_1 < max; ++i_1)
|
||||||
|
this._bits[i_1] &= bs._bits[i_1];
|
||||||
|
while (i < this._bits.length)
|
||||||
|
this._bits[i++] = 0;
|
||||||
|
};
|
||||||
|
BitSet.prototype.andNot = function (bs) {
|
||||||
|
var i = Math.min(this._bits.length, bs._bits.length);
|
||||||
|
while (--i >= 0)
|
||||||
|
this._bits[i] &= ~bs._bits[i];
|
||||||
|
};
|
||||||
|
BitSet.prototype.cardinality = function () {
|
||||||
|
var card = 0;
|
||||||
|
for (var i = this._bits.length - 1; i >= 0; i--) {
|
||||||
|
var a = this._bits[i];
|
||||||
|
if (a == 0)
|
||||||
|
continue;
|
||||||
|
if (a == -1) {
|
||||||
|
card += 64;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
a = ((a >> 1) & 0x5555555555555555) + (a & 0x5555555555555555);
|
||||||
|
a = ((a >> 2) & 0x3333333333333333) + (a & 0x3333333333333333);
|
||||||
|
var b = ((a >> 32) + a);
|
||||||
|
b = ((b >> 4) & 0x0f0f0f0f) + (b & 0x0f0f0f0f);
|
||||||
|
b = ((b >> 8) & 0x00ff00ff) + (b & 0x00ff00ff);
|
||||||
|
card += ((b >> 16) & 0x0000ffff) + (b & 0x0000ffff);
|
||||||
|
}
|
||||||
|
return card;
|
||||||
|
};
|
||||||
|
BitSet.prototype.clear = function (pos) {
|
||||||
|
if (pos != undefined) {
|
||||||
|
var offset = pos >> 6;
|
||||||
|
this.ensure(offset);
|
||||||
|
this._bits[offset] &= ~(1 << pos);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (var i = 0; i < this._bits.length; i++)
|
||||||
|
this._bits[i] = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
BitSet.prototype.ensure = function (lastElt) {
|
||||||
|
if (lastElt >= this._bits.length) {
|
||||||
|
var nd = new Number[lastElt + 1];
|
||||||
|
nd = this._bits.copyWithin(0, 0, this._bits.length);
|
||||||
|
this._bits = nd;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
BitSet.prototype.get = function (pos) {
|
||||||
|
var offset = pos >> 6;
|
||||||
|
if (offset >= this._bits.length)
|
||||||
|
return false;
|
||||||
|
return (this._bits[offset] & (1 << pos)) != 0;
|
||||||
|
};
|
||||||
|
BitSet.prototype.intersects = function (set) {
|
||||||
|
var i = Math.min(this._bits.length, set._bits.length);
|
||||||
|
while (--i >= 0) {
|
||||||
|
if ((this._bits[i] & set._bits[i]) != 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
BitSet.prototype.isEmpty = function () {
|
||||||
|
for (var i = this._bits.length - 1; i >= 0; i--) {
|
||||||
|
if (this._bits[i] != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
BitSet.prototype.nextSetBit = function (from) {
|
||||||
|
var offset = from >> 6;
|
||||||
|
var mask = 1 << from;
|
||||||
|
while (offset < this._bits.length) {
|
||||||
|
var h = this._bits[offset];
|
||||||
|
do {
|
||||||
|
if ((h & mask) != 0)
|
||||||
|
return from;
|
||||||
|
mask <<= 1;
|
||||||
|
from++;
|
||||||
|
} while (mask != 0);
|
||||||
|
mask = 1;
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
BitSet.prototype.set = function (pos) {
|
||||||
|
var offset = pos >> 6;
|
||||||
|
this.ensure(offset);
|
||||||
|
this._bits[offset] |= 1 << pos;
|
||||||
|
};
|
||||||
|
BitSet.LONG_MASK = 0x3f;
|
||||||
|
return BitSet;
|
||||||
|
}());
|
||||||
|
var ComponentTypeManager = (function () {
|
||||||
|
function ComponentTypeManager() {
|
||||||
|
}
|
||||||
|
ComponentTypeManager.add = function (type) {
|
||||||
|
if (!this._componentTypesMask.has(type))
|
||||||
|
this._componentTypesMask[type] = this._componentTypesMask.size;
|
||||||
|
};
|
||||||
|
ComponentTypeManager.getIndexFor = function (type) {
|
||||||
|
var v = -1;
|
||||||
|
if (!this._componentTypesMask.has(type)) {
|
||||||
|
this.add(type);
|
||||||
|
v = this._componentTypesMask.get(type);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
ComponentTypeManager._componentTypesMask = new Map();
|
||||||
|
return ComponentTypeManager;
|
||||||
|
}());
|
||||||
|
var EntityList = (function () {
|
||||||
|
function EntityList(scene) {
|
||||||
|
this._entitiesToRemove = [];
|
||||||
|
this._entitiesToAdded = [];
|
||||||
|
this._tempEntityList = [];
|
||||||
|
this._entities = [];
|
||||||
|
this.scene = scene;
|
||||||
|
}
|
||||||
|
Object.defineProperty(EntityList.prototype, "count", {
|
||||||
|
get: function () {
|
||||||
|
return this._entities.length;
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
Object.defineProperty(EntityList.prototype, "buffer", {
|
||||||
|
get: function () {
|
||||||
|
return this._entities;
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
EntityList.prototype.add = function (entity) {
|
||||||
|
this._entitiesToAdded.push(entity);
|
||||||
|
};
|
||||||
|
EntityList.prototype.remove = function (entity) {
|
||||||
|
if (this._entitiesToAdded.contains(entity)) {
|
||||||
|
this._entitiesToAdded.remove(entity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this._entitiesToRemove.contains(entity))
|
||||||
|
this._entitiesToRemove.push(entity);
|
||||||
|
};
|
||||||
|
EntityList.prototype.findEntity = function (name) {
|
||||||
|
for (var i = 0; i < this._entities.length; i++) {
|
||||||
|
if (this._entities[i].name == name)
|
||||||
|
return this._entities[i];
|
||||||
|
}
|
||||||
|
return this._entitiesToAdded.firstOrDefault(function (entity) { return entity.name == name; });
|
||||||
|
};
|
||||||
|
EntityList.prototype.update = function () {
|
||||||
|
for (var i = 0; i < this._entities.length; i++) {
|
||||||
|
var entity = this._entities[i];
|
||||||
|
if (entity.enabled)
|
||||||
|
entity.update();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
EntityList.prototype.removeAllEntities = function () {
|
||||||
|
this._entitiesToAdded.length = 0;
|
||||||
|
this.updateLists();
|
||||||
|
for (var i = 0; i < this._entities.length; i++) {
|
||||||
|
this._entities[i].scene = null;
|
||||||
|
}
|
||||||
|
this._entities.length = 0;
|
||||||
|
};
|
||||||
|
EntityList.prototype.updateLists = function () {
|
||||||
|
var _this = this;
|
||||||
|
if (this._entitiesToRemove.length > 0) {
|
||||||
|
var temp = this._entitiesToRemove;
|
||||||
|
this._entitiesToRemove = this._tempEntityList;
|
||||||
|
this._tempEntityList = temp;
|
||||||
|
this._tempEntityList.forEach(function (entity) {
|
||||||
|
_this._entities.remove(entity);
|
||||||
|
entity.scene = null;
|
||||||
|
_this.scene.entityProcessors.forEach(function (processor) { return processor.remove(entity); });
|
||||||
|
});
|
||||||
|
this._tempEntityList.length = 0;
|
||||||
|
}
|
||||||
|
if (this._entitiesToAdded.length > 0) {
|
||||||
|
var temp = this._entitiesToAdded;
|
||||||
|
this._entitiesToAdded = this._tempEntityList;
|
||||||
|
this._tempEntityList = temp;
|
||||||
|
this._tempEntityList.forEach(function (entity) {
|
||||||
|
_this._entities.push(entity);
|
||||||
|
entity.scene = _this.scene;
|
||||||
|
_this.scene.entityProcessors.forEach(function (processor) { return processor.onChanged(entity); });
|
||||||
|
});
|
||||||
|
this._tempEntityList.length = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return EntityList;
|
||||||
|
}());
|
||||||
var Matcher = (function () {
|
var Matcher = (function () {
|
||||||
function Matcher() {
|
function Matcher() {
|
||||||
|
this.allSet = new BitSet();
|
||||||
|
this.exclusionSet = new BitSet();
|
||||||
|
this.oneSet = new BitSet();
|
||||||
}
|
}
|
||||||
Matcher.empty = function () {
|
Matcher.empty = function () {
|
||||||
return new Matcher();
|
return new Matcher();
|
||||||
};
|
};
|
||||||
|
Matcher.prototype.IsIntersted = function (e) {
|
||||||
|
if (!this.allSet.isEmpty()) {
|
||||||
|
for (var i = this.allSet.nextSetBit(0); i >= 0; i = this.allSet.nextSetBit(i + 1)) {
|
||||||
|
if (!e.componentBits.get(i))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!this.exclusionSet.isEmpty() && this.exclusionSet.intersects(e.componentBits))
|
||||||
|
return false;
|
||||||
|
if (!this.oneSet.isEmpty() && !this.oneSet.intersects(e.componentBits))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
return Matcher;
|
return Matcher;
|
||||||
}());
|
}());
|
||||||
var MathHelper = (function () {
|
var MathHelper = (function () {
|
||||||
|
|||||||
2
demo/libs/framework/framework.min.js
vendored
2
demo/libs/framework/framework.min.js
vendored
File diff suppressed because one or more lines are too long
51
source/bin/framework.d.ts
vendored
51
source/bin/framework.d.ts
vendored
@@ -26,6 +26,7 @@ declare abstract class Component {
|
|||||||
abstract initialize(): any;
|
abstract initialize(): any;
|
||||||
update(): void;
|
update(): void;
|
||||||
bind(displayRender: egret.DisplayObject): this;
|
bind(displayRender: egret.DisplayObject): this;
|
||||||
|
registerComponent(): void;
|
||||||
}
|
}
|
||||||
declare class Entity {
|
declare class Entity {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -34,6 +35,7 @@ declare class Entity {
|
|||||||
readonly components: Component[];
|
readonly components: Component[];
|
||||||
private _updateOrder;
|
private _updateOrder;
|
||||||
private _enabled;
|
private _enabled;
|
||||||
|
componentBits: BitSet;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
setEnabled(isEnabled: boolean): this;
|
setEnabled(isEnabled: boolean): this;
|
||||||
constructor(name: string);
|
constructor(name: string);
|
||||||
@@ -47,7 +49,7 @@ declare class Entity {
|
|||||||
}
|
}
|
||||||
declare class Scene extends egret.DisplayObjectContainer {
|
declare class Scene extends egret.DisplayObjectContainer {
|
||||||
camera: Camera;
|
camera: Camera;
|
||||||
entities: Entity[];
|
readonly entities: EntityList;
|
||||||
private _projectionMatrix;
|
private _projectionMatrix;
|
||||||
private _transformMatrix;
|
private _transformMatrix;
|
||||||
private _matrixTransformMatrix;
|
private _matrixTransformMatrix;
|
||||||
@@ -55,7 +57,7 @@ declare class Scene extends egret.DisplayObjectContainer {
|
|||||||
constructor(displayObject: egret.DisplayObject);
|
constructor(displayObject: egret.DisplayObject);
|
||||||
createEntity(name: string): Entity;
|
createEntity(name: string): Entity;
|
||||||
addEntity(entity: Entity): Entity;
|
addEntity(entity: Entity): Entity;
|
||||||
destoryAllEntities(): void;
|
destroyAllEntities(): void;
|
||||||
findEntity(name: string): Entity;
|
findEntity(name: string): Entity;
|
||||||
addEntityProcessor(processor: EntitySystem): EntitySystem;
|
addEntityProcessor(processor: EntitySystem): EntitySystem;
|
||||||
removeEntityProcessor(processor: EntitySystem): void;
|
removeEntityProcessor(processor: EntitySystem): void;
|
||||||
@@ -139,6 +141,11 @@ declare class EntitySystem {
|
|||||||
scene: Scene;
|
scene: Scene;
|
||||||
constructor(matcher?: Matcher);
|
constructor(matcher?: Matcher);
|
||||||
initialize(): void;
|
initialize(): void;
|
||||||
|
onChanged(entity: Entity): void;
|
||||||
|
add(entity: Entity): void;
|
||||||
|
onAdded(entity: Entity): void;
|
||||||
|
remove(entity: Entity): void;
|
||||||
|
onRemoved(entity: Entity): void;
|
||||||
update(): void;
|
update(): void;
|
||||||
lateUpdate(): void;
|
lateUpdate(): void;
|
||||||
protected begin(): void;
|
protected begin(): void;
|
||||||
@@ -153,8 +160,48 @@ declare abstract class EntityProcessingSystem extends EntitySystem {
|
|||||||
protected process(entities: Entity[]): void;
|
protected process(entities: Entity[]): void;
|
||||||
protected lateProcess(entities: Entity[]): void;
|
protected lateProcess(entities: Entity[]): void;
|
||||||
}
|
}
|
||||||
|
declare class BitSet {
|
||||||
|
private static LONG_MASK;
|
||||||
|
private _bits;
|
||||||
|
constructor(nbits?: number);
|
||||||
|
and(bs: BitSet): void;
|
||||||
|
andNot(bs: BitSet): void;
|
||||||
|
cardinality(): number;
|
||||||
|
clear(pos?: number): void;
|
||||||
|
private ensure;
|
||||||
|
get(pos: number): boolean;
|
||||||
|
intersects(set: BitSet): boolean;
|
||||||
|
isEmpty(): boolean;
|
||||||
|
nextSetBit(from: number): number;
|
||||||
|
set(pos: number): void;
|
||||||
|
}
|
||||||
|
declare class ComponentTypeManager {
|
||||||
|
private static _componentTypesMask;
|
||||||
|
static add(type: any): void;
|
||||||
|
static getIndexFor(type: any): number;
|
||||||
|
}
|
||||||
|
declare class EntityList {
|
||||||
|
scene: Scene;
|
||||||
|
private _entitiesToRemove;
|
||||||
|
private _entitiesToAdded;
|
||||||
|
private _tempEntityList;
|
||||||
|
private _entities;
|
||||||
|
constructor(scene: Scene);
|
||||||
|
readonly count: number;
|
||||||
|
readonly buffer: Entity[];
|
||||||
|
add(entity: Entity): void;
|
||||||
|
remove(entity: Entity): void;
|
||||||
|
findEntity(name: string): Entity;
|
||||||
|
update(): void;
|
||||||
|
removeAllEntities(): void;
|
||||||
|
updateLists(): void;
|
||||||
|
}
|
||||||
declare class Matcher {
|
declare class Matcher {
|
||||||
|
protected allSet: BitSet;
|
||||||
|
protected exclusionSet: BitSet;
|
||||||
|
protected oneSet: BitSet;
|
||||||
static empty(): Matcher;
|
static empty(): Matcher;
|
||||||
|
IsIntersted(e: Entity): boolean;
|
||||||
}
|
}
|
||||||
declare class MathHelper {
|
declare class MathHelper {
|
||||||
static toDegrees(radians: number): number;
|
static toDegrees(radians: number): number;
|
||||||
|
|||||||
@@ -264,6 +264,11 @@ var Component = (function () {
|
|||||||
this.displayRender = displayRender;
|
this.displayRender = displayRender;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
Component.prototype.registerComponent = function () {
|
||||||
|
var _this = this;
|
||||||
|
this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this));
|
||||||
|
this.entity.scene.entityProcessors.forEach(function (processor) { return processor.onChanged(_this.entity); });
|
||||||
|
};
|
||||||
return Component;
|
return Component;
|
||||||
}());
|
}());
|
||||||
var Entity = (function () {
|
var Entity = (function () {
|
||||||
@@ -273,6 +278,7 @@ var Entity = (function () {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
this.transform = new Transform(this);
|
this.transform = new Transform(this);
|
||||||
this.components = [];
|
this.components = [];
|
||||||
|
this.componentBits = new BitSet();
|
||||||
}
|
}
|
||||||
Object.defineProperty(Entity.prototype, "enabled", {
|
Object.defineProperty(Entity.prototype, "enabled", {
|
||||||
get: function () {
|
get: function () {
|
||||||
@@ -310,7 +316,8 @@ var Entity = (function () {
|
|||||||
};
|
};
|
||||||
Entity.prototype.attachToScene = function (newScene) {
|
Entity.prototype.attachToScene = function (newScene) {
|
||||||
this.scene = newScene;
|
this.scene = newScene;
|
||||||
newScene.entities.push(this);
|
newScene.entities.add(this);
|
||||||
|
this.components.forEach(function (component) { return component.registerComponent(); });
|
||||||
for (var i = 0; i < this.transform.childCount; i++) {
|
for (var i = 0; i < this.transform.childCount; i++) {
|
||||||
this.transform.getChild(i).entity.attachToScene(newScene);
|
this.transform.getChild(i).entity.attachToScene(newScene);
|
||||||
}
|
}
|
||||||
@@ -342,10 +349,10 @@ var Scene = (function (_super) {
|
|||||||
__extends(Scene, _super);
|
__extends(Scene, _super);
|
||||||
function Scene(displayObject) {
|
function Scene(displayObject) {
|
||||||
var _this = _super.call(this) || this;
|
var _this = _super.call(this) || this;
|
||||||
_this.entities = [];
|
|
||||||
displayObject.stage.addChild(_this);
|
displayObject.stage.addChild(_this);
|
||||||
_this._projectionMatrix = new Matrix2D(0, 0, 0, 0, 0, 0);
|
_this._projectionMatrix = new Matrix2D(0, 0, 0, 0, 0, 0);
|
||||||
_this.entityProcessors = [];
|
_this.entityProcessors = [];
|
||||||
|
_this.entities = new EntityList(_this);
|
||||||
_this.addEventListener(egret.Event.ACTIVATE, _this.onActive, _this);
|
_this.addEventListener(egret.Event.ACTIVATE, _this.onActive, _this);
|
||||||
_this.addEventListener(egret.Event.DEACTIVATE, _this.onDeactive, _this);
|
_this.addEventListener(egret.Event.DEACTIVATE, _this.onDeactive, _this);
|
||||||
_this.addEventListener(egret.Event.ENTER_FRAME, _this.update, _this);
|
_this.addEventListener(egret.Event.ENTER_FRAME, _this.update, _this);
|
||||||
@@ -357,15 +364,19 @@ var Scene = (function (_super) {
|
|||||||
return this.addEntity(entity);
|
return this.addEntity(entity);
|
||||||
};
|
};
|
||||||
Scene.prototype.addEntity = function (entity) {
|
Scene.prototype.addEntity = function (entity) {
|
||||||
this.entities.push(entity);
|
this.entities.add(entity);
|
||||||
entity.scene = this;
|
entity.scene = this;
|
||||||
|
for (var i = 0; i < entity.transform.childCount; i++)
|
||||||
|
this.addEntity(entity.transform.getChild(i).entity);
|
||||||
return entity;
|
return entity;
|
||||||
};
|
};
|
||||||
Scene.prototype.destoryAllEntities = function () {
|
Scene.prototype.destroyAllEntities = function () {
|
||||||
this.entities.forEach(function (entity) { return entity.destory(); });
|
for (var i = 0; i < this.entities.count; i++) {
|
||||||
|
this.entities.buffer[i].destory();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Scene.prototype.findEntity = function (name) {
|
Scene.prototype.findEntity = function (name) {
|
||||||
return this.entities.firstOrDefault(function (entity) { return entity.name == name; });
|
return this.entities.findEntity(name);
|
||||||
};
|
};
|
||||||
Scene.prototype.addEntityProcessor = function (processor) {
|
Scene.prototype.addEntityProcessor = function (processor) {
|
||||||
processor.scene = this;
|
processor.scene = this;
|
||||||
@@ -391,8 +402,9 @@ var Scene = (function (_super) {
|
|||||||
Scene.prototype.onDeactive = function () {
|
Scene.prototype.onDeactive = function () {
|
||||||
};
|
};
|
||||||
Scene.prototype.update = function () {
|
Scene.prototype.update = function () {
|
||||||
|
this.entities.updateLists();
|
||||||
this.entityProcessors.forEach(function (processor) { return processor.update(); });
|
this.entityProcessors.forEach(function (processor) { return processor.update(); });
|
||||||
this.entities.forEach(function (entity) { return entity.update(); });
|
this.entities.update();
|
||||||
this.entityProcessors.forEach(function (processor) { return processor.lateUpdate(); });
|
this.entityProcessors.forEach(function (processor) { return processor.lateUpdate(); });
|
||||||
};
|
};
|
||||||
Scene.prototype.prepRenderState = function () {
|
Scene.prototype.prepRenderState = function () {
|
||||||
@@ -406,8 +418,7 @@ var Scene = (function (_super) {
|
|||||||
this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
||||||
this.camera.destory();
|
this.camera.destory();
|
||||||
this.camera = null;
|
this.camera = null;
|
||||||
this.entities.forEach(function (entity) { return entity.destory(); });
|
this.entities.removeAllEntities();
|
||||||
this.entities.length = 0;
|
|
||||||
};
|
};
|
||||||
return Scene;
|
return Scene;
|
||||||
}(egret.DisplayObjectContainer));
|
}(egret.DisplayObjectContainer));
|
||||||
@@ -599,7 +610,7 @@ var Camera = (function (_super) {
|
|||||||
};
|
};
|
||||||
Camera.prototype.update = function () {
|
Camera.prototype.update = function () {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
SceneManager.getActiveScene().entities.forEach(function (entity) { return entity.components.forEach(function (component) {
|
SceneManager.getActiveScene().entities.buffer.forEach(function (entity) { return entity.components.forEach(function (component) {
|
||||||
if (component.displayRender) {
|
if (component.displayRender) {
|
||||||
var has = _this.entity.scene.$children.indexOf(component.displayRender);
|
var has = _this.entity.scene.$children.indexOf(component.displayRender);
|
||||||
if (has == -1) {
|
if (has == -1) {
|
||||||
@@ -644,6 +655,26 @@ var EntitySystem = (function () {
|
|||||||
});
|
});
|
||||||
EntitySystem.prototype.initialize = function () {
|
EntitySystem.prototype.initialize = function () {
|
||||||
};
|
};
|
||||||
|
EntitySystem.prototype.onChanged = function (entity) {
|
||||||
|
var contains = this._entities.contains(entity);
|
||||||
|
var interest = this._matcher.IsIntersted(entity);
|
||||||
|
if (interest && !contains)
|
||||||
|
this.add(entity);
|
||||||
|
else if (!interest && contains)
|
||||||
|
this.remove(entity);
|
||||||
|
};
|
||||||
|
EntitySystem.prototype.add = function (entity) {
|
||||||
|
this._entities.push(entity);
|
||||||
|
this.onAdded(entity);
|
||||||
|
};
|
||||||
|
EntitySystem.prototype.onAdded = function (entity) {
|
||||||
|
};
|
||||||
|
EntitySystem.prototype.remove = function (entity) {
|
||||||
|
this._entities.remove(entity);
|
||||||
|
this.onRemoved(entity);
|
||||||
|
};
|
||||||
|
EntitySystem.prototype.onRemoved = function (entity) {
|
||||||
|
};
|
||||||
EntitySystem.prototype.update = function () {
|
EntitySystem.prototype.update = function () {
|
||||||
this.begin();
|
this.begin();
|
||||||
this.process(this._entities);
|
this.process(this._entities);
|
||||||
@@ -679,12 +710,231 @@ var EntityProcessingSystem = (function (_super) {
|
|||||||
};
|
};
|
||||||
return EntityProcessingSystem;
|
return EntityProcessingSystem;
|
||||||
}(EntitySystem));
|
}(EntitySystem));
|
||||||
|
var BitSet = (function () {
|
||||||
|
function BitSet(nbits) {
|
||||||
|
if (nbits === void 0) { nbits = 64; }
|
||||||
|
var length = nbits >> 6;
|
||||||
|
if ((nbits & BitSet.LONG_MASK) != 0)
|
||||||
|
length++;
|
||||||
|
this._bits = new Array(length);
|
||||||
|
}
|
||||||
|
BitSet.prototype.and = function (bs) {
|
||||||
|
var max = Math.min(this._bits.length, bs._bits.length);
|
||||||
|
var i;
|
||||||
|
for (var i_1 = 0; i_1 < max; ++i_1)
|
||||||
|
this._bits[i_1] &= bs._bits[i_1];
|
||||||
|
while (i < this._bits.length)
|
||||||
|
this._bits[i++] = 0;
|
||||||
|
};
|
||||||
|
BitSet.prototype.andNot = function (bs) {
|
||||||
|
var i = Math.min(this._bits.length, bs._bits.length);
|
||||||
|
while (--i >= 0)
|
||||||
|
this._bits[i] &= ~bs._bits[i];
|
||||||
|
};
|
||||||
|
BitSet.prototype.cardinality = function () {
|
||||||
|
var card = 0;
|
||||||
|
for (var i = this._bits.length - 1; i >= 0; i--) {
|
||||||
|
var a = this._bits[i];
|
||||||
|
if (a == 0)
|
||||||
|
continue;
|
||||||
|
if (a == -1) {
|
||||||
|
card += 64;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
a = ((a >> 1) & 0x5555555555555555) + (a & 0x5555555555555555);
|
||||||
|
a = ((a >> 2) & 0x3333333333333333) + (a & 0x3333333333333333);
|
||||||
|
var b = ((a >> 32) + a);
|
||||||
|
b = ((b >> 4) & 0x0f0f0f0f) + (b & 0x0f0f0f0f);
|
||||||
|
b = ((b >> 8) & 0x00ff00ff) + (b & 0x00ff00ff);
|
||||||
|
card += ((b >> 16) & 0x0000ffff) + (b & 0x0000ffff);
|
||||||
|
}
|
||||||
|
return card;
|
||||||
|
};
|
||||||
|
BitSet.prototype.clear = function (pos) {
|
||||||
|
if (pos != undefined) {
|
||||||
|
var offset = pos >> 6;
|
||||||
|
this.ensure(offset);
|
||||||
|
this._bits[offset] &= ~(1 << pos);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (var i = 0; i < this._bits.length; i++)
|
||||||
|
this._bits[i] = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
BitSet.prototype.ensure = function (lastElt) {
|
||||||
|
if (lastElt >= this._bits.length) {
|
||||||
|
var nd = new Number[lastElt + 1];
|
||||||
|
nd = this._bits.copyWithin(0, 0, this._bits.length);
|
||||||
|
this._bits = nd;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
BitSet.prototype.get = function (pos) {
|
||||||
|
var offset = pos >> 6;
|
||||||
|
if (offset >= this._bits.length)
|
||||||
|
return false;
|
||||||
|
return (this._bits[offset] & (1 << pos)) != 0;
|
||||||
|
};
|
||||||
|
BitSet.prototype.intersects = function (set) {
|
||||||
|
var i = Math.min(this._bits.length, set._bits.length);
|
||||||
|
while (--i >= 0) {
|
||||||
|
if ((this._bits[i] & set._bits[i]) != 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
BitSet.prototype.isEmpty = function () {
|
||||||
|
for (var i = this._bits.length - 1; i >= 0; i--) {
|
||||||
|
if (this._bits[i] != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
BitSet.prototype.nextSetBit = function (from) {
|
||||||
|
var offset = from >> 6;
|
||||||
|
var mask = 1 << from;
|
||||||
|
while (offset < this._bits.length) {
|
||||||
|
var h = this._bits[offset];
|
||||||
|
do {
|
||||||
|
if ((h & mask) != 0)
|
||||||
|
return from;
|
||||||
|
mask <<= 1;
|
||||||
|
from++;
|
||||||
|
} while (mask != 0);
|
||||||
|
mask = 1;
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
BitSet.prototype.set = function (pos) {
|
||||||
|
var offset = pos >> 6;
|
||||||
|
this.ensure(offset);
|
||||||
|
this._bits[offset] |= 1 << pos;
|
||||||
|
};
|
||||||
|
BitSet.LONG_MASK = 0x3f;
|
||||||
|
return BitSet;
|
||||||
|
}());
|
||||||
|
var ComponentTypeManager = (function () {
|
||||||
|
function ComponentTypeManager() {
|
||||||
|
}
|
||||||
|
ComponentTypeManager.add = function (type) {
|
||||||
|
if (!this._componentTypesMask.has(type))
|
||||||
|
this._componentTypesMask[type] = this._componentTypesMask.size;
|
||||||
|
};
|
||||||
|
ComponentTypeManager.getIndexFor = function (type) {
|
||||||
|
var v = -1;
|
||||||
|
if (!this._componentTypesMask.has(type)) {
|
||||||
|
this.add(type);
|
||||||
|
v = this._componentTypesMask.get(type);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
ComponentTypeManager._componentTypesMask = new Map();
|
||||||
|
return ComponentTypeManager;
|
||||||
|
}());
|
||||||
|
var EntityList = (function () {
|
||||||
|
function EntityList(scene) {
|
||||||
|
this._entitiesToRemove = [];
|
||||||
|
this._entitiesToAdded = [];
|
||||||
|
this._tempEntityList = [];
|
||||||
|
this._entities = [];
|
||||||
|
this.scene = scene;
|
||||||
|
}
|
||||||
|
Object.defineProperty(EntityList.prototype, "count", {
|
||||||
|
get: function () {
|
||||||
|
return this._entities.length;
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
Object.defineProperty(EntityList.prototype, "buffer", {
|
||||||
|
get: function () {
|
||||||
|
return this._entities;
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
EntityList.prototype.add = function (entity) {
|
||||||
|
this._entitiesToAdded.push(entity);
|
||||||
|
};
|
||||||
|
EntityList.prototype.remove = function (entity) {
|
||||||
|
if (this._entitiesToAdded.contains(entity)) {
|
||||||
|
this._entitiesToAdded.remove(entity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this._entitiesToRemove.contains(entity))
|
||||||
|
this._entitiesToRemove.push(entity);
|
||||||
|
};
|
||||||
|
EntityList.prototype.findEntity = function (name) {
|
||||||
|
for (var i = 0; i < this._entities.length; i++) {
|
||||||
|
if (this._entities[i].name == name)
|
||||||
|
return this._entities[i];
|
||||||
|
}
|
||||||
|
return this._entitiesToAdded.firstOrDefault(function (entity) { return entity.name == name; });
|
||||||
|
};
|
||||||
|
EntityList.prototype.update = function () {
|
||||||
|
for (var i = 0; i < this._entities.length; i++) {
|
||||||
|
var entity = this._entities[i];
|
||||||
|
if (entity.enabled)
|
||||||
|
entity.update();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
EntityList.prototype.removeAllEntities = function () {
|
||||||
|
this._entitiesToAdded.length = 0;
|
||||||
|
this.updateLists();
|
||||||
|
for (var i = 0; i < this._entities.length; i++) {
|
||||||
|
this._entities[i].scene = null;
|
||||||
|
}
|
||||||
|
this._entities.length = 0;
|
||||||
|
};
|
||||||
|
EntityList.prototype.updateLists = function () {
|
||||||
|
var _this = this;
|
||||||
|
if (this._entitiesToRemove.length > 0) {
|
||||||
|
var temp = this._entitiesToRemove;
|
||||||
|
this._entitiesToRemove = this._tempEntityList;
|
||||||
|
this._tempEntityList = temp;
|
||||||
|
this._tempEntityList.forEach(function (entity) {
|
||||||
|
_this._entities.remove(entity);
|
||||||
|
entity.scene = null;
|
||||||
|
_this.scene.entityProcessors.forEach(function (processor) { return processor.remove(entity); });
|
||||||
|
});
|
||||||
|
this._tempEntityList.length = 0;
|
||||||
|
}
|
||||||
|
if (this._entitiesToAdded.length > 0) {
|
||||||
|
var temp = this._entitiesToAdded;
|
||||||
|
this._entitiesToAdded = this._tempEntityList;
|
||||||
|
this._tempEntityList = temp;
|
||||||
|
this._tempEntityList.forEach(function (entity) {
|
||||||
|
_this._entities.push(entity);
|
||||||
|
entity.scene = _this.scene;
|
||||||
|
_this.scene.entityProcessors.forEach(function (processor) { return processor.onChanged(entity); });
|
||||||
|
});
|
||||||
|
this._tempEntityList.length = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return EntityList;
|
||||||
|
}());
|
||||||
var Matcher = (function () {
|
var Matcher = (function () {
|
||||||
function Matcher() {
|
function Matcher() {
|
||||||
|
this.allSet = new BitSet();
|
||||||
|
this.exclusionSet = new BitSet();
|
||||||
|
this.oneSet = new BitSet();
|
||||||
}
|
}
|
||||||
Matcher.empty = function () {
|
Matcher.empty = function () {
|
||||||
return new Matcher();
|
return new Matcher();
|
||||||
};
|
};
|
||||||
|
Matcher.prototype.IsIntersted = function (e) {
|
||||||
|
if (!this.allSet.isEmpty()) {
|
||||||
|
for (var i = this.allSet.nextSetBit(0); i >= 0; i = this.allSet.nextSetBit(i + 1)) {
|
||||||
|
if (!e.componentBits.get(i))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!this.exclusionSet.isEmpty() && this.exclusionSet.intersects(e.componentBits))
|
||||||
|
return false;
|
||||||
|
if (!this.oneSet.isEmpty() && !this.oneSet.intersects(e.componentBits))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
return Matcher;
|
return Matcher;
|
||||||
}());
|
}());
|
||||||
var MathHelper = (function () {
|
var MathHelper = (function () {
|
||||||
|
|||||||
2
source/bin/framework.min.js
vendored
2
source/bin/framework.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -30,4 +30,10 @@ abstract class Component {
|
|||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 内部使用 运行时不应该调用 */
|
||||||
|
public registerComponent(){
|
||||||
|
this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this));
|
||||||
|
this.entity.scene.entityProcessors.forEach(processor => processor.onChanged(this.entity));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -20,7 +20,7 @@ class Camera extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public update(){
|
public update(){
|
||||||
SceneManager.getActiveScene().entities.forEach(entity => entity.components.forEach(component => {
|
SceneManager.getActiveScene().entities.buffer.forEach(entity => entity.components.forEach(component => {
|
||||||
if (component.displayRender){
|
if (component.displayRender){
|
||||||
let has = this.entity.scene.$children.indexOf(component.displayRender)
|
let has = this.entity.scene.$children.indexOf(component.displayRender)
|
||||||
if (has == -1){
|
if (has == -1){
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ class Entity {
|
|||||||
private _updateOrder: number = 0;
|
private _updateOrder: number = 0;
|
||||||
private _enabled: boolean = true;
|
private _enabled: boolean = true;
|
||||||
|
|
||||||
|
public componentBits: BitSet;
|
||||||
|
|
||||||
public get enabled(){
|
public get enabled(){
|
||||||
return this._enabled;
|
return this._enabled;
|
||||||
}
|
}
|
||||||
@@ -29,6 +31,7 @@ class Entity {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
this.transform = new Transform(this);
|
this.transform = new Transform(this);
|
||||||
this.components = [];
|
this.components = [];
|
||||||
|
this.componentBits = new BitSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public get updateOrder(){
|
public get updateOrder(){
|
||||||
@@ -52,7 +55,8 @@ class Entity {
|
|||||||
|
|
||||||
public attachToScene(newScene: Scene){
|
public attachToScene(newScene: Scene){
|
||||||
this.scene = newScene;
|
this.scene = newScene;
|
||||||
newScene.entities.push(this);
|
newScene.entities.add(this);
|
||||||
|
this.components.forEach(component => component.registerComponent());
|
||||||
|
|
||||||
for (let i = 0; i < this.transform.childCount; i ++){
|
for (let i = 0; i < this.transform.childCount; i ++){
|
||||||
this.transform.getChild(i).entity.attachToScene(newScene);
|
this.transform.getChild(i).entity.attachToScene(newScene);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/** 场景 */
|
/** 场景 */
|
||||||
class Scene extends egret.DisplayObjectContainer {
|
class Scene extends egret.DisplayObjectContainer {
|
||||||
public camera: Camera;
|
public camera: Camera;
|
||||||
public entities: Entity[] = [];
|
public readonly entities: EntityList;
|
||||||
|
|
||||||
private _projectionMatrix: Matrix2D;
|
private _projectionMatrix: Matrix2D;
|
||||||
private _transformMatrix: Matrix2D;
|
private _transformMatrix: Matrix2D;
|
||||||
@@ -14,6 +14,7 @@ class Scene extends egret.DisplayObjectContainer {
|
|||||||
displayObject.stage.addChild(this);
|
displayObject.stage.addChild(this);
|
||||||
this._projectionMatrix = new Matrix2D(0, 0, 0, 0, 0, 0);
|
this._projectionMatrix = new Matrix2D(0, 0, 0, 0, 0, 0);
|
||||||
this.entityProcessors = [];
|
this.entityProcessors = [];
|
||||||
|
this.entities = new EntityList(this);
|
||||||
|
|
||||||
this.addEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
this.addEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
||||||
this.addEventListener(egret.Event.DEACTIVATE, this.onDeactive, this);
|
this.addEventListener(egret.Event.DEACTIVATE, this.onDeactive, this);
|
||||||
@@ -27,18 +28,23 @@ class Scene extends egret.DisplayObjectContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public addEntity(entity: Entity){
|
public addEntity(entity: Entity){
|
||||||
this.entities.push(entity);
|
this.entities.add(entity);
|
||||||
entity.scene = this;
|
entity.scene = this;
|
||||||
|
|
||||||
|
for (let i = 0; i < entity.transform.childCount; i ++)
|
||||||
|
this.addEntity(entity.transform.getChild(i).entity);
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public destoryAllEntities(){
|
public destroyAllEntities(){
|
||||||
this.entities.forEach(entity => entity.destory());
|
for (let i = 0; i < this.entities.count; i ++){
|
||||||
|
this.entities.buffer[i].destory();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public findEntity(name: string): Entity{
|
public findEntity(name: string): Entity{
|
||||||
return this.entities.firstOrDefault(entity => entity.name == name);
|
return this.entities.findEntity(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,7 +80,7 @@ class Scene extends egret.DisplayObjectContainer {
|
|||||||
|
|
||||||
/** 场景激活 */
|
/** 场景激活 */
|
||||||
public onActive(){
|
public onActive(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 场景失去焦点 */
|
/** 场景失去焦点 */
|
||||||
@@ -83,8 +89,10 @@ class Scene extends egret.DisplayObjectContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public update(){
|
public update(){
|
||||||
|
this.entities.updateLists();
|
||||||
|
|
||||||
this.entityProcessors.forEach(processor => processor.update());
|
this.entityProcessors.forEach(processor => processor.update());
|
||||||
this.entities.forEach(entity => entity.update());
|
this.entities.update();
|
||||||
this.entityProcessors.forEach(processor => processor.lateUpdate());
|
this.entityProcessors.forEach(processor => processor.lateUpdate());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +111,6 @@ class Scene extends egret.DisplayObjectContainer {
|
|||||||
this.camera.destory();
|
this.camera.destory();
|
||||||
this.camera = null;
|
this.camera = null;
|
||||||
|
|
||||||
this.entities.forEach(entity => entity.destory());
|
this.entities.removeAllEntities();
|
||||||
this.entities.length = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,34 @@ class EntitySystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public initialize(){
|
public initialize(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public onChanged(entity: Entity){
|
||||||
|
let contains = this._entities.contains(entity);
|
||||||
|
let interest = this._matcher.IsIntersted(entity);
|
||||||
|
|
||||||
|
if (interest && !contains)
|
||||||
|
this.add(entity);
|
||||||
|
else if(!interest && contains)
|
||||||
|
this.remove(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public add(entity: Entity){
|
||||||
|
this._entities.push(entity);
|
||||||
|
this.onAdded(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public onAdded(entity: Entity){
|
||||||
|
}
|
||||||
|
|
||||||
|
public remove(entity: Entity){
|
||||||
|
this._entities.remove(entity);
|
||||||
|
this.onRemoved(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public onRemoved(entity: Entity){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public update(){
|
public update(){
|
||||||
|
|||||||
129
source/src/ECS/Utils/BitSet.ts
Normal file
129
source/src/ECS/Utils/BitSet.ts
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
/**
|
||||||
|
* 这个类可以从两方面来考虑。你可以把它看成一个位向量或者一组非负整数。这个名字有点误导人。
|
||||||
|
*
|
||||||
|
* 它是由一个位向量实现的,但同样可以把它看成是一个非负整数的集合;集合中的每个整数由对应索引处的集合位表示。该结构的大小由集合中的最大整数决定。
|
||||||
|
*/
|
||||||
|
class BitSet{
|
||||||
|
private static LONG_MASK: number = 0x3f;
|
||||||
|
private _bits: number[];
|
||||||
|
|
||||||
|
constructor(nbits: number = 64){
|
||||||
|
let length = nbits >> 6;
|
||||||
|
if ((nbits & BitSet.LONG_MASK) != 0)
|
||||||
|
length ++;
|
||||||
|
|
||||||
|
this._bits = new Array(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public and(bs: BitSet){
|
||||||
|
let max = Math.min(this._bits.length, bs._bits.length);
|
||||||
|
let i;
|
||||||
|
for (let i = 0; i < max; ++i)
|
||||||
|
this._bits[i] &= bs._bits[i];
|
||||||
|
|
||||||
|
while (i < this._bits.length)
|
||||||
|
this._bits[i ++] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public andNot(bs: BitSet){
|
||||||
|
let i = Math.min(this._bits.length, bs._bits.length);
|
||||||
|
while(--i >= 0)
|
||||||
|
this._bits[i] &= ~bs._bits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
public cardinality(): number{
|
||||||
|
let card = 0;
|
||||||
|
for (let i = this._bits.length - 1; i >= 0; i --){
|
||||||
|
let a = this._bits[i];
|
||||||
|
|
||||||
|
if (a == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (a == -1){
|
||||||
|
card += 64;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = ((a >> 1) & 0x5555555555555555) + (a & 0x5555555555555555);
|
||||||
|
a = ((a >> 2) & 0x3333333333333333) + (a & 0x3333333333333333);
|
||||||
|
let b = ((a >> 32) + a);
|
||||||
|
b = ((b >> 4) & 0x0f0f0f0f) + (b & 0x0f0f0f0f);
|
||||||
|
b = ((b >> 8) & 0x00ff00ff) + (b & 0x00ff00ff);
|
||||||
|
card += ((b >> 16) & 0x0000ffff) + (b & 0x0000ffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return card;
|
||||||
|
}
|
||||||
|
|
||||||
|
public clear(pos?: number){
|
||||||
|
if (pos != undefined){
|
||||||
|
let offset = pos >> 6;
|
||||||
|
this.ensure(offset);
|
||||||
|
this._bits[offset] &= ~(1 << pos);
|
||||||
|
}else{
|
||||||
|
for (let i = 0; i < this._bits.length; i ++)
|
||||||
|
this._bits[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ensure(lastElt: number){
|
||||||
|
if (lastElt >= this._bits.length){
|
||||||
|
let nd = new Number[lastElt + 1];
|
||||||
|
nd = this._bits.copyWithin(0, 0, this._bits.length);
|
||||||
|
this._bits = nd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public get(pos: number): boolean{
|
||||||
|
let offset = pos >> 6;
|
||||||
|
if (offset >= this._bits.length)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return (this._bits[offset] & (1 << pos)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public intersects(set: BitSet){
|
||||||
|
let i = Math.min(this._bits.length, set._bits.length);
|
||||||
|
while (--i >= 0){
|
||||||
|
if ((this._bits[i] & set._bits[i]) != 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public isEmpty(): boolean{
|
||||||
|
for (let i = this._bits.length - 1; i >= 0; i --){
|
||||||
|
if (this._bits[i] != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public nextSetBit(from: number){
|
||||||
|
let offset = from >> 6;
|
||||||
|
let mask = 1 << from;
|
||||||
|
while (offset < this._bits.length){
|
||||||
|
let h = this._bits[offset];
|
||||||
|
do {
|
||||||
|
if ((h & mask) != 0)
|
||||||
|
return from;
|
||||||
|
|
||||||
|
mask <<= 1;
|
||||||
|
from ++;
|
||||||
|
} while (mask != 0);
|
||||||
|
|
||||||
|
mask = 1;
|
||||||
|
offset ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set(pos: number){
|
||||||
|
let offset = pos >> 6;
|
||||||
|
this.ensure(offset);
|
||||||
|
this._bits[offset] |= 1 << pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
source/src/ECS/Utils/ComponentTypeManager.ts
Normal file
18
source/src/ECS/Utils/ComponentTypeManager.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
class ComponentTypeManager{
|
||||||
|
private static _componentTypesMask: Map<any, number> = new Map<any, number>();
|
||||||
|
|
||||||
|
public static add(type){
|
||||||
|
if (!this._componentTypesMask.has(type))
|
||||||
|
this._componentTypesMask[type] = this._componentTypesMask.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getIndexFor(type){
|
||||||
|
let v = -1;
|
||||||
|
if (!this._componentTypesMask.has(type)){
|
||||||
|
this.add(type);
|
||||||
|
v = this._componentTypesMask.get(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
92
source/src/ECS/Utils/EntityList.ts
Normal file
92
source/src/ECS/Utils/EntityList.ts
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
class EntityList{
|
||||||
|
public scene: Scene;
|
||||||
|
private _entitiesToRemove: Entity[] = [];
|
||||||
|
private _entitiesToAdded: Entity[] = [];
|
||||||
|
private _tempEntityList: Entity[] = [];
|
||||||
|
private _entities: Entity[] = [];
|
||||||
|
|
||||||
|
constructor(scene: Scene){
|
||||||
|
this.scene = scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get count(){
|
||||||
|
return this._entities.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get buffer(){
|
||||||
|
return this._entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public add(entity: Entity){
|
||||||
|
this._entitiesToAdded.push(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public remove(entity: Entity){
|
||||||
|
if (this._entitiesToAdded.contains(entity)){
|
||||||
|
this._entitiesToAdded.remove(entity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._entitiesToRemove.contains(entity))
|
||||||
|
this._entitiesToRemove.push(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public findEntity(name: string){
|
||||||
|
for (let i = 0; i < this._entities.length; i ++){
|
||||||
|
if (this._entities[i].name == name)
|
||||||
|
return this._entities[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._entitiesToAdded.firstOrDefault(entity => entity.name == name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public update(){
|
||||||
|
for (let i = 0; i < this._entities.length; i++){
|
||||||
|
let entity = this._entities[i];
|
||||||
|
if (entity.enabled)
|
||||||
|
entity.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeAllEntities(){
|
||||||
|
this._entitiesToAdded.length = 0;
|
||||||
|
|
||||||
|
this.updateLists();
|
||||||
|
|
||||||
|
for (let i = 0; i < this._entities.length; i ++){
|
||||||
|
this._entities[i].scene = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._entities.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public updateLists(){
|
||||||
|
if (this._entitiesToRemove.length > 0){
|
||||||
|
let temp = this._entitiesToRemove;
|
||||||
|
this._entitiesToRemove = this._tempEntityList;
|
||||||
|
this._tempEntityList = temp;
|
||||||
|
this._tempEntityList.forEach(entity => {
|
||||||
|
this._entities.remove(entity);
|
||||||
|
entity.scene = null;
|
||||||
|
|
||||||
|
this.scene.entityProcessors.forEach(processor => processor.remove(entity));
|
||||||
|
});
|
||||||
|
|
||||||
|
this._tempEntityList.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._entitiesToAdded.length > 0){
|
||||||
|
let temp = this._entitiesToAdded;
|
||||||
|
this._entitiesToAdded = this._tempEntityList;
|
||||||
|
this._tempEntityList = temp;
|
||||||
|
this._tempEntityList.forEach(entity => {
|
||||||
|
this._entities.push(entity);
|
||||||
|
entity.scene = this.scene;
|
||||||
|
|
||||||
|
this.scene.entityProcessors.forEach(processor => processor.onChanged(entity));
|
||||||
|
});
|
||||||
|
|
||||||
|
this._tempEntityList.length = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,26 @@
|
|||||||
class Matcher{
|
class Matcher{
|
||||||
|
protected allSet = new BitSet();
|
||||||
|
protected exclusionSet = new BitSet();
|
||||||
|
protected oneSet = new BitSet();
|
||||||
|
|
||||||
public static empty(){
|
public static empty(){
|
||||||
return new Matcher();
|
return new Matcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IsIntersted(e: Entity){
|
||||||
|
if (!this.allSet.isEmpty()){
|
||||||
|
for (let i = this.allSet.nextSetBit(0); i >= 0; i = this.allSet.nextSetBit(i + 1)){
|
||||||
|
if (!e.componentBits.get(i))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.exclusionSet.isEmpty() && this.exclusionSet.intersects(e.componentBits))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!this.oneSet.isEmpty() && !this.oneSet.intersects(e.componentBits))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user