Files
esengine/src/ECS/Utils/Bits.ts

164 lines
4.2 KiB
TypeScript
Raw Normal View History

/**
*
*
*/
export class Bits {
private _words: number[] = [];
private static readonly WORD_SIZE = 32;
constructor() {
this._words = [];
}
/**
* 1
* @param index
*/
public set(index: number): void {
const wordIndex = Math.floor(index / Bits.WORD_SIZE);
const bitIndex = index % Bits.WORD_SIZE;
// 确保数组足够大
while (this._words.length <= wordIndex) {
this._words.push(0);
}
this._words[wordIndex] |= (1 << bitIndex);
}
2021-05-07 16:23:15 +08:00
/**
* 0
* @param index
*/
public clear(index: number): void {
const wordIndex = Math.floor(index / Bits.WORD_SIZE);
const bitIndex = index % Bits.WORD_SIZE;
if (wordIndex < this._words.length) {
this._words[wordIndex] &= ~(1 << bitIndex);
2021-05-07 16:23:15 +08:00
}
}
2021-05-07 16:23:15 +08:00
/**
*
* @param index
* @returns true或false
*/
public get(index: number): boolean {
const wordIndex = Math.floor(index / Bits.WORD_SIZE);
const bitIndex = index % Bits.WORD_SIZE;
if (wordIndex >= this._words.length) {
return false;
2021-05-07 16:23:15 +08:00
}
return (this._words[wordIndex] & (1 << bitIndex)) !== 0;
2021-05-07 16:23:15 +08:00
}
/**
*
* @param other Bits对象
* @returns true
*/
public containsAll(other: Bits): boolean {
const maxLength = Math.max(this._words.length, other._words.length);
for (let i = 0; i < maxLength; i++) {
const thisWord = i < this._words.length ? this._words[i] : 0;
const otherWord = i < other._words.length ? other._words[i] : 0;
if ((thisWord & otherWord) !== otherWord) {
return false;
}
}
return true;
}
/**
*
* @param other Bits对象
* @returns true
*/
public intersects(other: Bits): boolean {
const minLength = Math.min(this._words.length, other._words.length);
for (let i = 0; i < minLength; i++) {
if ((this._words[i] & other._words[i]) !== 0) {
return true;
}
}
return false;
}
/**
*
* @param other Bits对象
* @returns true
*/
public excludes(other: Bits): boolean {
return !this.intersects(other);
}
/**
*
*/
public clearAll(): void {
this._words.length = 0;
}
/**
*
* @returns true
*/
public isEmpty(): boolean {
for (const word of this._words) {
if (word !== 0) {
return false;
}
}
return true;
}
/**
*
* @returns
*/
public cardinality(): number {
let count = 0;
for (const word of this._words) {
count += this.popCount(word);
}
return count;
}
/**
* 32
* @param n 32
* @returns
*/
private popCount(n: number): number {
n = n - ((n >>> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >>> 2) & 0x33333333);
return (((n + (n >>> 4)) & 0xF0F0F0F) * 0x1010101) >>> 24;
}
/**
* Bits对象
* @param other Bits对象
*/
public copyFrom(other: Bits): void {
this._words = [...other._words];
}
/**
* Bits的副本
* @returns Bits对象
*/
public clone(): Bits {
const newBits = new Bits();
newBits.copyFrom(this);
return newBits;
}
2021-05-07 16:23:15 +08:00
}