修复ITriggerListener失效问题
This commit is contained in:
Vendored
+18
-79
@@ -433,7 +433,6 @@ declare module es {
|
|||||||
tweenLocalRotationDegreesTo(to: number, duration?: number): TransformVector2Tween;
|
tweenLocalRotationDegreesTo(to: number, duration?: number): TransformVector2Tween;
|
||||||
compareTo(other: Entity): number;
|
compareTo(other: Entity): number;
|
||||||
equals(other: Entity): boolean;
|
equals(other: Entity): boolean;
|
||||||
getHashCode(): number;
|
|
||||||
toString(): string;
|
toString(): string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2721,6 +2720,10 @@ declare module es {
|
|||||||
* @param self
|
* @param self
|
||||||
*/
|
*/
|
||||||
static invertFlags(self: Ref<number>): void;
|
static invertFlags(self: Ref<number>): void;
|
||||||
|
/**
|
||||||
|
* 打印 number 的二进制表示。 方便调试 number 标志
|
||||||
|
*/
|
||||||
|
static binaryStringRepresentation(self: number, leftPadWidth?: number): string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module es {
|
declare module es {
|
||||||
@@ -3470,6 +3473,7 @@ declare module es {
|
|||||||
* 它将处理任何与Collider重叠的ITriggerListeners。
|
* 它将处理任何与Collider重叠的ITriggerListeners。
|
||||||
*/
|
*/
|
||||||
update(): void;
|
update(): void;
|
||||||
|
private getColliders;
|
||||||
private checkForExitedColliders;
|
private checkForExitedColliders;
|
||||||
private notifyTriggerListeners;
|
private notifyTriggerListeners;
|
||||||
}
|
}
|
||||||
@@ -4946,10 +4950,6 @@ declare module es {
|
|||||||
* @param other
|
* @param other
|
||||||
*/
|
*/
|
||||||
equals(other: any): boolean;
|
equals(other: any): boolean;
|
||||||
/**
|
|
||||||
* 生成对象的哈希码
|
|
||||||
*/
|
|
||||||
getHashCode(): number;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module es {
|
declare module es {
|
||||||
@@ -5354,13 +5354,24 @@ declare module es {
|
|||||||
/**
|
/**
|
||||||
* 用于管理一对对象的简单DTO
|
* 用于管理一对对象的简单DTO
|
||||||
*/
|
*/
|
||||||
class Pair<T> implements IEqualityComparable {
|
class Pair<T> {
|
||||||
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 {
|
||||||
|
class PairSet<T> {
|
||||||
|
readonly all: Array<Pair<T>>;
|
||||||
|
has(pair: Pair<T>): boolean;
|
||||||
|
add(pair: Pair<T>): void;
|
||||||
|
remove(pair: Pair<T>): void;
|
||||||
|
clear(): void;
|
||||||
|
union(other: PairSet<T>): void;
|
||||||
|
except(other: PairSet<T>): void;
|
||||||
|
private _all;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module es {
|
declare module es {
|
||||||
@@ -5403,78 +5414,6 @@ declare module es {
|
|||||||
}
|
}
|
||||||
var isIPoolable: (props: any) => props is IPoolable;
|
var isIPoolable: (props: any) => props is IPoolable;
|
||||||
}
|
}
|
||||||
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;
|
|
||||||
/**
|
|
||||||
* 确定当前集合是否为指定集合或数组的子集
|
|
||||||
* @param other
|
|
||||||
*/
|
|
||||||
isSubsetOf(other: Array<T>): boolean;
|
|
||||||
/**
|
|
||||||
* 确定当前不可变排序集是否为指定集合的超集
|
|
||||||
* @param other
|
|
||||||
*/
|
|
||||||
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 {
|
||||||
/**
|
/**
|
||||||
* startCoroutine返回的接口,它提供了中途停止coroutine的能力。
|
* startCoroutine返回的接口,它提供了中途停止coroutine的能力。
|
||||||
|
|||||||
+117
-207
@@ -1111,9 +1111,6 @@ var es;
|
|||||||
Entity.prototype.equals = function (other) {
|
Entity.prototype.equals = function (other) {
|
||||||
return this.compareTo(other) == 0;
|
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 + "]";
|
||||||
};
|
};
|
||||||
@@ -6755,6 +6752,17 @@ var es;
|
|||||||
Flags.invertFlags = function (self) {
|
Flags.invertFlags = function (self) {
|
||||||
self.value = ~self.value;
|
self.value = ~self.value;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 打印 number 的二进制表示。 方便调试 number 标志
|
||||||
|
*/
|
||||||
|
Flags.binaryStringRepresentation = function (self, leftPadWidth) {
|
||||||
|
if (leftPadWidth === void 0) { leftPadWidth = 10; }
|
||||||
|
var str = self.toString(2);
|
||||||
|
while (str.length < (leftPadWidth || 2)) {
|
||||||
|
str = '0' + str;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
};
|
||||||
return Flags;
|
return Flags;
|
||||||
}());
|
}());
|
||||||
es.Flags = Flags;
|
es.Flags = Flags;
|
||||||
@@ -8485,9 +8493,9 @@ var es;
|
|||||||
var ColliderTriggerHelper = /** @class */ (function () {
|
var ColliderTriggerHelper = /** @class */ (function () {
|
||||||
function ColliderTriggerHelper(entity) {
|
function ColliderTriggerHelper(entity) {
|
||||||
/** 存储当前帧中发生的所有活动交点对 */
|
/** 存储当前帧中发生的所有活动交点对 */
|
||||||
this._activeTriggerIntersections = new es.HashSet();
|
this._activeTriggerIntersections = new es.PairSet();
|
||||||
/** 存储前一帧的交点对,这样我们就可以在移动这一帧后检测到退出 */
|
/** 存储前一帧的交点对,这样我们就可以在移动这一帧后检测到退出 */
|
||||||
this._previousTriggerIntersections = new es.HashSet();
|
this._previousTriggerIntersections = new es.PairSet();
|
||||||
this._tempTriggerList = [];
|
this._tempTriggerList = [];
|
||||||
this._entity = entity;
|
this._entity = entity;
|
||||||
}
|
}
|
||||||
@@ -8500,10 +8508,10 @@ var es;
|
|||||||
var lateColliders = [];
|
var lateColliders = [];
|
||||||
// 对所有实体.colliders进行重叠检查,这些实体.colliders是触发器,与所有宽相碰撞器,无论是否触发器。
|
// 对所有实体.colliders进行重叠检查,这些实体.colliders是触发器,与所有宽相碰撞器,无论是否触发器。
|
||||||
// 任何重叠都会导致触发事件
|
// 任何重叠都会导致触发事件
|
||||||
var colliders = this._entity.getComponents(es.Collider);
|
var colliders = this.getColliders();
|
||||||
for (var i = 0; i < colliders.length; i++) {
|
for (var i = 0; i < colliders.length; i++) {
|
||||||
var collider = colliders[i];
|
var collider = colliders[i];
|
||||||
var neighbors = es.Physics.boxcastBroadphaseExcludingSelf(collider.bounds, collider.collidesWithLayers);
|
var neighbors = es.Physics.boxcastBroadphaseExcludingSelf(collider, collider.bounds, collider.collidesWithLayers.value);
|
||||||
for (var j = 0; j < neighbors.length; j++) {
|
for (var j = 0; j < neighbors.length; j++) {
|
||||||
var neighbor = neighbors[j];
|
var neighbor = neighbors[j];
|
||||||
// 我们至少需要一个碰撞器作为触发器
|
// 我们至少需要一个碰撞器作为触发器
|
||||||
@@ -8512,8 +8520,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.contains(pair) &&
|
var shouldReportTriggerEvent = !this._activeTriggerIntersections.has(pair) &&
|
||||||
!this._previousTriggerIntersections.contains(pair);
|
!this._previousTriggerIntersections.has(pair);
|
||||||
if (shouldReportTriggerEvent) {
|
if (shouldReportTriggerEvent) {
|
||||||
if (neighbor.castSortOrder >= es.Collider.lateSortOrder) {
|
if (neighbor.castSortOrder >= es.Collider.lateSortOrder) {
|
||||||
lateColliders.push(pair);
|
lateColliders.push(pair);
|
||||||
@@ -8541,15 +8549,27 @@ var es;
|
|||||||
}
|
}
|
||||||
this.checkForExitedColliders();
|
this.checkForExitedColliders();
|
||||||
};
|
};
|
||||||
ColliderTriggerHelper.prototype.checkForExitedColliders = function () {
|
ColliderTriggerHelper.prototype.getColliders = function () {
|
||||||
// 删除所有与此帧交互的触发器,留下我们退出的触发器
|
var colliders = [];
|
||||||
this._previousTriggerIntersections.exceptWith(this._activeTriggerIntersections.toArray());
|
for (var i = 0; i < this._entity.components.buffer.length; i++) {
|
||||||
for (var i = 0; i < this._previousTriggerIntersections.getCount(); i++) {
|
var component = this._entity.components.buffer[i];
|
||||||
this.notifyTriggerListeners(this._previousTriggerIntersections[i], false);
|
if (component instanceof es.Collider) {
|
||||||
|
colliders.push(component);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return colliders;
|
||||||
|
};
|
||||||
|
ColliderTriggerHelper.prototype.checkForExitedColliders = function () {
|
||||||
|
var _this = this;
|
||||||
|
// 删除所有与此帧交互的触发器,留下我们退出的触发器
|
||||||
|
this._previousTriggerIntersections.except(this._activeTriggerIntersections);
|
||||||
|
var all = this._previousTriggerIntersections.all;
|
||||||
|
all.forEach(function (pair) {
|
||||||
|
_this.notifyTriggerListeners(pair, false);
|
||||||
|
});
|
||||||
this._previousTriggerIntersections.clear();
|
this._previousTriggerIntersections.clear();
|
||||||
// 添加所有当前激活的触发器
|
// 添加所有当前激活的触发器
|
||||||
this._previousTriggerIntersections.unionWith(this._activeTriggerIntersections.toArray());
|
this._previousTriggerIntersections.union(this._activeTriggerIntersections);
|
||||||
// 清空活动集,为下一帧做准备
|
// 清空活动集,为下一帧做准备
|
||||||
this._activeTriggerIntersections.clear();
|
this._activeTriggerIntersections.clear();
|
||||||
};
|
};
|
||||||
@@ -14079,17 +14099,85 @@ var es;
|
|||||||
};
|
};
|
||||||
Pair.prototype.equals = function (other) {
|
Pair.prototype.equals = function (other) {
|
||||||
// 这两种方法在功能上应该是等价的
|
// 这两种方法在功能上应该是等价的
|
||||||
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;
|
||||||
})(es || (es = {}));
|
})(es || (es = {}));
|
||||||
var es;
|
var es;
|
||||||
|
(function (es) {
|
||||||
|
var PairSet = /** @class */ (function () {
|
||||||
|
function PairSet() {
|
||||||
|
this._all = new Array();
|
||||||
|
}
|
||||||
|
Object.defineProperty(PairSet.prototype, "all", {
|
||||||
|
get: function () {
|
||||||
|
return this._all;
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
PairSet.prototype.has = function (pair) {
|
||||||
|
var index = this._all.findIndex(function (p) { return p.equals(pair); });
|
||||||
|
return index > -1;
|
||||||
|
};
|
||||||
|
PairSet.prototype.add = function (pair) {
|
||||||
|
if (!this.has(pair)) {
|
||||||
|
this._all.push(pair);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
PairSet.prototype.remove = function (pair) {
|
||||||
|
var index = this._all.findIndex(function (p) { return p.equals(pair); });
|
||||||
|
if (index > -1) {
|
||||||
|
var temp = this._all[index];
|
||||||
|
this._all[index] = this._all[this._all.length - 1];
|
||||||
|
this._all[this._all.length - 1] = temp;
|
||||||
|
this._all = this._all.slice(0, this._all.length - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
PairSet.prototype.clear = function () {
|
||||||
|
this._all = [];
|
||||||
|
};
|
||||||
|
PairSet.prototype.union = function (other) {
|
||||||
|
var e_12, _a;
|
||||||
|
var otherAll = other.all;
|
||||||
|
try {
|
||||||
|
for (var otherAll_1 = __values(otherAll), otherAll_1_1 = otherAll_1.next(); !otherAll_1_1.done; otherAll_1_1 = otherAll_1.next()) {
|
||||||
|
var elem = otherAll_1_1.value;
|
||||||
|
this.add(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e_12_1) { e_12 = { error: e_12_1 }; }
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
if (otherAll_1_1 && !otherAll_1_1.done && (_a = otherAll_1.return)) _a.call(otherAll_1);
|
||||||
|
}
|
||||||
|
finally { if (e_12) throw e_12.error; }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
PairSet.prototype.except = function (other) {
|
||||||
|
var e_13, _a;
|
||||||
|
var otherAll = other.all;
|
||||||
|
try {
|
||||||
|
for (var otherAll_2 = __values(otherAll), otherAll_2_1 = otherAll_2.next(); !otherAll_2_1.done; otherAll_2_1 = otherAll_2.next()) {
|
||||||
|
var elem = otherAll_2_1.value;
|
||||||
|
this.remove(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e_13_1) { e_13 = { error: e_13_1 }; }
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
if (otherAll_2_1 && !otherAll_2_1.done && (_a = otherAll_2.return)) _a.call(otherAll_2);
|
||||||
|
}
|
||||||
|
finally { if (e_13) throw e_13.error; }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return PairSet;
|
||||||
|
}());
|
||||||
|
es.PairSet = PairSet;
|
||||||
|
})(es || (es = {}));
|
||||||
|
var es;
|
||||||
(function (es) {
|
(function (es) {
|
||||||
/**
|
/**
|
||||||
* 用于池任何对象
|
* 用于池任何对象
|
||||||
@@ -14158,184 +14246,6 @@ var es;
|
|||||||
es.isIPoolable = function (props) { return typeof props['reset'] !== 'undefined'; };
|
es.isIPoolable = function (props) { return typeof props['reset'] !== 'undefined'; };
|
||||||
})(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);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* 确定当前集合是否为指定集合或数组的子集
|
|
||||||
* @param other
|
|
||||||
*/
|
|
||||||
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); });
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* 确定当前不可变排序集是否为指定集合的超集
|
|
||||||
* @param other
|
|
||||||
*/
|
|
||||||
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) {
|
||||||
var Coroutine = /** @class */ (function () {
|
var Coroutine = /** @class */ (function () {
|
||||||
function Coroutine() {
|
function Coroutine() {
|
||||||
@@ -16227,7 +16137,7 @@ var es;
|
|||||||
* 创建一个Set从一个Enumerable.List< T>。
|
* 创建一个Set从一个Enumerable.List< T>。
|
||||||
*/
|
*/
|
||||||
List.prototype.toSet = function () {
|
List.prototype.toSet = function () {
|
||||||
var e_12, _a;
|
var e_14, _a;
|
||||||
var result = new Set();
|
var result = new Set();
|
||||||
try {
|
try {
|
||||||
for (var _b = __values(this._elements), _c = _b.next(); !_c.done; _c = _b.next()) {
|
for (var _b = __values(this._elements), _c = _b.next(); !_c.done; _c = _b.next()) {
|
||||||
@@ -16235,12 +16145,12 @@ var es;
|
|||||||
result.add(x);
|
result.add(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e_12_1) { e_12 = { error: e_12_1 }; }
|
catch (e_14_1) { e_14 = { error: e_14_1 }; }
|
||||||
finally {
|
finally {
|
||||||
try {
|
try {
|
||||||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
||||||
}
|
}
|
||||||
finally { if (e_12) throw e_12.error; }
|
finally { if (e_14) throw e_14.error; }
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
@@ -16489,7 +16399,7 @@ var es;
|
|||||||
* 计算可见性多边形,并返回三角形扇形的顶点(减去中心顶点)。返回的数组来自ListPool
|
* 计算可见性多边形,并返回三角形扇形的顶点(减去中心顶点)。返回的数组来自ListPool
|
||||||
*/
|
*/
|
||||||
VisibilityComputer.prototype.end = function () {
|
VisibilityComputer.prototype.end = function () {
|
||||||
var e_13, _a;
|
var e_15, _a;
|
||||||
var output = es.ListPool.obtain(es.Vector2);
|
var output = es.ListPool.obtain(es.Vector2);
|
||||||
this.updateSegments();
|
this.updateSegments();
|
||||||
this._endPoints.sort(this._radialComparer.compare);
|
this._endPoints.sort(this._radialComparer.compare);
|
||||||
@@ -16528,12 +16438,12 @@ var es;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e_13_1) { e_13 = { error: e_13_1 }; }
|
catch (e_15_1) { e_15 = { error: e_15_1 }; }
|
||||||
finally {
|
finally {
|
||||||
try {
|
try {
|
||||||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
||||||
}
|
}
|
||||||
finally { if (e_13) throw e_13.error; }
|
finally { if (e_15) throw e_15.error; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VisibilityComputer._openSegments.clear();
|
VisibilityComputer._openSegments.clear();
|
||||||
@@ -16649,7 +16559,7 @@ var es;
|
|||||||
* 处理片段,以便我们稍后对它们进行分类
|
* 处理片段,以便我们稍后对它们进行分类
|
||||||
*/
|
*/
|
||||||
VisibilityComputer.prototype.updateSegments = function () {
|
VisibilityComputer.prototype.updateSegments = function () {
|
||||||
var e_14, _a;
|
var e_16, _a;
|
||||||
try {
|
try {
|
||||||
for (var _b = __values(this._segments), _c = _b.next(); !_c.done; _c = _b.next()) {
|
for (var _b = __values(this._segments), _c = _b.next(); !_c.done; _c = _b.next()) {
|
||||||
var segment = _c.value;
|
var segment = _c.value;
|
||||||
@@ -16667,12 +16577,12 @@ var es;
|
|||||||
segment.p2.begin = !segment.p1.begin;
|
segment.p2.begin = !segment.p1.begin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e_14_1) { e_14 = { error: e_14_1 }; }
|
catch (e_16_1) { e_16 = { error: e_16_1 }; }
|
||||||
finally {
|
finally {
|
||||||
try {
|
try {
|
||||||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
||||||
}
|
}
|
||||||
finally { if (e_14) throw e_14.error; }
|
finally { if (e_16) throw e_16.error; }
|
||||||
}
|
}
|
||||||
// 如果我们有一个聚光灯,我们需要存储前两个段的角度。
|
// 如果我们有一个聚光灯,我们需要存储前两个段的角度。
|
||||||
// 这些是光斑的边界,我们将用它们来过滤它们之外的任何顶点。
|
// 这些是光斑的边界,我们将用它们来过滤它们之外的任何顶点。
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -562,10 +562,6 @@ module es {
|
|||||||
return this.compareTo(other) == 0;
|
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}]`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,5 +60,17 @@ module es {
|
|||||||
public static invertFlags(self: Ref<number>) {
|
public static invertFlags(self: Ref<number>) {
|
||||||
self.value = ~self.value;
|
self.value = ~self.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打印 number 的二进制表示。 方便调试 number 标志
|
||||||
|
*/
|
||||||
|
public static binaryStringRepresentation(self: number,
|
||||||
|
leftPadWidth: number = 10) {
|
||||||
|
let str = self.toString(2);
|
||||||
|
while (str.length < (leftPadWidth || 2)) {
|
||||||
|
str = '0' + str;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ module es {
|
|||||||
export class ColliderTriggerHelper {
|
export class ColliderTriggerHelper {
|
||||||
private _entity: Entity;
|
private _entity: Entity;
|
||||||
/** 存储当前帧中发生的所有活动交点对 */
|
/** 存储当前帧中发生的所有活动交点对 */
|
||||||
private _activeTriggerIntersections: HashSet<Pair<Collider>> = new HashSet<Pair<Collider>>();
|
private _activeTriggerIntersections: PairSet<Collider> = new PairSet<Collider>();
|
||||||
/** 存储前一帧的交点对,这样我们就可以在移动这一帧后检测到退出 */
|
/** 存储前一帧的交点对,这样我们就可以在移动这一帧后检测到退出 */
|
||||||
private _previousTriggerIntersections: HashSet<Pair<Collider>> = new HashSet<Pair<Collider>>();
|
private _previousTriggerIntersections: PairSet<Collider> = new PairSet<Collider>();
|
||||||
private _tempTriggerList: ITriggerListener[] = [];
|
private _tempTriggerList: ITriggerListener[] = [];
|
||||||
|
|
||||||
constructor(entity: Entity) {
|
constructor(entity: Entity) {
|
||||||
@@ -22,11 +22,11 @@ module es {
|
|||||||
const lateColliders = [];
|
const lateColliders = [];
|
||||||
// 对所有实体.colliders进行重叠检查,这些实体.colliders是触发器,与所有宽相碰撞器,无论是否触发器。
|
// 对所有实体.colliders进行重叠检查,这些实体.colliders是触发器,与所有宽相碰撞器,无论是否触发器。
|
||||||
// 任何重叠都会导致触发事件
|
// 任何重叠都会导致触发事件
|
||||||
let colliders = this._entity.getComponents(Collider);
|
let colliders: Collider[] = this.getColliders();
|
||||||
for (let i = 0; i < colliders.length; i++) {
|
for (let i = 0; i < colliders.length; i++) {
|
||||||
let collider = colliders[i];
|
let collider = colliders[i];
|
||||||
|
|
||||||
let neighbors = Physics.boxcastBroadphaseExcludingSelf(collider.bounds, collider.collidesWithLayers);
|
let neighbors = Physics.boxcastBroadphaseExcludingSelf(collider, collider.bounds, collider.collidesWithLayers.value);
|
||||||
for (let j = 0; j < neighbors.length; j++) {
|
for (let j = 0; j < neighbors.length; j++) {
|
||||||
let neighbor = neighbors[j];
|
let neighbor = neighbors[j];
|
||||||
// 我们至少需要一个碰撞器作为触发器
|
// 我们至少需要一个碰撞器作为触发器
|
||||||
@@ -37,8 +37,8 @@ module es {
|
|||||||
const pair = new Pair<Collider>(collider, neighbor);
|
const pair = new Pair<Collider>(collider, neighbor);
|
||||||
|
|
||||||
// 如果我们的某一个集合中已经有了这个对子(前一个或当前的触发交叉点),就不要调用输入事件了
|
// 如果我们的某一个集合中已经有了这个对子(前一个或当前的触发交叉点),就不要调用输入事件了
|
||||||
const shouldReportTriggerEvent = !this._activeTriggerIntersections.contains(pair) &&
|
const shouldReportTriggerEvent = !this._activeTriggerIntersections.has(pair) &&
|
||||||
!this._previousTriggerIntersections.contains(pair);
|
!this._previousTriggerIntersections.has(pair);
|
||||||
|
|
||||||
if (shouldReportTriggerEvent) {
|
if (shouldReportTriggerEvent) {
|
||||||
if (neighbor.castSortOrder >= Collider.lateSortOrder) {
|
if (neighbor.castSortOrder >= Collider.lateSortOrder) {
|
||||||
@@ -60,18 +60,30 @@ module es {
|
|||||||
this.checkForExitedColliders();
|
this.checkForExitedColliders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getColliders() {
|
||||||
|
const colliders: Collider[] = [];
|
||||||
|
for (let i = 0; i < this._entity.components.buffer.length; i ++) {
|
||||||
|
const component = this._entity.components.buffer[i];
|
||||||
|
if (component instanceof Collider) {
|
||||||
|
colliders.push(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return colliders;
|
||||||
|
}
|
||||||
|
|
||||||
private checkForExitedColliders() {
|
private checkForExitedColliders() {
|
||||||
// 删除所有与此帧交互的触发器,留下我们退出的触发器
|
// 删除所有与此帧交互的触发器,留下我们退出的触发器
|
||||||
this._previousTriggerIntersections.exceptWith(this._activeTriggerIntersections.toArray());
|
this._previousTriggerIntersections.except(this._activeTriggerIntersections);
|
||||||
|
const all = this._previousTriggerIntersections.all;
|
||||||
for (let i = 0; i < this._previousTriggerIntersections.getCount(); i++) {
|
all.forEach(pair => {
|
||||||
this.notifyTriggerListeners(this._previousTriggerIntersections[i], false)
|
this.notifyTriggerListeners(pair, false);
|
||||||
}
|
});
|
||||||
|
|
||||||
this._previousTriggerIntersections.clear();
|
this._previousTriggerIntersections.clear();
|
||||||
|
|
||||||
// 添加所有当前激活的触发器
|
// 添加所有当前激活的触发器
|
||||||
this._previousTriggerIntersections.unionWith(this._activeTriggerIntersections.toArray());
|
this._previousTriggerIntersections.union(this._activeTriggerIntersections);
|
||||||
|
|
||||||
// 清空活动集,为下一帧做准备
|
// 清空活动集,为下一帧做准备
|
||||||
this._activeTriggerIntersections.clear();
|
this._activeTriggerIntersections.clear();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ module es {
|
|||||||
/**
|
/**
|
||||||
* 用于管理一对对象的简单DTO
|
* 用于管理一对对象的简单DTO
|
||||||
*/
|
*/
|
||||||
export class Pair<T> implements IEqualityComparable {
|
export class Pair<T> {
|
||||||
public first: T;
|
public first: T;
|
||||||
public second: T;
|
public second: T;
|
||||||
|
|
||||||
@@ -17,12 +17,7 @@ module es {
|
|||||||
|
|
||||||
public equals(other: Pair<T>): boolean {
|
public equals(other: Pair<T>): boolean {
|
||||||
// 这两种方法在功能上应该是等价的
|
// 这两种方法在功能上应该是等价的
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
module es {
|
||||||
|
export class PairSet<T> {
|
||||||
|
public get all(): Array<Pair<T>> {
|
||||||
|
return this._all;
|
||||||
|
}
|
||||||
|
|
||||||
|
public has(pair: Pair<T>) {
|
||||||
|
const index = this._all.findIndex(p => p.equals(pair));
|
||||||
|
return index > -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public add(pair: Pair<T>) {
|
||||||
|
if (!this.has(pair)) {
|
||||||
|
this._all.push(pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public remove(pair: Pair<T>) {
|
||||||
|
const index = this._all.findIndex(p => p.equals(pair));
|
||||||
|
if (index > -1) {
|
||||||
|
const temp = this._all[index];
|
||||||
|
this._all[index] = this._all[this._all.length - 1];
|
||||||
|
this._all[this._all.length - 1] = temp;
|
||||||
|
this._all = this._all.slice(0, this._all.length - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public clear() {
|
||||||
|
this._all = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public union(other: PairSet<T>) {
|
||||||
|
const otherAll = other.all;
|
||||||
|
for (const elem of otherAll) {
|
||||||
|
this.add(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public except(other: PairSet<T>) {
|
||||||
|
const otherAll = other.all;
|
||||||
|
for (const elem of otherAll) {
|
||||||
|
this.remove(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _all: Array<Pair<T>> = new Array<Pair<T>>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,212 +0,0 @@
|
|||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 确定当前集合是否为指定集合或数组的子集
|
|
||||||
* @param other
|
|
||||||
*/
|
|
||||||
isSubsetOf(other: Array<T>) {
|
|
||||||
|
|
||||||
let otherBuckets = this.buildInternalBuckets(other);
|
|
||||||
return this.toArray().every(value => this.bucketsContains(otherBuckets.Buckets, value));
|
|
||||||
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 确定当前不可变排序集是否为指定集合的超集
|
|
||||||
* @param other
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,10 +8,5 @@ module es {
|
|||||||
* @param other
|
* @param other
|
||||||
*/
|
*/
|
||||||
equals(other: any): boolean;
|
equals(other: any): boolean;
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成对象的哈希码
|
|
||||||
*/
|
|
||||||
getHashCode(): number;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user