移除 Entity._localComponents/强制Entity必须属于Scene/简化组件操作逻辑

This commit is contained in:
YHH
2025-10-10 16:31:43 +08:00
parent bf14b59a28
commit 62d7521384
12 changed files with 158 additions and 158 deletions

View File

@@ -14,7 +14,9 @@ export class EntityBuilder {
constructor(scene: IScene, storageManager: ComponentStorageManager) {
this.scene = scene;
this.storageManager = storageManager;
this.entity = new Entity("", scene.identifierPool.checkOut());
const id = scene.identifierPool.checkOut();
this.entity = new Entity("", id);
this.entity.scene = this.scene as any;
}
/**

View File

@@ -145,12 +145,6 @@ export class Entity {
*/
private _componentCache: Component[] | null = null;
/**
* 本地组件存储(用于没有 Scene 的 Entity
* 当 Entity 添加到 Scene 时,组件会迁移到 Scene 的 componentStorageManager
*/
private _localComponents: Map<ComponentType, Component> = new Map();
/**
* 构造函数
*
@@ -186,28 +180,23 @@ export class Entity {
*/
private _rebuildComponentCache(): void {
const components: Component[] = [];
const mask = this._componentMask;
if (!this.scene?.componentStorageManager) {
this._componentCache = components;
return;
}
const mask = this._componentMask;
const maxBitIndex = ComponentRegistry.getRegisteredCount();
for (let bitIndex = 0; bitIndex < maxBitIndex; bitIndex++) {
if (BitMask64Utils.getBit(mask, bitIndex)) {
const componentType = ComponentRegistry.getTypeByBitIndex(bitIndex);
if (componentType) {
let component: Component | null = null;
// 优先从 Scene 存储获取
if (this.scene?.componentStorageManager) {
component = this.scene.componentStorageManager.getComponent(
this.id,
componentType
);
}
// Fallback 到本地存储
if (!component) {
component = this._localComponents.get(componentType) || null;
}
const component = this.scene.componentStorageManager.getComponent(
this.id,
componentType
);
if (component) {
components.push(component);
@@ -378,9 +367,6 @@ export class Entity {
ComponentRegistry.register(componentType);
}
// 存储到本地 Map
this._localComponents.set(componentType, component);
// 更新位掩码
const componentMask = ComponentRegistry.getBitMask(componentType);
BitMask64Utils.orInPlace(this._componentMask, componentMask);
@@ -406,19 +392,25 @@ export class Entity {
*/
public addComponent<T extends Component>(component: T): T {
const componentType = component.constructor as ComponentType<T>;
if (!this.scene) {
throw new Error(`Entity must be added to Scene before adding components. Use scene.createEntity() instead of new Entity()`);
}
if (!this.scene.componentStorageManager) {
throw new Error(`Scene does not have componentStorageManager`);
}
if (this.hasComponent(componentType)) {
throw new Error(`Entity ${this.name} already has component ${getComponentTypeName(componentType)}`);
}
this.addComponentInternal(component);
if (this.scene && this.scene.componentStorageManager) {
this.scene.componentStorageManager.addComponent(this.id, component);
}
this.scene.componentStorageManager.addComponent(this.id, component);
component.onAddedToEntity();
if (Entity.eventBus) {
Entity.eventBus.emitComponentAdded({
timestamp: Date.now(),
@@ -430,7 +422,7 @@ export class Entity {
component: component
});
}
// 通知所有相关的QuerySystem组件已变动
Entity.notifyQuerySystems(this);
@@ -459,16 +451,13 @@ export class Entity {
return null;
}
// 优先从 Scene 存储获取
if (this.scene?.componentStorageManager) {
const component = this.scene.componentStorageManager.getComponent(this.id, type);
if (component) {
return component as T;
}
// Scene存储获取
if (!this.scene?.componentStorageManager) {
return null;
}
// Fallback 到本地存储
return (this._localComponents.get(type) as T) || null;
const component = this.scene.componentStorageManager.getComponent(this.id, type);
return component as T | null;
}
@@ -538,17 +527,14 @@ export class Entity {
const bitIndex = ComponentRegistry.getBitIndex(componentType);
// 从本地存储移除
this._localComponents.delete(componentType);
// 更新位掩码
BitMask64Utils.clearBit(this._componentMask, bitIndex);
// 使缓存失效
this._componentCache = null;
// 从 Scene 存储移除
if (this.scene && this.scene.componentStorageManager) {
// 从Scene存储移除
if (this.scene?.componentStorageManager) {
this.scene.componentStorageManager.removeComponent(this.id, componentType);
}
@@ -593,9 +579,6 @@ export class Entity {
public removeAllComponents(): void {
const componentsToRemove = [...this.components];
// 清除本地存储
this._localComponents.clear();
// 清除位掩码
BitMask64Utils.clear(this._componentMask);
@@ -605,7 +588,7 @@ export class Entity {
for (const component of componentsToRemove) {
const componentType = component.constructor as ComponentType;
if (this.scene && this.scene.componentStorageManager) {
if (this.scene?.componentStorageManager) {
this.scene.componentStorageManager.removeComponent(this.id, componentType);
}

View File

@@ -8,6 +8,7 @@ import { Entity } from '../Entity';
import { Component } from '../Component';
import { ComponentType } from '../Core/ComponentStorage';
import { ComponentSerializer, SerializedComponent } from './ComponentSerializer';
import { IScene } from '../IScene';
/**
* 序列化后的实体数据
@@ -108,18 +109,25 @@ export class EntitySerializer {
* @param componentRegistry 组件类型注册表
* @param idGenerator 实体ID生成器用于生成新ID或保持原ID
* @param preserveIds 是否保持原始ID默认false
* @param scene 目标场景可选用于设置entity.scene以支持添加组件
* @returns 反序列化后的实体
*/
public static deserialize(
serializedEntity: SerializedEntity,
componentRegistry: Map<string, ComponentType>,
idGenerator: () => number,
preserveIds: boolean = false
preserveIds: boolean = false,
scene?: IScene
): Entity {
// 创建实体使用原始ID或新生成的ID
const entityId = preserveIds ? serializedEntity.id : idGenerator();
const entity = new Entity(serializedEntity.name, entityId);
// 如果提供了scene先设置entity.scene以支持添加组件
if (scene) {
entity.scene = scene;
}
// 恢复实体属性
entity.tag = serializedEntity.tag;
entity.active = serializedEntity.active;
@@ -142,7 +150,8 @@ export class EntitySerializer {
childData,
componentRegistry,
idGenerator,
preserveIds
preserveIds,
scene
);
entity.addChild(childEntity);
}
@@ -181,13 +190,15 @@ export class EntitySerializer {
* @param componentRegistry 组件类型注册表
* @param idGenerator 实体ID生成器
* @param preserveIds 是否保持原始ID
* @param scene 目标场景可选用于设置entity.scene以支持添加组件
* @returns 反序列化后的实体数组
*/
public static deserializeEntities(
serializedEntities: SerializedEntity[],
componentRegistry: Map<string, ComponentType>,
idGenerator: () => number,
preserveIds: boolean = false
preserveIds: boolean = false,
scene?: IScene
): Entity[] {
const result: Entity[] = [];
@@ -196,7 +207,8 @@ export class EntitySerializer {
serialized,
componentRegistry,
idGenerator,
preserveIds
preserveIds,
scene
);
result.push(entity);
}

View File

@@ -269,7 +269,8 @@ export class SceneSerializer {
serializedScene.entities,
componentRegistry,
idGenerator,
opts.preserveIds || false
opts.preserveIds || false,
scene
);
// 将实体添加到场景