优化entitylist

This commit is contained in:
yhh
2020-11-26 20:02:53 +08:00
parent ae2cfdafdd
commit 6113fd9986
5 changed files with 125 additions and 156 deletions

View File

@@ -270,8 +270,12 @@ declare module es {
}
}
declare module es {
class EntityComparer implements IComparer<Entity> {
compare(self: Entity, other: Entity): number;
}
class Entity {
static _idGenerator: number;
static entityComparer: IComparer<Entity>;
/**
* 当前实体所属的场景
*/
@@ -1220,15 +1224,15 @@ declare module es {
/**
* 场景中添加的实体列表
*/
_entities: Entity[];
_entities: FastList<Entity>;
/**
* 本帧添加的实体列表。用于对实体进行分组,以便我们可以同时处理它们
*/
_entitiesToAdded: Entity[];
_entitiesToAdded: Set<Entity>;
/**
* 本帧被标记为删除的实体列表。用于对实体进行分组,以便我们可以同时处理它们
*/
_entitiesToRemove: Entity[];
_entitiesToRemove: Set<Entity>;
/**
* 标志,用于确定我们是否需要在这一帧中对实体进行排序
*/
@@ -1238,14 +1242,9 @@ declare module es {
*/
_entityDict: Map<number, Entity[]>;
_unsortedTags: Set<number>;
_addToSceneEntityList: Entity[];
/** 是否使用分帧处理 */
frameAllocate: boolean;
/** 每帧最大处理数量 */
maxAllocate: number;
constructor(scene: Scene);
readonly count: number;
readonly buffer: Entity[];
readonly buffer: FastList<Entity>;
markEntityListUnsorted(): void;
markTagUnsorted(tag: number): void;
/**
@@ -1272,13 +1271,11 @@ declare module es {
removeFromTagList(entity: Entity): void;
update(): void;
updateLists(): void;
/** 每次添加一个实体到场景 */
private perEntityAddToScene;
/**
* 返回第一个找到的名字为name的实体。如果没有找到则返回null
* @param name
*/
findEntity(name: string): Entity;
findEntity(name: string): any;
/**
* 返回带有标签的所有实体的列表。如果没有实体有标签,则返回一个空列表。
* 返回的List可以通过ListPool.free放回池中

View File

@@ -642,6 +642,18 @@ var es;
})(es || (es = {}));
var es;
(function (es) {
var EntityComparer = /** @class */ (function () {
function EntityComparer() {
}
EntityComparer.prototype.compare = function (self, other) {
var compare = self.updateOrder - other.updateOrder;
if (compare == 0)
compare = self.id - other.id;
return compare;
};
return EntityComparer;
}());
es.EntityComparer = EntityComparer;
var Entity = /** @class */ (function () {
function Entity(name) {
/**
@@ -1017,6 +1029,7 @@ var es;
return "[Entity: name: " + this.name + ", tag: " + this.tag + ", enabled: " + this.enabled + ", depth: " + this.updateOrder + "]";
};
Entity._idGenerator = 0;
Entity.entityComparer = new EntityComparer();
return Entity;
}());
es.Entity = Entity;
@@ -2893,25 +2906,20 @@ var es;
/**
* 场景中添加的实体列表
*/
this._entities = [];
this._entities = new es.FastList();
/**
* 本帧添加的实体列表。用于对实体进行分组,以便我们可以同时处理它们
*/
this._entitiesToAdded = [];
this._entitiesToAdded = new Set();
/**
* 本帧被标记为删除的实体列表。用于对实体进行分组,以便我们可以同时处理它们
*/
this._entitiesToRemove = [];
this._entitiesToRemove = new Set();
/**
* 通过标签跟踪实体,便于检索
*/
this._entityDict = new Map();
this._unsortedTags = new Set();
this._addToSceneEntityList = [];
/** 是否使用分帧处理 */
this.frameAllocate = false;
/** 每帧最大处理数量 */
this.maxAllocate = 10;
this.scene = scene;
}
Object.defineProperty(EntityList.prototype, "count", {
@@ -2939,32 +2947,31 @@ var es;
* @param entity
*/
EntityList.prototype.add = function (entity) {
if (this._entitiesToAdded.indexOf(entity) == -1)
this._entitiesToAdded.push(entity);
this._entitiesToAdded.add(entity);
};
/**
* 从列表中删除一个实体。所有的生命周期方法将在下一帧中被调用
* @param entity
*/
EntityList.prototype.remove = function (entity) {
if (!this._entitiesToRemove.contains(entity)) {
if (!this._entitiesToRemove.has(entity)) {
console.warn("\u60A8\u6B63\u5728\u5C1D\u8BD5\u5220\u9664\u5DF2\u7ECF\u5220\u9664\u7684\u5B9E\u4F53(" + entity.name + ")");
return;
}
// 防止在同一帧中添加或删除实体
if (this._entitiesToAdded.contains(entity)) {
this._entitiesToAdded.remove(entity);
if (this._entitiesToAdded.has(entity)) {
this._entitiesToAdded.delete(entity);
return;
}
if (!this._entitiesToRemove.contains(entity))
this._entitiesToRemove.push(entity);
if (!this._entitiesToRemove.has(entity))
this._entitiesToRemove.add(entity);
};
/**
* 从实体列表中删除所有实体
*/
EntityList.prototype.removeAllEntities = function () {
this._unsortedTags.clear();
this._entitiesToAdded.length = 0;
this._entitiesToAdded.clear();
this._isEntityListUnsorted = false;
// 为什么我们要在这里更新列表?主要是为了处理在场景切换前被分离的实体。
// 它们仍然会在_entitiesToRemove列表中这将由updateLists处理。
@@ -2982,8 +2989,7 @@ var es;
* @param entity
*/
EntityList.prototype.contains = function (entity) {
return this._entities.findIndex(function (e) { return e.id == entity.id; }) != -1 ||
this._entitiesToAdded.findIndex(function (e) { return e.id == entity.id; }) != -1;
return this._entities.contains(entity) || this._entitiesToAdded.has(entity);
};
EntityList.prototype.getTagList = function (tag) {
var list = this._entityDict.get(tag);
@@ -3014,10 +3020,9 @@ var es;
}
};
EntityList.prototype.updateLists = function () {
var _this = this;
if (this._entitiesToRemove.length > 0) {
for (var _i = 0, _a = this._entitiesToRemove; _i < _a.length; _i++) {
var entity = _a[_i];
if (this._entitiesToRemove.size > 0) {
for (var i = 0; i < this._entitiesToRemove.size; i++) {
var entity = this._entitiesToRemove[i];
// 处理标签列表
this.removeFromTagList(entity);
// 处理常规实体列表
@@ -3027,56 +3032,32 @@ var es;
if (es.Core.entitySystemsEnabled)
this.scene.entityProcessors.onEntityRemoved(entity);
}
this._entitiesToRemove.length = 0;
this._entitiesToRemove.clear();
}
// 现在所有的实体都被添加到场景中我们再次循环并调用onAddedToScene
while (this._addToSceneEntityList.length > 0) {
var entity = this._addToSceneEntityList.shift();
entity.onAddedToScene();
}
if (this._entitiesToAdded.length > 0) {
if (this.frameAllocate && this._entitiesToAdded.length > this.maxAllocate) {
// 启用分帧处理
for (var i = 0; i < this.maxAllocate; i++) {
this.perEntityAddToScene();
}
if (this._entitiesToAdded.length == 0)
this._isEntityListUnsorted = true;
}
else {
while (this._entitiesToAdded.length > 0) {
this.perEntityAddToScene();
}
this._isEntityListUnsorted = true;
}
}
if (this._isEntityListUnsorted) {
this._entities.sort(function (a, b) {
return a.compareTo(b);
});
this._isEntityListUnsorted = false;
}
// 根据需要对标签列表进行排序
if (this._addToSceneEntityList.length == 0 && this._unsortedTags.size > 0) {
this._unsortedTags.forEach(function (tag) {
_this._entityDict.get(tag).sort(function (a, b) {
return a.compareTo(b);
});
});
this._unsortedTags.clear();
}
};
/** 每次添加一个实体到场景 */
EntityList.prototype.perEntityAddToScene = function () {
var entity = this._entitiesToAdded.shift();
this._addToSceneEntityList.push(entity);
if (this._entities.findIndex(function (e) { return e.id == entity.id; }) == -1) {
this._entities.push(entity);
if (this._entitiesToAdded.size > 0) {
for (var i = 0; i < this._entitiesToAdded.size; i++) {
var entity = this._entitiesToAdded[i];
this._entities.add(entity);
entity.scene = this.scene;
this.addToTagList(entity);
if (es.Core.entitySystemsEnabled)
this.scene.entityProcessors.onEntityAdded(entity);
}
for (var i = 0; i < this._entitiesToAdded.size; i++)
this._entitiesToAdded[i].onAddedToScene();
this._entitiesToAdded.clear();
this._isEntityListUnsorted = true;
}
if (this._isEntityListUnsorted) {
this._entities.sort(es.Entity.entityComparer);
this._isEntityListUnsorted = false;
}
// 根据需要对标签列表进行排序
if (this._unsortedTags.size == 0) {
for (var i = 0; i < this._unsortedTags.size; i++)
this._entityDict.get(this._unsortedTags[i]).sort();
this._unsortedTags.clear();
}
};
/**
* 返回第一个找到的名字为name的实体。如果没有找到则返回null
@@ -3087,7 +3068,11 @@ var es;
if (this._entities[i].name == name)
return this._entities[i];
}
return this._entitiesToAdded.firstOrDefault(function (entity) { return entity.name == name; });
for (var i = 0; i < this._entitiesToAdded.size; i++) {
if (this._entitiesToAdded[i].name == name)
return this._entitiesToAdded[i];
}
return null;
};
/**
* 返回带有标签的所有实体的列表。如果没有实体有标签,则返回一个空列表。
@@ -3113,11 +3098,12 @@ var es;
if (this._entities[i] instanceof type)
list.push(this._entities[i]);
}
for (var _i = 0, _a = this._entitiesToAdded; _i < _a.length; _i++) {
var entity = _a[_i];
if (entity instanceof type)
for (var i = 0; i < this._entitiesToAdded.size; i++) {
var entity = this._entitiesToAdded[i];
if (entity instanceof type) {
list.push(entity);
}
}
return list;
};
/**
@@ -3127,12 +3113,12 @@ var es;
EntityList.prototype.findComponentOfType = function (type) {
for (var i = 0; i < this._entities.length; i++) {
if (this._entities[i].enabled) {
var comp = this._entities[i].getComponent(type);
var comp = this._entities.buffer[i].getComponent(type);
if (comp)
return comp;
}
}
for (var i = 0; i < this._entitiesToAdded.length; i++) {
for (var i = 0; i < this._entitiesToAdded.size; i++) {
var entity = this._entitiesToAdded[i];
if (entity.enabled) {
var comp = entity.getComponent(type);
@@ -3153,7 +3139,7 @@ var es;
if (this._entities[i].enabled)
this._entities[i].getComponents(type, comps);
}
for (var i = 0; i < this._entitiesToAdded.length; i++) {
for (var i = 0; i < this._entitiesToAdded.size; i++) {
var entity = this._entitiesToAdded[i];
if (entity.enabled)
entity.getComponents(type, comps);

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,16 @@
module es {
export class EntityComparer implements IComparer<Entity> {
public compare(self: Entity, other: Entity): number {
let compare = self.updateOrder - other.updateOrder;
if (compare == 0)
compare = self.id - other.id;
return compare;
}
}
export class Entity {
public static _idGenerator: number = 0;
public static entityComparer: IComparer<Entity> = new EntityComparer();
/**
* 当前实体所属的场景
*/

View File

@@ -4,15 +4,15 @@ module es {
/**
* 场景中添加的实体列表
*/
public _entities: Entity[] = [];
public _entities: FastList<Entity> = new FastList<Entity>();
/**
* 本帧添加的实体列表。用于对实体进行分组,以便我们可以同时处理它们
*/
public _entitiesToAdded: Entity[] = [];
public _entitiesToAdded: Set<Entity> = new Set<Entity>();
/**
* 本帧被标记为删除的实体列表。用于对实体进行分组,以便我们可以同时处理它们
*/
public _entitiesToRemove: Entity[] = [];
public _entitiesToRemove: Set<Entity> = new Set<Entity>();
/**
* 标志,用于确定我们是否需要在这一帧中对实体进行排序
*/
@@ -22,11 +22,6 @@ module es {
*/
public _entityDict: Map<number, Entity[]> = new Map<number, Entity[]>();
public _unsortedTags: Set<number> = new Set<number>();
public _addToSceneEntityList: Entity[] = [];
/** 是否使用分帧处理 */
public frameAllocate: boolean = false;
/** 每帧最大处理数量 */
public maxAllocate: number = 10;
constructor(scene: Scene) {
this.scene = scene;
@@ -53,8 +48,7 @@ module es {
* @param entity
*/
public add(entity: Entity) {
if (this._entitiesToAdded.indexOf(entity) == -1)
this._entitiesToAdded.push(entity);
this._entitiesToAdded.add(entity);
}
/**
@@ -62,19 +56,19 @@ module es {
* @param entity
*/
public remove(entity: Entity) {
if (!this._entitiesToRemove.contains(entity)) {
if (!this._entitiesToRemove.has(entity)) {
console.warn(`您正在尝试删除已经删除的实体(${entity.name})`);
return;
}
// 防止在同一帧中添加或删除实体
if (this._entitiesToAdded.contains(entity)) {
this._entitiesToAdded.remove(entity);
if (this._entitiesToAdded.has(entity)) {
this._entitiesToAdded.delete(entity);
return;
}
if (!this._entitiesToRemove.contains(entity))
this._entitiesToRemove.push(entity);
if (!this._entitiesToRemove.has(entity))
this._entitiesToRemove.add(entity);
}
/**
@@ -82,7 +76,7 @@ module es {
*/
public removeAllEntities() {
this._unsortedTags.clear();
this._entitiesToAdded.length = 0;
this._entitiesToAdded.clear();
this._isEntityListUnsorted = false;
// 为什么我们要在这里更新列表?主要是为了处理在场景切换前被分离的实体。
@@ -104,8 +98,7 @@ module es {
* @param entity
*/
public contains(entity: Entity): boolean {
return this._entities.findIndex(e => e.id == entity.id) != -1 ||
this._entitiesToAdded.findIndex(e => e.id == entity.id) != -1;
return this._entities.contains(entity) || this._entitiesToAdded.has(entity);
}
public getTagList(tag: number) {
@@ -142,8 +135,9 @@ module es {
}
public updateLists() {
if (this._entitiesToRemove.length > 0) {
for (const entity of this._entitiesToRemove) {
if (this._entitiesToRemove.size > 0) {
for (let i = 0; i< this._entitiesToRemove.size; i ++) {
let entity = this._entitiesToRemove[i];
// 处理标签列表
this.removeFromTagList(entity);
@@ -156,58 +150,13 @@ module es {
this.scene.entityProcessors.onEntityRemoved(entity);
}
this._entitiesToRemove.length = 0;
this._entitiesToRemove.clear();
}
// 现在所有的实体都被添加到场景中我们再次循环并调用onAddedToScene
while (this._addToSceneEntityList.length > 0){
let entity = this._addToSceneEntityList.shift();
entity.onAddedToScene();
}
if (this._entitiesToAdded.length > 0) {
if (this.frameAllocate && this._entitiesToAdded.length > this.maxAllocate){
// 启用分帧处理
for (let i = 0; i < this.maxAllocate; i ++){
this.perEntityAddToScene();
}
if (this._entitiesToAdded.length == 0) this._isEntityListUnsorted = true;
}else{
while (this._entitiesToAdded.length > 0){
this.perEntityAddToScene();
}
this._isEntityListUnsorted = true;
}
}
if (this._isEntityListUnsorted) {
this._entities.sort((a, b)=>{
return a.compareTo(b);
});
this._isEntityListUnsorted = false;
}
// 根据需要对标签列表进行排序
if (this._addToSceneEntityList.length == 0 && this._unsortedTags.size > 0) {
this._unsortedTags.forEach((tag)=>{
this._entityDict.get(tag).sort((a, b) => {
return a.compareTo(b);
});
});
this._unsortedTags.clear();
}
}
/** 每次添加一个实体到场景 */
private perEntityAddToScene(){
let entity = this._entitiesToAdded.shift();
this._addToSceneEntityList.push(entity);
if (this._entities.findIndex(e => e.id == entity.id) == -1) {
this._entities.push(entity);
if (this._entitiesToAdded.size > 0) {
for (let i = 0; i < this._entitiesToAdded.size; i ++) {
let entity = this._entitiesToAdded[i];
this._entities.add(entity);
entity.scene = this.scene;
this.addToTagList(entity);
@@ -215,6 +164,26 @@ module es {
if (Core.entitySystemsEnabled)
this.scene.entityProcessors.onEntityAdded(entity);
}
for (let i = 0; i < this._entitiesToAdded.size; i ++)
this._entitiesToAdded[i].onAddedToScene();
this._entitiesToAdded.clear();
this._isEntityListUnsorted = true;
}
if (this._isEntityListUnsorted) {
this._entities.sort(Entity.entityComparer);
this._isEntityListUnsorted = false;
}
// 根据需要对标签列表进行排序
if (this._unsortedTags.size == 0) {
for (let i = 0; i < this._unsortedTags.size; i ++)
this._entityDict.get(this._unsortedTags[i]).sort();
this._unsortedTags.clear();
}
}
/**
@@ -227,7 +196,12 @@ module es {
return this._entities[i];
}
return this._entitiesToAdded.firstOrDefault(entity => entity.name == name);
for (let i = 0; i < this._entitiesToAdded.size; i ++){
if (this._entitiesToAdded[i].name == name)
return this._entitiesToAdded[i];
}
return null;
}
/**
@@ -257,9 +231,12 @@ module es {
if (this._entities[i] instanceof type)
list.push(this._entities[i] as T);
}
for (const entity of this._entitiesToAdded) {
if (entity instanceof type)
list.push(entity as T);
for (let i = 0; i < this._entitiesToAdded.size; i ++){
let entity = this._entitiesToAdded[i];
if (entity instanceof type) {
list.push(entity);
}
}
return list;
@@ -272,14 +249,14 @@ module es {
public findComponentOfType<T extends Component>(type): T {
for (let i = 0; i < this._entities.length; i++) {
if (this._entities[i].enabled) {
let comp = this._entities[i].getComponent<T>(type);
let comp = this._entities.buffer[i].getComponent<T>(type);
if (comp)
return comp;
}
}
for (let i = 0; i < this._entitiesToAdded.length; i++) {
let entity = this._entitiesToAdded[i];
for (let i = 0; i < this._entitiesToAdded.size; i++) {
let entity: Entity = this._entitiesToAdded[i];
if (entity.enabled) {
let comp = entity.getComponent<T>(type);
if (comp)
@@ -302,7 +279,7 @@ module es {
this._entities[i].getComponents(type, comps);
}
for (let i = 0; i < this._entitiesToAdded.length; i++) {
for (let i = 0; i < this._entitiesToAdded.size; i++) {
let entity = this._entitiesToAdded[i];
if (entity.enabled)
entity.getComponents(type, comps);