feat(editor): 优化编辑器UI和改进核心功能 (#234)

* feat(editor): 优化编辑器UI和改进核心功能

* feat(editor): 优化编辑器UI和改进核心功能
This commit is contained in:
YHH
2025-11-23 21:45:10 +08:00
committed by GitHub
parent 4d95a7f044
commit 32460ac133
38 changed files with 2201 additions and 485 deletions

View File

@@ -1,4 +1,4 @@
import { Injectable, IService, Entity } from '@esengine/ecs-framework';
import { Injectable, IService, Entity, Core } from '@esengine/ecs-framework';
import { MessageHub } from './MessageHub';
export interface EntityTreeNode {
@@ -14,21 +14,21 @@ export interface EntityTreeNode {
export class EntityStoreService implements IService {
private entities: Map<number, Entity> = new Map();
private selectedEntity: Entity | null = null;
private rootEntities: Set<number> = new Set();
private rootEntityIds: number[] = [];
constructor(private messageHub: MessageHub) {}
public dispose(): void {
this.entities.clear();
this.rootEntities.clear();
this.rootEntityIds = [];
this.selectedEntity = null;
}
public addEntity(entity: Entity, parent?: Entity): void {
this.entities.set(entity.id, entity);
if (!parent) {
this.rootEntities.add(entity.id);
if (!parent && !this.rootEntityIds.includes(entity.id)) {
this.rootEntityIds.push(entity.id);
}
this.messageHub.publish('entity:added', { entity, parent });
@@ -36,7 +36,10 @@ export class EntityStoreService implements IService {
public removeEntity(entity: Entity): void {
this.entities.delete(entity.id);
this.rootEntities.delete(entity.id);
const idx = this.rootEntityIds.indexOf(entity.id);
if (idx !== -1) {
this.rootEntityIds.splice(idx, 1);
}
if (this.selectedEntity?.id === entity.id) {
this.selectedEntity = null;
@@ -60,7 +63,7 @@ export class EntityStoreService implements IService {
}
public getRootEntities(): Entity[] {
return Array.from(this.rootEntities)
return this.rootEntityIds
.map((id) => this.entities.get(id))
.filter((e): e is Entity => e !== undefined);
}
@@ -71,8 +74,40 @@ export class EntityStoreService implements IService {
public clear(): void {
this.entities.clear();
this.rootEntities.clear();
this.rootEntityIds = [];
this.selectedEntity = null;
this.messageHub.publish('entities:cleared', {});
}
public syncFromScene(): void {
const scene = Core.scene;
if (!scene) return;
this.entities.clear();
this.rootEntityIds = [];
scene.entities.forEach((entity) => {
this.entities.set(entity.id, entity);
if (!entity.parent) {
this.rootEntityIds.push(entity.id);
}
});
}
public reorderEntity(entityId: number, newIndex: number): void {
const idx = this.rootEntityIds.indexOf(entityId);
if (idx === -1 || idx === newIndex) return;
const clampedIndex = Math.max(0, Math.min(newIndex, this.rootEntityIds.length - 1));
this.rootEntityIds.splice(idx, 1);
this.rootEntityIds.splice(clampedIndex, 0, entityId);
const scene = Core.scene;
if (scene) {
scene.entities.reorderEntity(entityId, clampedIndex);
}
this.messageHub.publish('entity:reordered', { entityId, newIndex: clampedIndex });
}
}

View File

@@ -186,14 +186,6 @@ export class LogService implements IService {
*/
public clear(): void {
this.logs = [];
this.notifyListeners({
id: -1,
timestamp: new Date(),
level: LogLevel.Info,
source: 'system',
message: 'Logs cleared',
args: []
});
}
/**

View File

@@ -3,6 +3,7 @@ import { Injectable, Core, createLogger, SceneSerializer, Scene } from '@esengin
import type { MessageHub } from './MessageHub';
import type { IFileAPI } from '../Types/IFileAPI';
import type { ProjectService } from './ProjectService';
import type { EntityStoreService } from './EntityStoreService';
const logger = createLogger('SceneManagerService');
@@ -27,7 +28,8 @@ export class SceneManagerService implements IService {
constructor(
private messageHub: MessageHub,
private fileAPI: IFileAPI,
private projectService?: ProjectService
private projectService?: ProjectService,
private entityStore?: EntityStoreService
) {
this.setupAutoModificationTracking();
logger.info('SceneManagerService initialized');
@@ -55,6 +57,7 @@ export class SceneManagerService implements IService {
isSaved: false
};
this.entityStore?.syncFromScene();
await this.messageHub.publish('scene:new', {});
logger.info('New scene created');
}
@@ -98,6 +101,7 @@ export class SceneManagerService implements IService {
isSaved: true
};
this.entityStore?.syncFromScene();
await this.messageHub.publish('scene:loaded', {
path,
sceneName,
@@ -268,7 +272,11 @@ export class SceneManagerService implements IService {
this.markAsModified();
});
this.unsubscribeHandlers.push(unsubscribeEntityAdded, unsubscribeEntityRemoved);
const unsubscribeEntityReordered = this.messageHub.subscribe('entity:reordered', () => {
this.markAsModified();
});
this.unsubscribeHandlers.push(unsubscribeEntityAdded, unsubscribeEntityRemoved, unsubscribeEntityReordered);
logger.debug('Auto modification tracking setup complete');
}