把掩码从BigInt-like多态都改成Mask64
This commit is contained in:
@@ -1,205 +1,15 @@
|
|||||||
import { Component } from '../Component';
|
import { Component } from '../Component';
|
||||||
import { IBigIntLike, BigIntFactory } from '../Utils/BigIntCompatibility';
|
import { BitMask64Utils, BitMask64Data } from '../Utils/BigIntCompatibility';
|
||||||
import { SoAStorage, EnableSoA, HighPrecision, Float64, Int32, SerializeMap, SerializeSet, SerializeArray, DeepCopy } from './SoAStorage';
|
import { SoAStorage, EnableSoA, HighPrecision, Float64, Int32, SerializeMap, SerializeSet, SerializeArray, DeepCopy } from './SoAStorage';
|
||||||
import { createLogger } from '../../Utils/Logger';
|
import { createLogger } from '../../Utils/Logger';
|
||||||
import { getComponentTypeName } from '../Decorators';
|
import { getComponentTypeName } from '../Decorators';
|
||||||
|
import { ComponentRegistry, ComponentType } from './ComponentStorage/ComponentRegistry';
|
||||||
|
|
||||||
// 重新导出装饰器
|
// 重新导出装饰器和核心类型
|
||||||
export { EnableSoA, HighPrecision, Float64, Int32, SerializeMap, SerializeSet, SerializeArray, DeepCopy };
|
export { EnableSoA, HighPrecision, Float64, Int32, SerializeMap, SerializeSet, SerializeArray, DeepCopy };
|
||||||
|
export { ComponentRegistry, ComponentType };
|
||||||
|
|
||||||
/**
|
|
||||||
* 组件类型定义
|
|
||||||
* 支持任意构造函数签名,提供更好的类型安全性
|
|
||||||
*/
|
|
||||||
export type ComponentType<T extends Component = Component> = new (...args: any[]) => T;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 组件注册表
|
|
||||||
* 管理组件类型的位掩码分配
|
|
||||||
*/
|
|
||||||
export class ComponentRegistry {
|
|
||||||
protected static readonly _logger = createLogger('ComponentStorage');
|
|
||||||
private static componentTypes = new Map<Function, number>();
|
|
||||||
private static componentNameToType = new Map<string, Function>();
|
|
||||||
private static componentNameToId = new Map<string, number>();
|
|
||||||
private static maskCache = new Map<string, IBigIntLike>();
|
|
||||||
private static nextBitIndex = 0;
|
|
||||||
private static maxComponents = 64; // 支持最多64种组件类型
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 注册组件类型并分配位掩码
|
|
||||||
* @param componentType 组件类型
|
|
||||||
* @returns 分配的位索引
|
|
||||||
*/
|
|
||||||
public static register<T extends Component>(componentType: ComponentType<T>): number {
|
|
||||||
if (this.componentTypes.has(componentType)) {
|
|
||||||
return this.componentTypes.get(componentType)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.nextBitIndex >= this.maxComponents) {
|
|
||||||
throw new Error(`Maximum number of component types (${this.maxComponents}) exceeded`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const bitIndex = this.nextBitIndex++;
|
|
||||||
this.componentTypes.set(componentType, bitIndex);
|
|
||||||
this.componentNameToType.set(getComponentTypeName(componentType), componentType);
|
|
||||||
this.componentNameToId.set(getComponentTypeName(componentType), bitIndex);
|
|
||||||
return bitIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取组件类型的位掩码
|
|
||||||
* @param componentType 组件类型
|
|
||||||
* @returns 位掩码
|
|
||||||
*/
|
|
||||||
public static getBitMask<T extends Component>(componentType: ComponentType<T>): IBigIntLike {
|
|
||||||
const bitIndex = this.componentTypes.get(componentType);
|
|
||||||
if (bitIndex === undefined) {
|
|
||||||
throw new Error(`Component type ${getComponentTypeName(componentType)} is not registered`);
|
|
||||||
}
|
|
||||||
return BigIntFactory.one().shiftLeft(bitIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取组件类型的位索引
|
|
||||||
* @param componentType 组件类型
|
|
||||||
* @returns 位索引
|
|
||||||
*/
|
|
||||||
public static getBitIndex<T extends Component>(componentType: ComponentType<T>): number {
|
|
||||||
const bitIndex = this.componentTypes.get(componentType);
|
|
||||||
if (bitIndex === undefined) {
|
|
||||||
throw new Error(`Component type ${getComponentTypeName(componentType)} is not registered`);
|
|
||||||
}
|
|
||||||
return bitIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查组件类型是否已注册
|
|
||||||
* @param componentType 组件类型
|
|
||||||
* @returns 是否已注册
|
|
||||||
*/
|
|
||||||
public static isRegistered<T extends Component>(componentType: ComponentType<T>): boolean {
|
|
||||||
return this.componentTypes.has(componentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过名称获取组件类型
|
|
||||||
* @param componentName 组件名称
|
|
||||||
* @returns 组件类型构造函数
|
|
||||||
*/
|
|
||||||
public static getComponentType(componentName: string): Function | null {
|
|
||||||
return this.componentNameToType.get(componentName) || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取所有已注册的组件类型
|
|
||||||
* @returns 组件类型映射
|
|
||||||
*/
|
|
||||||
public static getAllRegisteredTypes(): Map<Function, number> {
|
|
||||||
return new Map(this.componentTypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取所有组件名称到类型的映射
|
|
||||||
* @returns 名称到类型的映射
|
|
||||||
*/
|
|
||||||
public static getAllComponentNames(): Map<string, Function> {
|
|
||||||
return new Map(this.componentNameToType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过名称获取组件类型ID
|
|
||||||
* @param componentName 组件名称
|
|
||||||
* @returns 组件类型ID
|
|
||||||
*/
|
|
||||||
public static getComponentId(componentName: string): number | undefined {
|
|
||||||
return this.componentNameToId.get(componentName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 注册组件类型(通过名称)
|
|
||||||
* @param componentName 组件名称
|
|
||||||
* @returns 分配的组件ID
|
|
||||||
*/
|
|
||||||
public static registerComponentByName(componentName: string): number {
|
|
||||||
if (this.componentNameToId.has(componentName)) {
|
|
||||||
return this.componentNameToId.get(componentName)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.nextBitIndex >= this.maxComponents) {
|
|
||||||
throw new Error(`Maximum number of component types (${this.maxComponents}) exceeded`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const bitIndex = this.nextBitIndex++;
|
|
||||||
this.componentNameToId.set(componentName, bitIndex);
|
|
||||||
return bitIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建单个组件的掩码
|
|
||||||
* @param componentName 组件名称
|
|
||||||
* @returns 组件掩码
|
|
||||||
*/
|
|
||||||
public static createSingleComponentMask(componentName: string): IBigIntLike {
|
|
||||||
const cacheKey = `single:${componentName}`;
|
|
||||||
|
|
||||||
if (this.maskCache.has(cacheKey)) {
|
|
||||||
return this.maskCache.get(cacheKey)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
const componentId = this.getComponentId(componentName);
|
|
||||||
if (componentId === undefined) {
|
|
||||||
throw new Error(`Component type ${componentName} is not registered`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const mask = BigIntFactory.one().shiftLeft(componentId);
|
|
||||||
this.maskCache.set(cacheKey, mask);
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建多个组件的掩码
|
|
||||||
* @param componentNames 组件名称数组
|
|
||||||
* @returns 组合掩码
|
|
||||||
*/
|
|
||||||
public static createComponentMask(componentNames: string[]): IBigIntLike {
|
|
||||||
const sortedNames = [...componentNames].sort();
|
|
||||||
const cacheKey = `multi:${sortedNames.join(',')}`;
|
|
||||||
|
|
||||||
if (this.maskCache.has(cacheKey)) {
|
|
||||||
return this.maskCache.get(cacheKey)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mask = BigIntFactory.zero();
|
|
||||||
for (const name of componentNames) {
|
|
||||||
const componentId = this.getComponentId(name);
|
|
||||||
if (componentId !== undefined) {
|
|
||||||
mask = mask.or(BigIntFactory.one().shiftLeft(componentId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.maskCache.set(cacheKey, mask);
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清除掩码缓存
|
|
||||||
*/
|
|
||||||
public static clearMaskCache(): void {
|
|
||||||
this.maskCache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重置注册表(用于测试)
|
|
||||||
*/
|
|
||||||
public static reset(): void {
|
|
||||||
this.componentTypes.clear();
|
|
||||||
this.componentNameToType.clear();
|
|
||||||
this.componentNameToId.clear();
|
|
||||||
this.maskCache.clear();
|
|
||||||
this.nextBitIndex = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 高性能组件存储器
|
* 高性能组件存储器
|
||||||
@@ -532,13 +342,13 @@ export class ComponentStorageManager {
|
|||||||
* @param entityId 实体ID
|
* @param entityId 实体ID
|
||||||
* @returns 组件位掩码
|
* @returns 组件位掩码
|
||||||
*/
|
*/
|
||||||
public getComponentMask(entityId: number): IBigIntLike {
|
public getComponentMask(entityId: number): BitMask64Data {
|
||||||
let mask = BigIntFactory.zero();
|
let mask = BitMask64Utils.clone(BitMask64Utils.ZERO);
|
||||||
|
|
||||||
for (const [componentType, storage] of this.storages.entries()) {
|
for (const [componentType, storage] of this.storages.entries()) {
|
||||||
if (storage.hasComponent(entityId)) {
|
if (storage.hasComponent(entityId)) {
|
||||||
const componentMask = ComponentRegistry.getBitMask(componentType as ComponentType);
|
const componentMask = ComponentRegistry.getBitMask(componentType as ComponentType);
|
||||||
mask = mask.or(componentMask);
|
BitMask64Utils.orInPlace(mask, componentMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Component } from '../../Component';
|
import { Component } from '../../Component';
|
||||||
import { IBigIntLike, BigIntFactory } from '../../Utils/BigIntCompatibility';
|
import { BitMask64Utils, BitMask64Data } from '../../Utils/BigIntCompatibility';
|
||||||
import { createLogger } from '../../../Utils/Logger';
|
import { createLogger } from '../../../Utils/Logger';
|
||||||
import { getComponentTypeName } from '../../Decorators';
|
import { getComponentTypeName } from '../../Decorators';
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ export class ComponentRegistry {
|
|||||||
private static componentTypes = new Map<Function, number>();
|
private static componentTypes = new Map<Function, number>();
|
||||||
private static componentNameToType = new Map<string, Function>();
|
private static componentNameToType = new Map<string, Function>();
|
||||||
private static componentNameToId = new Map<string, number>();
|
private static componentNameToId = new Map<string, number>();
|
||||||
private static maskCache = new Map<string, IBigIntLike>();
|
private static maskCache = new Map<string, BitMask64Data>();
|
||||||
private static nextBitIndex = 0;
|
private static nextBitIndex = 0;
|
||||||
private static maxComponents = 64; // 支持最多64种组件类型
|
private static maxComponents = 64; // 支持最多64种组件类型
|
||||||
|
|
||||||
@@ -51,13 +51,13 @@ export class ComponentRegistry {
|
|||||||
* @param componentType 组件类型
|
* @param componentType 组件类型
|
||||||
* @returns 位掩码
|
* @returns 位掩码
|
||||||
*/
|
*/
|
||||||
public static getBitMask<T extends Component>(componentType: ComponentType<T>): IBigIntLike {
|
public static getBitMask<T extends Component>(componentType: ComponentType<T>): BitMask64Data {
|
||||||
const bitIndex = this.componentTypes.get(componentType);
|
const bitIndex = this.componentTypes.get(componentType);
|
||||||
if (bitIndex === undefined) {
|
if (bitIndex === undefined) {
|
||||||
const typeName = getComponentTypeName(componentType);
|
const typeName = getComponentTypeName(componentType);
|
||||||
throw new Error(`Component type ${typeName} is not registered`);
|
throw new Error(`Component type ${typeName} is not registered`);
|
||||||
}
|
}
|
||||||
return BigIntFactory.one().shiftLeft(bitIndex);
|
return BitMask64Utils.create(bitIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,7 +141,7 @@ export class ComponentRegistry {
|
|||||||
* @param componentName 组件名称
|
* @param componentName 组件名称
|
||||||
* @returns 组件掩码
|
* @returns 组件掩码
|
||||||
*/
|
*/
|
||||||
public static createSingleComponentMask(componentName: string): IBigIntLike {
|
public static createSingleComponentMask(componentName: string): BitMask64Data {
|
||||||
const cacheKey = `single:${componentName}`;
|
const cacheKey = `single:${componentName}`;
|
||||||
|
|
||||||
if (this.maskCache.has(cacheKey)) {
|
if (this.maskCache.has(cacheKey)) {
|
||||||
@@ -153,7 +153,7 @@ export class ComponentRegistry {
|
|||||||
throw new Error(`Component type ${componentName} is not registered`);
|
throw new Error(`Component type ${componentName} is not registered`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const mask = BigIntFactory.one().shiftLeft(componentId);
|
const mask = BitMask64Utils.create(componentId);
|
||||||
this.maskCache.set(cacheKey, mask);
|
this.maskCache.set(cacheKey, mask);
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
@@ -163,7 +163,7 @@ export class ComponentRegistry {
|
|||||||
* @param componentNames 组件名称数组
|
* @param componentNames 组件名称数组
|
||||||
* @returns 组合掩码
|
* @returns 组合掩码
|
||||||
*/
|
*/
|
||||||
public static createComponentMask(componentNames: string[]): IBigIntLike {
|
public static createComponentMask(componentNames: string[]): BitMask64Data {
|
||||||
const sortedNames = [...componentNames].sort();
|
const sortedNames = [...componentNames].sort();
|
||||||
const cacheKey = `multi:${sortedNames.join(',')}`;
|
const cacheKey = `multi:${sortedNames.join(',')}`;
|
||||||
|
|
||||||
@@ -171,11 +171,12 @@ export class ComponentRegistry {
|
|||||||
return this.maskCache.get(cacheKey)!;
|
return this.maskCache.get(cacheKey)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mask = BigIntFactory.zero();
|
let mask = BitMask64Utils.clone(BitMask64Utils.ZERO);
|
||||||
for (const name of componentNames) {
|
for (const name of componentNames) {
|
||||||
const componentId = this.getComponentId(name);
|
const componentId = this.getComponentId(name);
|
||||||
if (componentId !== undefined) {
|
if (componentId !== undefined) {
|
||||||
mask = mask.or(BigIntFactory.one().shiftLeft(componentId));
|
const componentMask = BitMask64Utils.create(componentId);
|
||||||
|
BitMask64Utils.orInPlace(mask, componentMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Entity } from '../Entity';
|
import { Entity } from '../Entity';
|
||||||
import { Component } from '../Component';
|
import { Component } from '../Component';
|
||||||
import { ComponentRegistry, ComponentType } from './ComponentStorage';
|
import { ComponentRegistry, ComponentType } from './ComponentStorage';
|
||||||
import { IBigIntLike, BigIntFactory } from '../Utils/BigIntCompatibility';
|
import { BitMask64Utils, BitMask64Data } from '../Utils/BigIntCompatibility';
|
||||||
import { createLogger } from '../../Utils/Logger';
|
import { createLogger } from '../../Utils/Logger';
|
||||||
import { getComponentTypeName } from '../Decorators';
|
import { getComponentTypeName } from '../Decorators';
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ export enum QueryConditionType {
|
|||||||
export interface QueryCondition {
|
export interface QueryCondition {
|
||||||
type: QueryConditionType;
|
type: QueryConditionType;
|
||||||
componentTypes: ComponentType[];
|
componentTypes: ComponentType[];
|
||||||
mask: IBigIntLike;
|
mask: BitMask64Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -483,7 +483,7 @@ export class QuerySystem {
|
|||||||
const result: Entity[] = [];
|
const result: Entity[] = [];
|
||||||
|
|
||||||
for (const entity of smallestSet) {
|
for (const entity of smallestSet) {
|
||||||
if (entity.componentMask.and(mask).equals(mask)) {
|
if (BitMask64Utils.hasAll(entity.componentMask, mask)) {
|
||||||
result.push(entity);
|
result.push(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -587,7 +587,7 @@ export class QuerySystem {
|
|||||||
|
|
||||||
const mask = this.createComponentMask(componentTypes);
|
const mask = this.createComponentMask(componentTypes);
|
||||||
const entities = this.entities.filter(entity =>
|
const entities = this.entities.filter(entity =>
|
||||||
entity.componentMask.and(mask).isZero()
|
BitMask64Utils.hasNone(entity.componentMask, mask)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.addToCache(cacheKey, entities);
|
this.addToCache(cacheKey, entities);
|
||||||
@@ -872,14 +872,14 @@ export class QuerySystem {
|
|||||||
* @param componentTypes 组件类型列表
|
* @param componentTypes 组件类型列表
|
||||||
* @returns 生成的位掩码
|
* @returns 生成的位掩码
|
||||||
*/
|
*/
|
||||||
private createComponentMask(componentTypes: ComponentType[]): IBigIntLike {
|
private createComponentMask(componentTypes: ComponentType[]): BitMask64Data {
|
||||||
let mask = BigIntFactory.zero();
|
let mask = BitMask64Utils.clone(BitMask64Utils.ZERO);
|
||||||
let hasValidComponents = false;
|
let hasValidComponents = false;
|
||||||
|
|
||||||
for (const type of componentTypes) {
|
for (const type of componentTypes) {
|
||||||
try {
|
try {
|
||||||
const bitMask = ComponentRegistry.getBitMask(type);
|
const bitMask = ComponentRegistry.getBitMask(type);
|
||||||
mask = mask.or(bitMask);
|
BitMask64Utils.orInPlace(mask, bitMask);
|
||||||
hasValidComponents = true;
|
hasValidComponents = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this._logger.warn(`组件类型 ${getComponentTypeName(type)} 未注册,跳过`);
|
this._logger.warn(`组件类型 ${getComponentTypeName(type)} 未注册,跳过`);
|
||||||
@@ -888,7 +888,7 @@ export class QuerySystem {
|
|||||||
|
|
||||||
// 如果没有有效的组件类型,返回一个不可能匹配的掩码
|
// 如果没有有效的组件类型,返回一个不可能匹配的掩码
|
||||||
if (!hasValidComponents) {
|
if (!hasValidComponents) {
|
||||||
return BigIntFactory.create(-1); // 所有位都是1,不可能与任何实体匹配
|
return { lo: 0xFFFFFFFF, hi: 0xFFFFFFFF }; // 所有位都是1,不可能与任何实体匹配
|
||||||
}
|
}
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
@@ -1134,12 +1134,12 @@ export class QueryBuilder {
|
|||||||
/**
|
/**
|
||||||
* 创建组件掩码
|
* 创建组件掩码
|
||||||
*/
|
*/
|
||||||
private createComponentMask(componentTypes: ComponentType[]): IBigIntLike {
|
private createComponentMask(componentTypes: ComponentType[]): BitMask64Data {
|
||||||
let mask = BigIntFactory.zero();
|
let mask = BitMask64Utils.clone(BitMask64Utils.ZERO);
|
||||||
for (const type of componentTypes) {
|
for (const type of componentTypes) {
|
||||||
try {
|
try {
|
||||||
const bitMask = ComponentRegistry.getBitMask(type);
|
const bitMask = ComponentRegistry.getBitMask(type);
|
||||||
mask = mask.or(bitMask);
|
BitMask64Utils.orInPlace(mask, bitMask);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this._logger.warn(`组件类型 ${getComponentTypeName(type)} 未注册,跳过`);
|
this._logger.warn(`组件类型 ${getComponentTypeName(type)} 未注册,跳过`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Component } from './Component';
|
import { Component } from './Component';
|
||||||
import { ComponentRegistry, ComponentType } from './Core/ComponentStorage';
|
import { ComponentRegistry, ComponentType } from './Core/ComponentStorage';
|
||||||
import { EventBus } from './Core/EventBus';
|
import { EventBus } from './Core/EventBus';
|
||||||
import { IBigIntLike, BigIntFactory } from './Utils/BigIntCompatibility';
|
import { BitMask64Utils, BitMask64Data } from './Utils/BigIntCompatibility';
|
||||||
import { createLogger } from '../Utils/Logger';
|
import { createLogger } from '../Utils/Logger';
|
||||||
import { getComponentInstanceTypeName, getComponentTypeName } from './Decorators';
|
import { getComponentInstanceTypeName, getComponentTypeName } from './Decorators';
|
||||||
import type { IScene } from './IScene';
|
import type { IScene } from './IScene';
|
||||||
@@ -161,7 +161,7 @@ export class Entity {
|
|||||||
*
|
*
|
||||||
* 用于快速查询实体拥有的组件类型。
|
* 用于快速查询实体拥有的组件类型。
|
||||||
*/
|
*/
|
||||||
private _componentMask: IBigIntLike = BigIntFactory.zero();
|
private _componentMask: BitMask64Data = BitMask64Utils.clone(BitMask64Utils.ZERO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按组件类型ID直址的稀疏数组
|
* 按组件类型ID直址的稀疏数组
|
||||||
@@ -310,7 +310,7 @@ export class Entity {
|
|||||||
*
|
*
|
||||||
* @returns 实体的组件位掩码
|
* @returns 实体的组件位掩码
|
||||||
*/
|
*/
|
||||||
public get componentMask(): IBigIntLike {
|
public get componentMask(): BitMask64Data {
|
||||||
return this._componentMask;
|
return this._componentMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,7 +354,7 @@ export class Entity {
|
|||||||
|
|
||||||
// 更新位掩码
|
// 更新位掩码
|
||||||
const componentMask = ComponentRegistry.getBitMask(componentType);
|
const componentMask = ComponentRegistry.getBitMask(componentType);
|
||||||
this._componentMask = this._componentMask.or(componentMask);
|
BitMask64Utils.orInPlace(this._componentMask, componentMask);
|
||||||
|
|
||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
@@ -422,7 +422,7 @@ export class Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mask = ComponentRegistry.getBitMask(type);
|
const mask = ComponentRegistry.getBitMask(type);
|
||||||
if (this._componentMask.and(mask).isZero()) {
|
if (BitMask64Utils.hasNone(this._componentMask, mask)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,7 +475,7 @@ export class Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mask = ComponentRegistry.getBitMask(type);
|
const mask = ComponentRegistry.getBitMask(type);
|
||||||
return !this._componentMask.and(mask).isZero();
|
return BitMask64Utils.hasAny(this._componentMask, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -510,8 +510,8 @@ export class Entity {
|
|||||||
this._componentsByTypeId[typeId] = undefined;
|
this._componentsByTypeId[typeId] = undefined;
|
||||||
|
|
||||||
// 更新位掩码
|
// 更新位掩码
|
||||||
const componentMask = ComponentRegistry.getBitMask(componentType);
|
const bitIndex = ComponentRegistry.getBitIndex(componentType);
|
||||||
this._componentMask = this._componentMask.and(componentMask.not());
|
BitMask64Utils.clearBit(this._componentMask, bitIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从迭代数组中移除
|
// 从迭代数组中移除
|
||||||
@@ -579,7 +579,7 @@ export class Entity {
|
|||||||
|
|
||||||
// 清空稀疏数组和位掩码
|
// 清空稀疏数组和位掩码
|
||||||
this._componentsByTypeId.length = 0;
|
this._componentsByTypeId.length = 0;
|
||||||
this._componentMask = BigIntFactory.zero();
|
BitMask64Utils.clear(this._componentMask);
|
||||||
|
|
||||||
// 移除组件
|
// 移除组件
|
||||||
for (const component of componentsToRemove) {
|
for (const component of componentsToRemove) {
|
||||||
@@ -981,7 +981,7 @@ export class Entity {
|
|||||||
destroyed: this._isDestroyed,
|
destroyed: this._isDestroyed,
|
||||||
componentCount: this.components.length,
|
componentCount: this.components.length,
|
||||||
componentTypes: this.components.map(c => getComponentInstanceTypeName(c)),
|
componentTypes: this.components.map(c => getComponentInstanceTypeName(c)),
|
||||||
componentMask: this._componentMask.toString(2), // 二进制表示
|
componentMask: BitMask64Utils.toString(this._componentMask, 2), // 二进制表示
|
||||||
parentId: this._parent?.id || null,
|
parentId: this._parent?.id || null,
|
||||||
childCount: this._children.length,
|
childCount: this._children.length,
|
||||||
childIds: this._children.map(c => c.id),
|
childIds: this._children.map(c => c.id),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Entity } from '../Entity';
|
import { Entity } from '../Entity';
|
||||||
import { ComponentType, ComponentRegistry } from '../Core/ComponentStorage';
|
import { ComponentType, ComponentRegistry } from '../Core/ComponentStorage';
|
||||||
import { IBigIntLike, BigIntFactory } from './BigIntCompatibility';
|
import { BitMask64Utils, BitMask64Data } from './BigIntCompatibility';
|
||||||
import { SparseSet } from './SparseSet';
|
import { SparseSet } from './SparseSet';
|
||||||
import { Pool } from '../../Utils/Pool/Pool';
|
import { Pool } from '../../Utils/Pool/Pool';
|
||||||
import { IPoolable } from '../../Utils/Pool/IPoolable';
|
import { IPoolable } from '../../Utils/Pool/IPoolable';
|
||||||
@@ -44,7 +44,7 @@ export class ComponentSparseSet {
|
|||||||
* 与实体稀疏集合的密集数组对应,存储每个实体的组件位掩码。
|
* 与实体稀疏集合的密集数组对应,存储每个实体的组件位掩码。
|
||||||
* 数组索引与稀疏集合的密集数组索引一一对应。
|
* 数组索引与稀疏集合的密集数组索引一一对应。
|
||||||
*/
|
*/
|
||||||
private _componentMasks: IBigIntLike[] = [];
|
private _componentMasks: BitMask64Data[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组件类型到实体集合的映射
|
* 组件类型到实体集合的映射
|
||||||
@@ -77,7 +77,7 @@ export class ComponentSparseSet {
|
|||||||
this.removeEntity(entity);
|
this.removeEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
let componentMask = BigIntFactory.zero();
|
let componentMask = BitMask64Utils.clone(BitMask64Utils.ZERO);
|
||||||
const entityComponents = new Set<ComponentType>();
|
const entityComponents = new Set<ComponentType>();
|
||||||
|
|
||||||
// 分析实体组件并构建位掩码
|
// 分析实体组件并构建位掩码
|
||||||
@@ -92,7 +92,7 @@ export class ComponentSparseSet {
|
|||||||
|
|
||||||
// 获取组件位掩码并合并
|
// 获取组件位掩码并合并
|
||||||
const bitMask = ComponentRegistry.getBitMask(componentType);
|
const bitMask = ComponentRegistry.getBitMask(componentType);
|
||||||
componentMask = componentMask.or(bitMask);
|
BitMask64Utils.orInPlace(componentMask, bitMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加实体到稀疏集合
|
// 添加实体到稀疏集合
|
||||||
@@ -101,7 +101,7 @@ export class ComponentSparseSet {
|
|||||||
|
|
||||||
// 确保位掩码数组有足够空间
|
// 确保位掩码数组有足够空间
|
||||||
while (this._componentMasks.length <= entityIndex) {
|
while (this._componentMasks.length <= entityIndex) {
|
||||||
this._componentMasks.push(BigIntFactory.zero());
|
this._componentMasks.push(BitMask64Utils.clone(BitMask64Utils.ZERO));
|
||||||
}
|
}
|
||||||
this._componentMasks[entityIndex] = componentMask;
|
this._componentMasks[entityIndex] = componentMask;
|
||||||
|
|
||||||
@@ -169,13 +169,13 @@ export class ComponentSparseSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 构建目标位掩码
|
// 构建目标位掩码
|
||||||
let targetMask = BigIntFactory.zero();
|
let targetMask = BitMask64Utils.clone(BitMask64Utils.ZERO);
|
||||||
for (const componentType of componentTypes) {
|
for (const componentType of componentTypes) {
|
||||||
if (!ComponentRegistry.isRegistered(componentType)) {
|
if (!ComponentRegistry.isRegistered(componentType)) {
|
||||||
return new Set<Entity>(); // 未注册的组件类型,结果为空
|
return new Set<Entity>(); // 未注册的组件类型,结果为空
|
||||||
}
|
}
|
||||||
const bitMask = ComponentRegistry.getBitMask(componentType);
|
const bitMask = ComponentRegistry.getBitMask(componentType);
|
||||||
targetMask = targetMask.or(bitMask);
|
BitMask64Utils.orInPlace(targetMask, bitMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = ComponentSparseSet._entitySetPool.obtain();
|
const result = ComponentSparseSet._entitySetPool.obtain();
|
||||||
@@ -183,7 +183,7 @@ export class ComponentSparseSet {
|
|||||||
// 遍历所有实体,检查位掩码匹配
|
// 遍历所有实体,检查位掩码匹配
|
||||||
this._entities.forEach((entity, index) => {
|
this._entities.forEach((entity, index) => {
|
||||||
const entityMask = this._componentMasks[index];
|
const entityMask = this._componentMasks[index];
|
||||||
if ((entityMask.and(targetMask)).equals(targetMask)) {
|
if (BitMask64Utils.hasAll(entityMask, targetMask)) {
|
||||||
result.add(entity);
|
result.add(entity);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -209,15 +209,15 @@ export class ComponentSparseSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 构建目标位掩码
|
// 构建目标位掩码
|
||||||
let targetMask = BigIntFactory.zero();
|
let targetMask = BitMask64Utils.clone(BitMask64Utils.ZERO);
|
||||||
for (const componentType of componentTypes) {
|
for (const componentType of componentTypes) {
|
||||||
if (ComponentRegistry.isRegistered(componentType)) {
|
if (ComponentRegistry.isRegistered(componentType)) {
|
||||||
const bitMask = ComponentRegistry.getBitMask(componentType);
|
const bitMask = ComponentRegistry.getBitMask(componentType);
|
||||||
targetMask = targetMask.or(bitMask);
|
BitMask64Utils.orInPlace(targetMask, bitMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetMask.equals(BigIntFactory.zero())) {
|
if (BitMask64Utils.equals(targetMask, BitMask64Utils.ZERO)) {
|
||||||
return new Set<Entity>(); // 没有有效的组件类型
|
return new Set<Entity>(); // 没有有效的组件类型
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +226,7 @@ export class ComponentSparseSet {
|
|||||||
// 遍历所有实体,检查位掩码匹配
|
// 遍历所有实体,检查位掩码匹配
|
||||||
this._entities.forEach((entity, index) => {
|
this._entities.forEach((entity, index) => {
|
||||||
const entityMask = this._componentMasks[index];
|
const entityMask = this._componentMasks[index];
|
||||||
if (!(entityMask.and(targetMask)).equals(BigIntFactory.zero())) {
|
if (BitMask64Utils.hasAny(entityMask, targetMask)) {
|
||||||
result.add(entity);
|
result.add(entity);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -254,7 +254,7 @@ export class ComponentSparseSet {
|
|||||||
const entityMask = this._componentMasks[entityIndex];
|
const entityMask = this._componentMasks[entityIndex];
|
||||||
const componentMask = ComponentRegistry.getBitMask(componentType);
|
const componentMask = ComponentRegistry.getBitMask(componentType);
|
||||||
|
|
||||||
return !(entityMask.and(componentMask)).equals(BigIntFactory.zero());
|
return BitMask64Utils.hasAny(entityMask, componentMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -263,7 +263,7 @@ export class ComponentSparseSet {
|
|||||||
* @param entity 实体
|
* @param entity 实体
|
||||||
* @returns 组件位掩码,如果实体不存在则返回undefined
|
* @returns 组件位掩码,如果实体不存在则返回undefined
|
||||||
*/
|
*/
|
||||||
public getEntityMask(entity: Entity): IBigIntLike | undefined {
|
public getEntityMask(entity: Entity): BitMask64Data | undefined {
|
||||||
const entityIndex = this._entities.getIndex(entity);
|
const entityIndex = this._entities.getIndex(entity);
|
||||||
if (entityIndex === undefined) {
|
if (entityIndex === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
@@ -299,7 +299,7 @@ export class ComponentSparseSet {
|
|||||||
*
|
*
|
||||||
* @param callback 遍历回调函数
|
* @param callback 遍历回调函数
|
||||||
*/
|
*/
|
||||||
public forEach(callback: (entity: Entity, mask: IBigIntLike, index: number) => void): void {
|
public forEach(callback: (entity: Entity, mask: BitMask64Data, index: number) => void): void {
|
||||||
this._entities.forEach((entity, index) => {
|
this._entities.forEach((entity, index) => {
|
||||||
callback(entity, this._componentMasks[index], index);
|
callback(entity, this._componentMasks[index], index);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user