新增hashSet
This commit is contained in:
116
source/bin/framework.d.ts
vendored
116
source/bin/framework.d.ts
vendored
@@ -273,7 +273,7 @@ declare module es {
|
|||||||
class EntityComparer implements IComparer<Entity> {
|
class EntityComparer implements IComparer<Entity> {
|
||||||
compare(self: Entity, other: Entity): number;
|
compare(self: Entity, other: Entity): number;
|
||||||
}
|
}
|
||||||
class Entity {
|
class Entity implements IEqualityComparable {
|
||||||
static _idGenerator: number;
|
static _idGenerator: number;
|
||||||
static entityComparer: IComparer<Entity>;
|
static entityComparer: IComparer<Entity>;
|
||||||
/**
|
/**
|
||||||
@@ -429,6 +429,8 @@ declare module es {
|
|||||||
*/
|
*/
|
||||||
removeAllComponents(): void;
|
removeAllComponents(): void;
|
||||||
compareTo(other: Entity): number;
|
compareTo(other: Entity): number;
|
||||||
|
equals(other: Entity): boolean;
|
||||||
|
getHashCode(): number;
|
||||||
toString(): string;
|
toString(): string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1228,11 +1230,11 @@ declare module es {
|
|||||||
/**
|
/**
|
||||||
* 本帧添加的实体列表。用于对实体进行分组,以便我们可以同时处理它们
|
* 本帧添加的实体列表。用于对实体进行分组,以便我们可以同时处理它们
|
||||||
*/
|
*/
|
||||||
_entitiesToAdded: Set<Entity>;
|
_entitiesToAdded: HashSet<Entity>;
|
||||||
/**
|
/**
|
||||||
* 本帧被标记为删除的实体列表。用于对实体进行分组,以便我们可以同时处理它们
|
* 本帧被标记为删除的实体列表。用于对实体进行分组,以便我们可以同时处理它们
|
||||||
*/
|
*/
|
||||||
_entitiesToRemove: Set<Entity>;
|
_entitiesToRemove: HashSet<Entity>;
|
||||||
/**
|
/**
|
||||||
* 标志,用于确定我们是否需要在这一帧中对实体进行排序
|
* 标志,用于确定我们是否需要在这一帧中对实体进行排序
|
||||||
*/
|
*/
|
||||||
@@ -2487,8 +2489,6 @@ declare module es {
|
|||||||
*/
|
*/
|
||||||
update(): void;
|
update(): void;
|
||||||
private checkForExitedColliders;
|
private checkForExitedColliders;
|
||||||
private excepthWith;
|
|
||||||
private unionWith;
|
|
||||||
private notifyTriggerListeners;
|
private notifyTriggerListeners;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3309,10 +3309,14 @@ declare module es {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module es {
|
declare module es {
|
||||||
class EqualityComparer<T> implements IEqualityComparer {
|
class EqualityComparer<T> implements IEqualityComparer<T> {
|
||||||
static default<T>(): EqualityComparer<T>;
|
static default<T>(): EqualityComparer<T>;
|
||||||
protected constructor();
|
protected constructor();
|
||||||
equals(x: T, y: T): boolean;
|
equals(x: T, y: T): boolean;
|
||||||
|
getHashCode(o: T): number;
|
||||||
|
private _getHashCodeForNumber;
|
||||||
|
private _getHashCodeForString;
|
||||||
|
private forOwn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module es {
|
declare module es {
|
||||||
@@ -3353,8 +3357,37 @@ declare module es {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module es {
|
declare module es {
|
||||||
interface IEqualityComparer {
|
/**
|
||||||
equals(x: any, y: any): boolean;
|
* 对象声明自己的平等方法和Hashcode的生成
|
||||||
|
*/
|
||||||
|
interface IEqualityComparable {
|
||||||
|
/**
|
||||||
|
* 确定另一个对象是否等于这个实例
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
equals(other: any): boolean;
|
||||||
|
/**
|
||||||
|
* 生成对象的哈希码
|
||||||
|
*/
|
||||||
|
getHashCode(): number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
declare module es {
|
||||||
|
/**
|
||||||
|
* 为确定对象的哈希码和两个项目是否相等提供接口
|
||||||
|
*/
|
||||||
|
interface IEqualityComparer<T> {
|
||||||
|
/**
|
||||||
|
* 判断两个对象是否相等
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
*/
|
||||||
|
equals(x: T, y: T): boolean;
|
||||||
|
/**
|
||||||
|
* 生成对象的哈希码
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
getHashCode(value: T): number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module es {
|
declare module es {
|
||||||
@@ -3405,12 +3438,13 @@ declare module es {
|
|||||||
/**
|
/**
|
||||||
* 用于管理一对对象的简单DTO
|
* 用于管理一对对象的简单DTO
|
||||||
*/
|
*/
|
||||||
class Pair<T> implements IEquatable<Pair<T>> {
|
class Pair<T> implements IEqualityComparable {
|
||||||
first: T;
|
first: T;
|
||||||
second: T;
|
second: T;
|
||||||
constructor(first: T, second: T);
|
constructor(first: T, second: T);
|
||||||
clear(): void;
|
clear(): void;
|
||||||
equals(other: Pair<T>): boolean;
|
equals(other: Pair<T>): boolean;
|
||||||
|
getHashCode(): number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module es {
|
declare module es {
|
||||||
@@ -3556,6 +3590,70 @@ declare module es {
|
|||||||
constructor(value: T);
|
constructor(value: T);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
declare module es {
|
||||||
|
interface ISet<T> {
|
||||||
|
add(item: T): boolean;
|
||||||
|
remove(item: T): boolean;
|
||||||
|
contains(item: T): boolean;
|
||||||
|
getCount(): number;
|
||||||
|
clear(): void;
|
||||||
|
toArray(): Array<T>;
|
||||||
|
/**
|
||||||
|
* 从当前集合中删除指定集合中的所有元素
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
exceptWith(other: Array<T>): void;
|
||||||
|
/**
|
||||||
|
* 修改当前Set对象,使其只包含该对象和指定数组中的元素
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
intersectWith(other: Array<T>): void;
|
||||||
|
/**
|
||||||
|
* 修改当前的集合对象,使其包含所有存在于自身、指定集合中的元素,或者两者都包含
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
unionWith(other: Array<T>): void;
|
||||||
|
isSubsetOf(other: Array<T>): boolean;
|
||||||
|
isSupersetOf(other: Array<T>): boolean;
|
||||||
|
overlaps(other: Array<T>): boolean;
|
||||||
|
setEquals(other: Array<T>): boolean;
|
||||||
|
}
|
||||||
|
abstract class Set<T> implements ISet<T> {
|
||||||
|
protected buckets: T[][];
|
||||||
|
protected count: number;
|
||||||
|
constructor(source?: Array<T>);
|
||||||
|
abstract getHashCode(item: T): number;
|
||||||
|
abstract areEqual(value1: T, value2: T): boolean;
|
||||||
|
add(item: T): boolean;
|
||||||
|
remove(item: T): boolean;
|
||||||
|
contains(item: T): boolean;
|
||||||
|
getCount(): number;
|
||||||
|
clear(): void;
|
||||||
|
toArray(): T[];
|
||||||
|
/**
|
||||||
|
* 从当前集合中删除指定集合中的所有元素
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
exceptWith(other: Array<T>): void;
|
||||||
|
/**
|
||||||
|
* 修改当前Set对象,使其只包含该对象和指定数组中的元素
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
intersectWith(other: Array<T>): void;
|
||||||
|
unionWith(other: Array<T>): void;
|
||||||
|
isSubsetOf(other: Array<T>): boolean;
|
||||||
|
isSupersetOf(other: Array<T>): boolean;
|
||||||
|
overlaps(other: Array<T>): boolean;
|
||||||
|
setEquals(other: Array<T>): boolean;
|
||||||
|
private buildInternalBuckets;
|
||||||
|
private bucketsContains;
|
||||||
|
}
|
||||||
|
class HashSet<T extends IEqualityComparable> extends Set<T> {
|
||||||
|
constructor(source?: Array<T>);
|
||||||
|
getHashCode(item: T): number;
|
||||||
|
areEqual(value1: T, value2: T): boolean;
|
||||||
|
}
|
||||||
|
}
|
||||||
declare module es {
|
declare module es {
|
||||||
/**
|
/**
|
||||||
* 管理数值的简单助手类。它存储值,直到累计的总数大于1。一旦超过1,该值将在调用update时添加到amount中。
|
* 管理数值的简单助手类。它存储值,直到累计的总数大于1。一旦超过1,该值将在调用update时添加到amount中。
|
||||||
|
|||||||
@@ -1025,6 +1025,12 @@ var es;
|
|||||||
compare = this.id - other.id;
|
compare = this.id - other.id;
|
||||||
return compare;
|
return compare;
|
||||||
};
|
};
|
||||||
|
Entity.prototype.equals = function (other) {
|
||||||
|
return this.compareTo(other) == 0;
|
||||||
|
};
|
||||||
|
Entity.prototype.getHashCode = function () {
|
||||||
|
return this.id;
|
||||||
|
};
|
||||||
Entity.prototype.toString = function () {
|
Entity.prototype.toString = function () {
|
||||||
return "[Entity: name: " + this.name + ", tag: " + this.tag + ", enabled: " + this.enabled + ", depth: " + this.updateOrder + "]";
|
return "[Entity: name: " + this.name + ", tag: " + this.tag + ", enabled: " + this.enabled + ", depth: " + this.updateOrder + "]";
|
||||||
};
|
};
|
||||||
@@ -2910,11 +2916,11 @@ var es;
|
|||||||
/**
|
/**
|
||||||
* 本帧添加的实体列表。用于对实体进行分组,以便我们可以同时处理它们
|
* 本帧添加的实体列表。用于对实体进行分组,以便我们可以同时处理它们
|
||||||
*/
|
*/
|
||||||
this._entitiesToAdded = new Set();
|
this._entitiesToAdded = new es.HashSet();
|
||||||
/**
|
/**
|
||||||
* 本帧被标记为删除的实体列表。用于对实体进行分组,以便我们可以同时处理它们
|
* 本帧被标记为删除的实体列表。用于对实体进行分组,以便我们可以同时处理它们
|
||||||
*/
|
*/
|
||||||
this._entitiesToRemove = new Set();
|
this._entitiesToRemove = new es.HashSet();
|
||||||
/**
|
/**
|
||||||
* 通过标签跟踪实体,便于检索
|
* 通过标签跟踪实体,便于检索
|
||||||
*/
|
*/
|
||||||
@@ -2954,16 +2960,16 @@ var es;
|
|||||||
* @param entity
|
* @param entity
|
||||||
*/
|
*/
|
||||||
EntityList.prototype.remove = function (entity) {
|
EntityList.prototype.remove = function (entity) {
|
||||||
if (!this._entitiesToRemove.has(entity)) {
|
if (!this._entitiesToRemove.contains(entity)) {
|
||||||
console.warn("\u60A8\u6B63\u5728\u5C1D\u8BD5\u5220\u9664\u5DF2\u7ECF\u5220\u9664\u7684\u5B9E\u4F53(" + entity.name + ")");
|
console.warn("\u60A8\u6B63\u5728\u5C1D\u8BD5\u5220\u9664\u5DF2\u7ECF\u5220\u9664\u7684\u5B9E\u4F53(" + entity.name + ")");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 防止在同一帧中添加或删除实体
|
// 防止在同一帧中添加或删除实体
|
||||||
if (this._entitiesToAdded.has(entity)) {
|
if (this._entitiesToAdded.contains(entity)) {
|
||||||
this._entitiesToAdded.delete(entity);
|
this._entitiesToAdded.remove(entity);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this._entitiesToRemove.has(entity))
|
if (!this._entitiesToRemove.contains(entity))
|
||||||
this._entitiesToRemove.add(entity);
|
this._entitiesToRemove.add(entity);
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
@@ -2989,7 +2995,7 @@ var es;
|
|||||||
* @param entity
|
* @param entity
|
||||||
*/
|
*/
|
||||||
EntityList.prototype.contains = function (entity) {
|
EntityList.prototype.contains = function (entity) {
|
||||||
return this._entities.contains(entity) || this._entitiesToAdded.has(entity);
|
return this._entities.contains(entity) || this._entitiesToAdded.contains(entity);
|
||||||
};
|
};
|
||||||
EntityList.prototype.getTagList = function (tag) {
|
EntityList.prototype.getTagList = function (tag) {
|
||||||
var list = this._entityDict.get(tag);
|
var list = this._entityDict.get(tag);
|
||||||
@@ -3014,14 +3020,15 @@ var es;
|
|||||||
};
|
};
|
||||||
EntityList.prototype.update = function () {
|
EntityList.prototype.update = function () {
|
||||||
for (var i = 0; i < this._entities.length; i++) {
|
for (var i = 0; i < this._entities.length; i++) {
|
||||||
var entity = this._entities[i];
|
var entity = this._entities.buffer[i];
|
||||||
if (entity.enabled && (entity.updateInterval == 1 || es.Time.frameCount % entity.updateInterval == 0))
|
if (entity.enabled && (entity.updateInterval == 1 || es.Time.frameCount % entity.updateInterval == 0))
|
||||||
entity.update();
|
entity.update();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
EntityList.prototype.updateLists = function () {
|
EntityList.prototype.updateLists = function () {
|
||||||
if (this._entitiesToRemove.size > 0) {
|
var _this = this;
|
||||||
for (var i = 0; i < this._entitiesToRemove.size; i++) {
|
if (this._entitiesToRemove.getCount() > 0) {
|
||||||
|
for (var i = 0; i < this._entitiesToRemove.getCount(); i++) {
|
||||||
var entity = this._entitiesToRemove[i];
|
var entity = this._entitiesToRemove[i];
|
||||||
// 处理标签列表
|
// 处理标签列表
|
||||||
this.removeFromTagList(entity);
|
this.removeFromTagList(entity);
|
||||||
@@ -3034,17 +3041,17 @@ var es;
|
|||||||
}
|
}
|
||||||
this._entitiesToRemove.clear();
|
this._entitiesToRemove.clear();
|
||||||
}
|
}
|
||||||
if (this._entitiesToAdded.size > 0) {
|
if (this._entitiesToAdded.getCount() > 0) {
|
||||||
for (var i = 0; i < this._entitiesToAdded.size; i++) {
|
for (var i = 0; i < this._entitiesToAdded.getCount(); i++) {
|
||||||
var entity = this._entitiesToAdded[i];
|
var entity = this._entitiesToAdded.toArray()[i];
|
||||||
this._entities.add(entity);
|
this._entities.add(entity);
|
||||||
entity.scene = this.scene;
|
entity.scene = this.scene;
|
||||||
this.addToTagList(entity);
|
this.addToTagList(entity);
|
||||||
if (es.Core.entitySystemsEnabled)
|
if (es.Core.entitySystemsEnabled)
|
||||||
this.scene.entityProcessors.onEntityAdded(entity);
|
this.scene.entityProcessors.onEntityAdded(entity);
|
||||||
}
|
}
|
||||||
for (var i = 0; i < this._entitiesToAdded.size; i++)
|
for (var i = 0; i < this._entitiesToAdded.getCount(); i++)
|
||||||
this._entitiesToAdded[i].onAddedToScene();
|
this._entitiesToAdded.toArray()[i].onAddedToScene();
|
||||||
this._entitiesToAdded.clear();
|
this._entitiesToAdded.clear();
|
||||||
this._isEntityListUnsorted = true;
|
this._isEntityListUnsorted = true;
|
||||||
}
|
}
|
||||||
@@ -3054,8 +3061,7 @@ var es;
|
|||||||
}
|
}
|
||||||
// 根据需要对标签列表进行排序
|
// 根据需要对标签列表进行排序
|
||||||
if (this._unsortedTags.size == 0) {
|
if (this._unsortedTags.size == 0) {
|
||||||
for (var i = 0; i < this._unsortedTags.size; i++)
|
this._unsortedTags.forEach(function (value) { return _this._entityDict.get(value).sort(function (a, b) { return a.compareTo(b); }); });
|
||||||
this._entityDict.get(this._unsortedTags[i]).sort();
|
|
||||||
this._unsortedTags.clear();
|
this._unsortedTags.clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -3068,9 +3074,10 @@ var es;
|
|||||||
if (this._entities[i].name == name)
|
if (this._entities[i].name == name)
|
||||||
return this._entities[i];
|
return this._entities[i];
|
||||||
}
|
}
|
||||||
for (var i = 0; i < this._entitiesToAdded.size; i++) {
|
for (var i = 0; i < this._entitiesToAdded.getCount(); i++) {
|
||||||
if (this._entitiesToAdded[i].name == name)
|
var entity = this._entitiesToAdded.toArray()[i];
|
||||||
return this._entitiesToAdded[i];
|
if (entity.name == name)
|
||||||
|
return entity;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
@@ -3098,9 +3105,9 @@ var es;
|
|||||||
if (this._entities[i] instanceof type)
|
if (this._entities[i] instanceof type)
|
||||||
list.push(this._entities[i]);
|
list.push(this._entities[i]);
|
||||||
}
|
}
|
||||||
for (var i = 0; i < this._entitiesToAdded.size; i++) {
|
for (var i = 0; i < this._entitiesToAdded.getCount(); i++) {
|
||||||
var entity = this._entitiesToAdded[i];
|
var entity = this._entitiesToAdded.toArray()[i];
|
||||||
if (entity instanceof type) {
|
if (es.TypeUtils.getType(entity) instanceof type) {
|
||||||
list.push(entity);
|
list.push(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3118,8 +3125,8 @@ var es;
|
|||||||
return comp;
|
return comp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (var i = 0; i < this._entitiesToAdded.size; i++) {
|
for (var i = 0; i < this._entitiesToAdded.getCount(); i++) {
|
||||||
var entity = this._entitiesToAdded[i];
|
var entity = this._entitiesToAdded.toArray()[i];
|
||||||
if (entity.enabled) {
|
if (entity.enabled) {
|
||||||
var comp = entity.getComponent(type);
|
var comp = entity.getComponent(type);
|
||||||
if (comp)
|
if (comp)
|
||||||
@@ -3139,8 +3146,8 @@ var es;
|
|||||||
if (this._entities[i].enabled)
|
if (this._entities[i].enabled)
|
||||||
this._entities[i].getComponents(type, comps);
|
this._entities[i].getComponents(type, comps);
|
||||||
}
|
}
|
||||||
for (var i = 0; i < this._entitiesToAdded.size; i++) {
|
for (var i = 0; i < this._entitiesToAdded.getCount(); i++) {
|
||||||
var entity = this._entitiesToAdded[i];
|
var entity = this._entitiesToAdded.toArray()[i];
|
||||||
if (entity.enabled)
|
if (entity.enabled)
|
||||||
entity.getComponents(type, comps);
|
entity.getComponents(type, comps);
|
||||||
}
|
}
|
||||||
@@ -5993,9 +6000,9 @@ var es;
|
|||||||
var ColliderTriggerHelper = /** @class */ (function () {
|
var ColliderTriggerHelper = /** @class */ (function () {
|
||||||
function ColliderTriggerHelper(entity) {
|
function ColliderTriggerHelper(entity) {
|
||||||
/** 存储当前帧中发生的所有活动交点对 */
|
/** 存储当前帧中发生的所有活动交点对 */
|
||||||
this._activeTriggerIntersections = new Set();
|
this._activeTriggerIntersections = new es.HashSet();
|
||||||
/** 存储前一帧的交点对,这样我们就可以在移动这一帧后检测到退出 */
|
/** 存储前一帧的交点对,这样我们就可以在移动这一帧后检测到退出 */
|
||||||
this._previousTriggerIntersections = new Set();
|
this._previousTriggerIntersections = new es.HashSet();
|
||||||
this._tempTriggerList = [];
|
this._tempTriggerList = [];
|
||||||
this._entity = entity;
|
this._entity = entity;
|
||||||
}
|
}
|
||||||
@@ -6018,8 +6025,8 @@ var es;
|
|||||||
if (collider.overlaps(neighbor)) {
|
if (collider.overlaps(neighbor)) {
|
||||||
var pair = new es.Pair(collider, neighbor);
|
var pair = new es.Pair(collider, neighbor);
|
||||||
// 如果我们的某一个集合中已经有了这个对子(前一个或当前的触发交叉点),就不要调用输入事件了
|
// 如果我们的某一个集合中已经有了这个对子(前一个或当前的触发交叉点),就不要调用输入事件了
|
||||||
var shouldReportTriggerEvent = !this._activeTriggerIntersections.has(pair) &&
|
var shouldReportTriggerEvent = !this._activeTriggerIntersections.contains(pair) &&
|
||||||
!this._previousTriggerIntersections.has(pair);
|
!this._previousTriggerIntersections.contains(pair);
|
||||||
if (shouldReportTriggerEvent)
|
if (shouldReportTriggerEvent)
|
||||||
this.notifyTriggerListeners(pair, true);
|
this.notifyTriggerListeners(pair, true);
|
||||||
this._activeTriggerIntersections.add(pair);
|
this._activeTriggerIntersections.add(pair);
|
||||||
@@ -6031,32 +6038,16 @@ var es;
|
|||||||
};
|
};
|
||||||
ColliderTriggerHelper.prototype.checkForExitedColliders = function () {
|
ColliderTriggerHelper.prototype.checkForExitedColliders = function () {
|
||||||
// 删除所有与此帧交互的触发器,留下我们退出的触发器
|
// 删除所有与此帧交互的触发器,留下我们退出的触发器
|
||||||
this.excepthWith(this._previousTriggerIntersections, this._activeTriggerIntersections);
|
this._previousTriggerIntersections.exceptWith(this._activeTriggerIntersections.toArray());
|
||||||
for (var i = 0; i < this._previousTriggerIntersections.size; i++) {
|
for (var i = 0; i < this._previousTriggerIntersections.getCount(); i++) {
|
||||||
this.notifyTriggerListeners(this._previousTriggerIntersections[i], false);
|
this.notifyTriggerListeners(this._previousTriggerIntersections[i], false);
|
||||||
}
|
}
|
||||||
this._previousTriggerIntersections.clear();
|
this._previousTriggerIntersections.clear();
|
||||||
// 添加所有当前激活的触发器
|
// 添加所有当前激活的触发器
|
||||||
this.unionWith(this._previousTriggerIntersections, this._activeTriggerIntersections);
|
this._previousTriggerIntersections.unionWith(this._activeTriggerIntersections.toArray());
|
||||||
// 清空活动集,为下一帧做准备
|
// 清空活动集,为下一帧做准备
|
||||||
this._activeTriggerIntersections.clear();
|
this._activeTriggerIntersections.clear();
|
||||||
};
|
};
|
||||||
ColliderTriggerHelper.prototype.excepthWith = function (previous, active) {
|
|
||||||
for (var i = 0; i < previous.size; i++) {
|
|
||||||
var previousDATA = previous[i];
|
|
||||||
for (var j = 0; j < active.size; j++) {
|
|
||||||
var activeDATA = active[j];
|
|
||||||
if (activeDATA.equals(previousDATA))
|
|
||||||
previous.delete(previousDATA);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ColliderTriggerHelper.prototype.unionWith = function (previous, active) {
|
|
||||||
for (var i = 0; i < this._activeTriggerIntersections.size; i++) {
|
|
||||||
if (!this._previousTriggerIntersections.has(this._activeTriggerIntersections[i]))
|
|
||||||
this._previousTriggerIntersections.add(this._activeTriggerIntersections[i]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ColliderTriggerHelper.prototype.notifyTriggerListeners = function (collisionPair, isEntering) {
|
ColliderTriggerHelper.prototype.notifyTriggerListeners = function (collisionPair, isEntering) {
|
||||||
es.TriggerListenerHelper.getITriggerListener(collisionPair.first.entity, this._tempTriggerList);
|
es.TriggerListenerHelper.getITriggerListener(collisionPair.first.entity, this._tempTriggerList);
|
||||||
for (var i = 0; i < this._tempTriggerList.length; i++) {
|
for (var i = 0; i < this._tempTriggerList.length; i++) {
|
||||||
@@ -8309,6 +8300,44 @@ var es;
|
|||||||
return x === y;
|
return x === y;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
EqualityComparer.prototype.getHashCode = function (o) {
|
||||||
|
var _this = this;
|
||||||
|
if (typeof o == 'number') {
|
||||||
|
return this._getHashCodeForNumber(o);
|
||||||
|
}
|
||||||
|
if (typeof o == 'string') {
|
||||||
|
return this._getHashCodeForString(o);
|
||||||
|
}
|
||||||
|
var hashCode = 385229220;
|
||||||
|
this.forOwn(o, function (value) {
|
||||||
|
if (typeof value == 'number') {
|
||||||
|
hashCode += _this._getHashCodeForNumber(value);
|
||||||
|
}
|
||||||
|
else if (typeof value == 'string') {
|
||||||
|
hashCode += _this._getHashCodeForString(value);
|
||||||
|
}
|
||||||
|
else if (typeof value == 'object') {
|
||||||
|
_this.forOwn(value, function () {
|
||||||
|
hashCode += _this.getHashCode(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return hashCode;
|
||||||
|
};
|
||||||
|
EqualityComparer.prototype._getHashCodeForNumber = function (n) {
|
||||||
|
return n;
|
||||||
|
};
|
||||||
|
EqualityComparer.prototype._getHashCodeForString = function (s) {
|
||||||
|
var hashCode = 385229220;
|
||||||
|
for (var i = 0; i < s.length; i++) {
|
||||||
|
hashCode = (hashCode * -1521134295) ^ s.charCodeAt(i);
|
||||||
|
}
|
||||||
|
return hashCode;
|
||||||
|
};
|
||||||
|
EqualityComparer.prototype.forOwn = function (object, iteratee) {
|
||||||
|
object = Object(object);
|
||||||
|
Object.keys(object).forEach(function (key) { return iteratee(object[key], key, object); });
|
||||||
|
};
|
||||||
return EqualityComparer;
|
return EqualityComparer;
|
||||||
}());
|
}());
|
||||||
es.EqualityComparer = EqualityComparer;
|
es.EqualityComparer = EqualityComparer;
|
||||||
@@ -8457,6 +8486,10 @@ var es;
|
|||||||
// 这两种方法在功能上应该是等价的
|
// 这两种方法在功能上应该是等价的
|
||||||
return this.first == other.first && this.second == other.second;
|
return this.first == other.first && this.second == other.second;
|
||||||
};
|
};
|
||||||
|
Pair.prototype.getHashCode = function () {
|
||||||
|
return es.EqualityComparer.default().getHashCode(this.first) * 37 +
|
||||||
|
es.EqualityComparer.default().getHashCode(this.second);
|
||||||
|
};
|
||||||
return Pair;
|
return Pair;
|
||||||
}());
|
}());
|
||||||
es.Pair = Pair;
|
es.Pair = Pair;
|
||||||
@@ -8755,6 +8788,176 @@ var es;
|
|||||||
es.Ref = Ref;
|
es.Ref = Ref;
|
||||||
})(es || (es = {}));
|
})(es || (es = {}));
|
||||||
var es;
|
var es;
|
||||||
|
(function (es) {
|
||||||
|
var Set = /** @class */ (function () {
|
||||||
|
function Set(source) {
|
||||||
|
var _this = this;
|
||||||
|
this.clear();
|
||||||
|
if (source)
|
||||||
|
source.forEach(function (value) {
|
||||||
|
_this.add(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Set.prototype.add = function (item) {
|
||||||
|
var _this = this;
|
||||||
|
var hashCode = this.getHashCode(item);
|
||||||
|
var bucket = this.buckets[hashCode];
|
||||||
|
if (bucket === undefined) {
|
||||||
|
var newBucket = new Array();
|
||||||
|
newBucket.push(item);
|
||||||
|
this.buckets[hashCode] = newBucket;
|
||||||
|
this.count = this.count + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (bucket.some(function (value) { return _this.areEqual(value, item); }))
|
||||||
|
return false;
|
||||||
|
bucket.push(item);
|
||||||
|
this.count = this.count + 1;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
;
|
||||||
|
Set.prototype.remove = function (item) {
|
||||||
|
var _this = this;
|
||||||
|
var hashCode = this.getHashCode(item);
|
||||||
|
var bucket = this.buckets[hashCode];
|
||||||
|
if (bucket === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var result = false;
|
||||||
|
var newBucket = new Array();
|
||||||
|
bucket.forEach(function (value) {
|
||||||
|
if (!_this.areEqual(value, item))
|
||||||
|
newBucket.push(item);
|
||||||
|
else
|
||||||
|
result = true;
|
||||||
|
});
|
||||||
|
this.buckets[hashCode] = newBucket;
|
||||||
|
if (result)
|
||||||
|
this.count = this.count - 1;
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
Set.prototype.contains = function (item) {
|
||||||
|
return this.bucketsContains(this.buckets, item);
|
||||||
|
};
|
||||||
|
;
|
||||||
|
Set.prototype.getCount = function () {
|
||||||
|
return this.count;
|
||||||
|
};
|
||||||
|
Set.prototype.clear = function () {
|
||||||
|
this.buckets = new Array();
|
||||||
|
this.count = 0;
|
||||||
|
};
|
||||||
|
Set.prototype.toArray = function () {
|
||||||
|
var result = new Array();
|
||||||
|
this.buckets.forEach(function (value) {
|
||||||
|
value.forEach(function (inner) {
|
||||||
|
result.push(inner);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 从当前集合中删除指定集合中的所有元素
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
Set.prototype.exceptWith = function (other) {
|
||||||
|
var _this = this;
|
||||||
|
if (other) {
|
||||||
|
other.forEach(function (value) {
|
||||||
|
_this.remove(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 修改当前Set对象,使其只包含该对象和指定数组中的元素
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
Set.prototype.intersectWith = function (other) {
|
||||||
|
var _this = this;
|
||||||
|
if (other) {
|
||||||
|
var otherBuckets_1 = this.buildInternalBuckets(other);
|
||||||
|
this.toArray().forEach(function (value) {
|
||||||
|
if (!_this.bucketsContains(otherBuckets_1.Buckets, value))
|
||||||
|
_this.remove(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Set.prototype.unionWith = function (other) {
|
||||||
|
var _this = this;
|
||||||
|
other.forEach(function (value) {
|
||||||
|
_this.add(value);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Set.prototype.isSubsetOf = function (other) {
|
||||||
|
var _this = this;
|
||||||
|
var otherBuckets = this.buildInternalBuckets(other);
|
||||||
|
return this.toArray().every(function (value) { return _this.bucketsContains(otherBuckets.Buckets, value); });
|
||||||
|
};
|
||||||
|
Set.prototype.isSupersetOf = function (other) {
|
||||||
|
var _this = this;
|
||||||
|
return other.every(function (value) { return _this.contains(value); });
|
||||||
|
};
|
||||||
|
Set.prototype.overlaps = function (other) {
|
||||||
|
var _this = this;
|
||||||
|
return other.some(function (value) { return _this.contains(value); });
|
||||||
|
};
|
||||||
|
Set.prototype.setEquals = function (other) {
|
||||||
|
var _this = this;
|
||||||
|
var otherBuckets = this.buildInternalBuckets(other);
|
||||||
|
if (otherBuckets.Count !== this.count)
|
||||||
|
return false;
|
||||||
|
return other.every(function (value) { return _this.contains(value); });
|
||||||
|
};
|
||||||
|
Set.prototype.buildInternalBuckets = function (source) {
|
||||||
|
var _this = this;
|
||||||
|
var internalBuckets = new Array();
|
||||||
|
var internalCount = 0;
|
||||||
|
source.forEach(function (item) {
|
||||||
|
var hashCode = _this.getHashCode(item);
|
||||||
|
var bucket = internalBuckets[hashCode];
|
||||||
|
if (bucket === undefined) {
|
||||||
|
var newBucket = new Array();
|
||||||
|
newBucket.push(item);
|
||||||
|
internalBuckets[hashCode] = newBucket;
|
||||||
|
internalCount = internalCount + 1;
|
||||||
|
}
|
||||||
|
else if (!bucket.some(function (value) { return _this.areEqual(value, item); })) {
|
||||||
|
bucket.push(item);
|
||||||
|
internalCount = internalCount + 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return { Buckets: internalBuckets, Count: internalCount };
|
||||||
|
};
|
||||||
|
Set.prototype.bucketsContains = function (internalBuckets, item) {
|
||||||
|
var _this = this;
|
||||||
|
var hashCode = this.getHashCode(item);
|
||||||
|
var bucket = internalBuckets[hashCode];
|
||||||
|
if (bucket === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return bucket.some(function (value) { return _this.areEqual(value, item); });
|
||||||
|
};
|
||||||
|
return Set;
|
||||||
|
}());
|
||||||
|
var HashSet = /** @class */ (function (_super) {
|
||||||
|
__extends(HashSet, _super);
|
||||||
|
function HashSet(source) {
|
||||||
|
return _super.call(this, source) || this;
|
||||||
|
}
|
||||||
|
HashSet.prototype.getHashCode = function (item) {
|
||||||
|
return item.getHashCode();
|
||||||
|
};
|
||||||
|
HashSet.prototype.areEqual = function (value1, value2) {
|
||||||
|
return value1.equals(value2);
|
||||||
|
};
|
||||||
|
return HashSet;
|
||||||
|
}(Set));
|
||||||
|
es.HashSet = HashSet;
|
||||||
|
})(es || (es = {}));
|
||||||
|
var es;
|
||||||
(function (es) {
|
(function (es) {
|
||||||
/**
|
/**
|
||||||
* 管理数值的简单助手类。它存储值,直到累计的总数大于1。一旦超过1,该值将在调用update时添加到amount中。
|
* 管理数值的简单助手类。它存储值,直到累计的总数大于1。一旦超过1,该值将在调用update时添加到amount中。
|
||||||
|
|||||||
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
@@ -8,7 +8,7 @@ module es {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Entity {
|
export class Entity implements IEqualityComparable {
|
||||||
public static _idGenerator: number = 0;
|
public static _idGenerator: number = 0;
|
||||||
public static entityComparer: IComparer<Entity> = new EntityComparer();
|
public static entityComparer: IComparer<Entity> = new EntityComparer();
|
||||||
/**
|
/**
|
||||||
@@ -399,6 +399,14 @@ module es {
|
|||||||
return compare;
|
return compare;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public equals(other: Entity): boolean {
|
||||||
|
return this.compareTo(other) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getHashCode(): number {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
public toString(): string {
|
public toString(): string {
|
||||||
return `[Entity: name: ${this.name}, tag: ${this.tag}, enabled: ${this.enabled}, depth: ${this.updateOrder}]`;
|
return `[Entity: name: ${this.name}, tag: ${this.tag}, enabled: ${this.enabled}, depth: ${this.updateOrder}]`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ module es {
|
|||||||
/**
|
/**
|
||||||
* 本帧添加的实体列表。用于对实体进行分组,以便我们可以同时处理它们
|
* 本帧添加的实体列表。用于对实体进行分组,以便我们可以同时处理它们
|
||||||
*/
|
*/
|
||||||
public _entitiesToAdded: Set<Entity> = new Set<Entity>();
|
public _entitiesToAdded: HashSet<Entity> = new HashSet<Entity>();
|
||||||
/**
|
/**
|
||||||
* 本帧被标记为删除的实体列表。用于对实体进行分组,以便我们可以同时处理它们
|
* 本帧被标记为删除的实体列表。用于对实体进行分组,以便我们可以同时处理它们
|
||||||
*/
|
*/
|
||||||
public _entitiesToRemove: Set<Entity> = new Set<Entity>();
|
public _entitiesToRemove: HashSet<Entity> = new HashSet<Entity>();
|
||||||
/**
|
/**
|
||||||
* 标志,用于确定我们是否需要在这一帧中对实体进行排序
|
* 标志,用于确定我们是否需要在这一帧中对实体进行排序
|
||||||
*/
|
*/
|
||||||
@@ -56,18 +56,18 @@ module es {
|
|||||||
* @param entity
|
* @param entity
|
||||||
*/
|
*/
|
||||||
public remove(entity: Entity) {
|
public remove(entity: Entity) {
|
||||||
if (!this._entitiesToRemove.has(entity)) {
|
if (!this._entitiesToRemove.contains(entity)) {
|
||||||
console.warn(`您正在尝试删除已经删除的实体(${entity.name})`);
|
console.warn(`您正在尝试删除已经删除的实体(${entity.name})`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 防止在同一帧中添加或删除实体
|
// 防止在同一帧中添加或删除实体
|
||||||
if (this._entitiesToAdded.has(entity)) {
|
if (this._entitiesToAdded.contains(entity)) {
|
||||||
this._entitiesToAdded.delete(entity);
|
this._entitiesToAdded.remove(entity);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._entitiesToRemove.has(entity))
|
if (!this._entitiesToRemove.contains(entity))
|
||||||
this._entitiesToRemove.add(entity);
|
this._entitiesToRemove.add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ module es {
|
|||||||
* @param entity
|
* @param entity
|
||||||
*/
|
*/
|
||||||
public contains(entity: Entity): boolean {
|
public contains(entity: Entity): boolean {
|
||||||
return this._entities.contains(entity) || this._entitiesToAdded.has(entity);
|
return this._entities.contains(entity) || this._entitiesToAdded.contains(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTagList(tag: number) {
|
public getTagList(tag: number) {
|
||||||
@@ -128,15 +128,15 @@ module es {
|
|||||||
|
|
||||||
public update() {
|
public update() {
|
||||||
for (let i = 0; i < this._entities.length; i++) {
|
for (let i = 0; i < this._entities.length; i++) {
|
||||||
let entity = this._entities[i];
|
let entity = this._entities.buffer[i];
|
||||||
if (entity.enabled && (entity.updateInterval == 1 || Time.frameCount % entity.updateInterval == 0))
|
if (entity.enabled && (entity.updateInterval == 1 || Time.frameCount % entity.updateInterval == 0))
|
||||||
entity.update();
|
entity.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateLists() {
|
public updateLists() {
|
||||||
if (this._entitiesToRemove.size > 0) {
|
if (this._entitiesToRemove.getCount() > 0) {
|
||||||
for (let i = 0; i< this._entitiesToRemove.size; i ++) {
|
for (let i = 0; i< this._entitiesToRemove.getCount(); i ++) {
|
||||||
let entity = this._entitiesToRemove[i];
|
let entity = this._entitiesToRemove[i];
|
||||||
// 处理标签列表
|
// 处理标签列表
|
||||||
this.removeFromTagList(entity);
|
this.removeFromTagList(entity);
|
||||||
@@ -153,9 +153,9 @@ module es {
|
|||||||
this._entitiesToRemove.clear();
|
this._entitiesToRemove.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._entitiesToAdded.size > 0) {
|
if (this._entitiesToAdded.getCount() > 0) {
|
||||||
for (let i = 0; i < this._entitiesToAdded.size; i ++) {
|
for (let i = 0; i < this._entitiesToAdded.getCount(); i ++) {
|
||||||
let entity = this._entitiesToAdded[i];
|
let entity = this._entitiesToAdded.toArray()[i];
|
||||||
this._entities.add(entity);
|
this._entities.add(entity);
|
||||||
entity.scene = this.scene;
|
entity.scene = this.scene;
|
||||||
|
|
||||||
@@ -165,8 +165,8 @@ module es {
|
|||||||
this.scene.entityProcessors.onEntityAdded(entity);
|
this.scene.entityProcessors.onEntityAdded(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this._entitiesToAdded.size; i ++)
|
for (let i = 0; i < this._entitiesToAdded.getCount(); i ++)
|
||||||
this._entitiesToAdded[i].onAddedToScene();
|
this._entitiesToAdded.toArray()[i].onAddedToScene();
|
||||||
|
|
||||||
this._entitiesToAdded.clear();
|
this._entitiesToAdded.clear();
|
||||||
this._isEntityListUnsorted = true;
|
this._isEntityListUnsorted = true;
|
||||||
@@ -179,8 +179,7 @@ module es {
|
|||||||
|
|
||||||
// 根据需要对标签列表进行排序
|
// 根据需要对标签列表进行排序
|
||||||
if (this._unsortedTags.size == 0) {
|
if (this._unsortedTags.size == 0) {
|
||||||
for (let i = 0; i < this._unsortedTags.size; i ++)
|
this._unsortedTags.forEach(value => this._entityDict.get(value).sort((a, b) => a.compareTo(b)));
|
||||||
this._entityDict.get(this._unsortedTags[i]).sort();
|
|
||||||
|
|
||||||
this._unsortedTags.clear();
|
this._unsortedTags.clear();
|
||||||
}
|
}
|
||||||
@@ -196,9 +195,10 @@ module es {
|
|||||||
return this._entities[i];
|
return this._entities[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this._entitiesToAdded.size; i ++){
|
for (let i = 0; i < this._entitiesToAdded.getCount(); i ++){
|
||||||
if (this._entitiesToAdded[i].name == name)
|
let entity = this._entitiesToAdded.toArray()[i];
|
||||||
return this._entitiesToAdded[i];
|
if (entity.name == name)
|
||||||
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -232,10 +232,10 @@ module es {
|
|||||||
list.push(this._entities[i] as T);
|
list.push(this._entities[i] as T);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this._entitiesToAdded.size; i ++){
|
for (let i = 0; i < this._entitiesToAdded.getCount(); i ++){
|
||||||
let entity = this._entitiesToAdded[i];
|
let entity = this._entitiesToAdded.toArray()[i];
|
||||||
if (entity instanceof type) {
|
if (TypeUtils.getType(entity) instanceof type) {
|
||||||
list.push(entity);
|
list.push(entity as T);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,8 +255,8 @@ module es {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this._entitiesToAdded.size; i++) {
|
for (let i = 0; i < this._entitiesToAdded.getCount(); i++) {
|
||||||
let entity: Entity = this._entitiesToAdded[i];
|
let entity: Entity = this._entitiesToAdded.toArray()[i];
|
||||||
if (entity.enabled) {
|
if (entity.enabled) {
|
||||||
let comp = entity.getComponent<T>(type);
|
let comp = entity.getComponent<T>(type);
|
||||||
if (comp)
|
if (comp)
|
||||||
@@ -279,8 +279,8 @@ module es {
|
|||||||
this._entities[i].getComponents(type, comps);
|
this._entities[i].getComponents(type, comps);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this._entitiesToAdded.size; i++) {
|
for (let i = 0; i < this._entitiesToAdded.getCount(); i++) {
|
||||||
let entity = this._entitiesToAdded[i];
|
let entity = this._entitiesToAdded.toArray()[i];
|
||||||
if (entity.enabled)
|
if (entity.enabled)
|
||||||
entity.getComponents(type, comps);
|
entity.getComponents(type, comps);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ module es {
|
|||||||
export class ColliderTriggerHelper {
|
export class ColliderTriggerHelper {
|
||||||
private _entity: Entity;
|
private _entity: Entity;
|
||||||
/** 存储当前帧中发生的所有活动交点对 */
|
/** 存储当前帧中发生的所有活动交点对 */
|
||||||
private _activeTriggerIntersections: Set<Pair<Collider>> = new Set();
|
private _activeTriggerIntersections: HashSet<Pair<Collider>> = new HashSet<Pair<Collider>>();
|
||||||
/** 存储前一帧的交点对,这样我们就可以在移动这一帧后检测到退出 */
|
/** 存储前一帧的交点对,这样我们就可以在移动这一帧后检测到退出 */
|
||||||
private _previousTriggerIntersections: Set<Pair<Collider>> = new Set();
|
private _previousTriggerIntersections: HashSet<Pair<Collider>> = new HashSet<Pair<Collider>>();
|
||||||
private _tempTriggerList: ITriggerListener[] = [];
|
private _tempTriggerList: ITriggerListener[] = [];
|
||||||
|
|
||||||
constructor(entity: Entity) {
|
constructor(entity: Entity) {
|
||||||
@@ -36,8 +36,8 @@ module es {
|
|||||||
let pair = new Pair<Collider>(collider, neighbor);
|
let pair = new Pair<Collider>(collider, neighbor);
|
||||||
|
|
||||||
// 如果我们的某一个集合中已经有了这个对子(前一个或当前的触发交叉点),就不要调用输入事件了
|
// 如果我们的某一个集合中已经有了这个对子(前一个或当前的触发交叉点),就不要调用输入事件了
|
||||||
let shouldReportTriggerEvent = !this._activeTriggerIntersections.has(pair) &&
|
let shouldReportTriggerEvent = !this._activeTriggerIntersections.contains(pair) &&
|
||||||
!this._previousTriggerIntersections.has(pair);
|
!this._previousTriggerIntersections.contains(pair);
|
||||||
|
|
||||||
if (shouldReportTriggerEvent)
|
if (shouldReportTriggerEvent)
|
||||||
this.notifyTriggerListeners(pair, true);
|
this.notifyTriggerListeners(pair, true);
|
||||||
@@ -54,39 +54,21 @@ module es {
|
|||||||
|
|
||||||
private checkForExitedColliders() {
|
private checkForExitedColliders() {
|
||||||
// 删除所有与此帧交互的触发器,留下我们退出的触发器
|
// 删除所有与此帧交互的触发器,留下我们退出的触发器
|
||||||
this.excepthWith(this._previousTriggerIntersections, this._activeTriggerIntersections);
|
this._previousTriggerIntersections.exceptWith(this._activeTriggerIntersections.toArray());
|
||||||
|
|
||||||
for (let i = 0; i < this._previousTriggerIntersections.size; i++) {
|
for (let i = 0; i < this._previousTriggerIntersections.getCount(); i++) {
|
||||||
this.notifyTriggerListeners(this._previousTriggerIntersections[i], false)
|
this.notifyTriggerListeners(this._previousTriggerIntersections[i], false)
|
||||||
}
|
}
|
||||||
|
|
||||||
this._previousTriggerIntersections.clear();
|
this._previousTriggerIntersections.clear();
|
||||||
|
|
||||||
// 添加所有当前激活的触发器
|
// 添加所有当前激活的触发器
|
||||||
this.unionWith(this._previousTriggerIntersections, this._activeTriggerIntersections);
|
this._previousTriggerIntersections.unionWith(this._activeTriggerIntersections.toArray());
|
||||||
|
|
||||||
// 清空活动集,为下一帧做准备
|
// 清空活动集,为下一帧做准备
|
||||||
this._activeTriggerIntersections.clear();
|
this._activeTriggerIntersections.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private excepthWith(previous: Set<Pair<Collider>>, active: Set<Pair<Collider>>){
|
|
||||||
for (let i = 0; i < previous.size; i ++){
|
|
||||||
let previousDATA: Pair<Collider> = previous[i];
|
|
||||||
for (let j = 0; j < active.size; j ++){
|
|
||||||
let activeDATA: Pair<Collider> = active[j];
|
|
||||||
if (activeDATA.equals(previousDATA))
|
|
||||||
previous.delete(previousDATA);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private unionWith(previous: Set<Pair<Collider>>, active: Set<Pair<Collider>>) {
|
|
||||||
for (let i = 0; i < this._activeTriggerIntersections.size; i ++) {
|
|
||||||
if (!this._previousTriggerIntersections.has(this._activeTriggerIntersections[i]))
|
|
||||||
this._previousTriggerIntersections.add(this._activeTriggerIntersections[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private notifyTriggerListeners(collisionPair: Pair<Collider>, isEntering: boolean) {
|
private notifyTriggerListeners(collisionPair: Pair<Collider>, isEntering: boolean) {
|
||||||
TriggerListenerHelper.getITriggerListener(collisionPair.first.entity, this._tempTriggerList);
|
TriggerListenerHelper.getITriggerListener(collisionPair.first.entity, this._tempTriggerList);
|
||||||
for (let i = 0; i < this._tempTriggerList.length; i++) {
|
for (let i = 0; i < this._tempTriggerList.length; i++) {
|
||||||
|
|||||||
@@ -1,17 +1,61 @@
|
|||||||
module es {
|
module es {
|
||||||
export class EqualityComparer<T> implements IEqualityComparer {
|
export class EqualityComparer<T> implements IEqualityComparer<T> {
|
||||||
public static default<T>(){
|
public static default<T>() {
|
||||||
return new EqualityComparer<T>();
|
return new EqualityComparer<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected constructor(){ }
|
protected constructor() { }
|
||||||
|
|
||||||
public equals(x: T, y: T): boolean{
|
public equals(x: T, y: T): boolean {
|
||||||
if (typeof x["equals"] == 'function'){
|
if (typeof x["equals"] == 'function') {
|
||||||
return x["equals"](y);
|
return x["equals"](y);
|
||||||
} else {
|
} else {
|
||||||
return x === y;
|
return x === y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getHashCode(o: T): number {
|
||||||
|
if (typeof o == 'number') {
|
||||||
|
return this._getHashCodeForNumber(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof o == 'string') {
|
||||||
|
return this._getHashCodeForString(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
let hashCode = 385229220;
|
||||||
|
this.forOwn(o, (value) => {
|
||||||
|
if (typeof value == 'number') {
|
||||||
|
hashCode += this._getHashCodeForNumber(value);
|
||||||
|
} else if (typeof value == 'string') {
|
||||||
|
hashCode += this._getHashCodeForString(value);
|
||||||
|
} else if (typeof value == 'object') {
|
||||||
|
this.forOwn(value, () => {
|
||||||
|
hashCode += this.getHashCode(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getHashCodeForNumber(n: number): number {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getHashCodeForString(s: string): number {
|
||||||
|
let hashCode = 385229220;
|
||||||
|
|
||||||
|
for (let i = 0; i < s.length; i++) {
|
||||||
|
hashCode = (hashCode * -1521134295) ^ s.charCodeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private forOwn(object, iteratee){
|
||||||
|
object = Object(object);
|
||||||
|
Object.keys(object).forEach((key) => iteratee(object[key], key, object));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
17
source/src/Utils/IEqualityComparable.ts
Normal file
17
source/src/Utils/IEqualityComparable.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
module es {
|
||||||
|
/**
|
||||||
|
* 对象声明自己的平等方法和Hashcode的生成
|
||||||
|
*/
|
||||||
|
export interface IEqualityComparable {
|
||||||
|
/**
|
||||||
|
* 确定另一个对象是否等于这个实例
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
equals(other: any): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成对象的哈希码
|
||||||
|
*/
|
||||||
|
getHashCode(): number;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,19 @@
|
|||||||
module es {
|
module es {
|
||||||
export interface IEqualityComparer {
|
/**
|
||||||
equals(x: any, y: any): boolean;
|
* 为确定对象的哈希码和两个项目是否相等提供接口
|
||||||
|
*/
|
||||||
|
export interface IEqualityComparer<T> {
|
||||||
|
/**
|
||||||
|
* 判断两个对象是否相等
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
*/
|
||||||
|
equals(x: T, y: T): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成对象的哈希码
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
getHashCode(value: T): number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@ module es {
|
|||||||
/**
|
/**
|
||||||
* 用于管理一对对象的简单DTO
|
* 用于管理一对对象的简单DTO
|
||||||
*/
|
*/
|
||||||
export class Pair<T> implements IEquatable<Pair<T>> {
|
export class Pair<T> implements IEqualityComparable {
|
||||||
public first: T;
|
public first: T;
|
||||||
public second: T;
|
public second: T;
|
||||||
|
|
||||||
@@ -19,5 +19,10 @@ module es {
|
|||||||
// 这两种方法在功能上应该是等价的
|
// 这两种方法在功能上应该是等价的
|
||||||
return this.first == other.first && this.second == other.second;
|
return this.first == other.first && this.second == other.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getHashCode(): number {
|
||||||
|
return EqualityComparer.default<T>().getHashCode(this.first) * 37 +
|
||||||
|
EqualityComparer.default<T>().getHashCode(this.second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
204
source/src/Utils/Set.ts
Normal file
204
source/src/Utils/Set.ts
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
module es {
|
||||||
|
export interface ISet<T> {
|
||||||
|
add(item: T): boolean
|
||||||
|
remove(item: T): boolean
|
||||||
|
contains(item: T): boolean
|
||||||
|
getCount(): number
|
||||||
|
clear(): void
|
||||||
|
toArray(): Array<T>
|
||||||
|
/**
|
||||||
|
* 从当前集合中删除指定集合中的所有元素
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
exceptWith(other: Array<T>): void
|
||||||
|
/**
|
||||||
|
* 修改当前Set对象,使其只包含该对象和指定数组中的元素
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
intersectWith(other: Array<T>): void
|
||||||
|
/**
|
||||||
|
* 修改当前的集合对象,使其包含所有存在于自身、指定集合中的元素,或者两者都包含
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
unionWith(other: Array<T>): void
|
||||||
|
isSubsetOf(other: Array<T>): boolean
|
||||||
|
isSupersetOf(other: Array<T>): boolean
|
||||||
|
overlaps(other: Array<T>): boolean
|
||||||
|
setEquals(other: Array<T>): boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IBucketsWithCount<T> {
|
||||||
|
Buckets: Array<Array<T>>
|
||||||
|
Count: number
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class Set<T> implements ISet<T> {
|
||||||
|
protected buckets: T[][];
|
||||||
|
protected count: number;
|
||||||
|
constructor(source?: Array<T>) {
|
||||||
|
this.clear();
|
||||||
|
if (source)
|
||||||
|
source.forEach(value => {
|
||||||
|
this.add(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
abstract getHashCode(item: T): number;
|
||||||
|
abstract areEqual(value1: T, value2: T): boolean;
|
||||||
|
|
||||||
|
add(item: T) {
|
||||||
|
let hashCode = this.getHashCode(item);
|
||||||
|
let bucket = this.buckets[hashCode];
|
||||||
|
if (bucket === undefined) {
|
||||||
|
let newBucket = new Array<T>();
|
||||||
|
newBucket.push(item);
|
||||||
|
this.buckets[hashCode] = newBucket;
|
||||||
|
this.count = this.count + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (bucket.some((value) => this.areEqual(value,item)))
|
||||||
|
return false;
|
||||||
|
bucket.push(item);
|
||||||
|
this.count = this.count + 1;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
remove(item: T) {
|
||||||
|
let hashCode = this.getHashCode(item);
|
||||||
|
let bucket = this.buckets[hashCode];
|
||||||
|
if (bucket === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let result = false;
|
||||||
|
let newBucket = new Array<T>();
|
||||||
|
bucket.forEach((value) => {
|
||||||
|
if (!this.areEqual(value, item))
|
||||||
|
newBucket.push(item);
|
||||||
|
else
|
||||||
|
result = true;
|
||||||
|
});
|
||||||
|
this.buckets[hashCode] = newBucket;
|
||||||
|
if (result)
|
||||||
|
this.count = this.count - 1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
contains(item: T) {
|
||||||
|
return this.bucketsContains(this.buckets, item)
|
||||||
|
};
|
||||||
|
|
||||||
|
getCount() {
|
||||||
|
return this.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.buckets = new Array<Array<T>>();
|
||||||
|
this.count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
toArray() {
|
||||||
|
let result = new Array<T>()
|
||||||
|
this.buckets.forEach(value => {
|
||||||
|
value.forEach(inner => {
|
||||||
|
result.push(inner);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从当前集合中删除指定集合中的所有元素
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
exceptWith(other: Array<T>) {
|
||||||
|
if (other) {
|
||||||
|
other.forEach(value => {
|
||||||
|
this.remove(value);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 修改当前Set对象,使其只包含该对象和指定数组中的元素
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
intersectWith(other: Array<T>) {
|
||||||
|
if (other) {
|
||||||
|
let otherBuckets = this.buildInternalBuckets(other);
|
||||||
|
this.toArray().forEach(value => {
|
||||||
|
if (!this.bucketsContains(otherBuckets.Buckets, value))
|
||||||
|
this.remove(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unionWith(other: Array<T>) {
|
||||||
|
other.forEach(value => {
|
||||||
|
this.add(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
isSubsetOf(other: Array<T>) {
|
||||||
|
|
||||||
|
let otherBuckets = this.buildInternalBuckets(other);
|
||||||
|
return this.toArray().every(value => this.bucketsContains(otherBuckets.Buckets, value));
|
||||||
|
|
||||||
|
}
|
||||||
|
isSupersetOf(other: Array<T>) {
|
||||||
|
return other.every(value => this.contains(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
overlaps(other: Array<T>) {
|
||||||
|
return other.some(value => this.contains(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
setEquals(other: Array<T>) {
|
||||||
|
let otherBuckets = this.buildInternalBuckets(other);
|
||||||
|
if (otherBuckets.Count !== this.count)
|
||||||
|
return false
|
||||||
|
return other.every(value => this.contains(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildInternalBuckets(source: Array<T>): IBucketsWithCount<T> {
|
||||||
|
let internalBuckets = new Array<Array<T>>();
|
||||||
|
let internalCount = 0;
|
||||||
|
source.forEach(item=> {
|
||||||
|
let hashCode = this.getHashCode(item);
|
||||||
|
let bucket = internalBuckets[hashCode];
|
||||||
|
if (bucket === undefined) {
|
||||||
|
let newBucket = new Array<T>();
|
||||||
|
newBucket.push(item);
|
||||||
|
internalBuckets[hashCode] = newBucket;
|
||||||
|
internalCount = internalCount + 1;
|
||||||
|
}
|
||||||
|
else if (!bucket.some((value) => this.areEqual(value, item))) {
|
||||||
|
bucket.push(item);
|
||||||
|
internalCount = internalCount + 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return { Buckets: internalBuckets, Count: internalCount };
|
||||||
|
}
|
||||||
|
|
||||||
|
private bucketsContains(internalBuckets: Array<Array<T>>, item: T) {
|
||||||
|
let hashCode = this.getHashCode(item);
|
||||||
|
let bucket = internalBuckets[hashCode];
|
||||||
|
if (bucket === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return bucket.some((value) => this.areEqual(value, item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class HashSet<T extends IEqualityComparable> extends Set<T> {
|
||||||
|
constructor(source?: Array<T>) {
|
||||||
|
super(source)
|
||||||
|
}
|
||||||
|
getHashCode(item: T) {
|
||||||
|
return item.getHashCode();
|
||||||
|
}
|
||||||
|
areEqual(value1: T, value2: T) {
|
||||||
|
return value1.equals(value2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user