Files
esengine/packages/editor-core/src/Gizmos/GizmoRegistry.ts
YHH dbc6793dc4 refactor: 代码规范化与依赖清理 (#317)
* refactor(deps): 统一编辑器包依赖配置 & 优化分层架构

- 将 ecs-engine-bindgen 提升为 Layer 1 核心包
- 统一 9 个编辑器包的依赖声明模式
- 清理废弃的包目录 (ui, ui-editor, network-*)

* refactor(tokens): 修复 PrefabService 令牌冲突 & 补充 module.json

- 将 editor-core 的 PrefabServiceToken 改名为 EditorPrefabServiceToken
  避免与 asset-system 的 PrefabServiceToken 冲突 (Symbol.for 冲突)
- 为 mesh-3d 添加 module.json
- 为 world-streaming 添加 module.json

* refactor(editor-core): 整理导出结构 & 添加 blueprint tokens.ts

- 按功能分组整理 editor-core 的 65 行导出
- 添加清晰的分组注释 (中英双语)
- 为 blueprint 添加占位符 tokens.ts

* chore(editor): 为 14 个编辑器插件包添加 module.json

统一编辑器包的模块配置,包含:
- isEditorPlugin 标识
- runtimeModule 关联
- exports 导出清单 (inspectors, panels, gizmos)

* refactor(core): 改进类型安全 - 减少 as any 使用

- 添加 GlobalTypes.ts 定义小游戏平台和 Chrome API 类型
- SoAStorage 使用 IComponentTypeMetadata 替代 as any
- PlatformDetector 使用类型安全的平台检测
- 添加 ISoAStorageStats/ISoAFieldStats 接口

* feat(editor): 添加 EditorServicesContext 解决 prop drilling

- 新增 contexts/EditorServicesContext.tsx 提供统一服务访问
- App.tsx 包裹 EditorServicesProvider
- 提供 useEditorServices/useMessageHub 等便捷 hooks
- SceneHierarchy 添加迁移注释,后续可移除 props

* docs(editor): 澄清 inspector 目录架构关系

- inspector/ 标记为内部实现,添加 @deprecated 警告
- inspectors/ 标记为公共 API 入口点
- 添加架构说明文档

* refactor(editor): 添加全局类型声明消除 window as any

- 创建 editor-app/src/global.d.ts 声明 Window 接口扩展
- 创建 editor-core/src/global.d.ts 声明 Window 接口扩展
- 更新 App.tsx 使用类型安全的 window 属性访问
- 更新 PluginLoader.ts 使用 window.__ESENGINE_PLUGINS__
- 更新 PluginSDKRegistry.ts 使用 window.__ESENGINE_SDK__
- 更新 UserCodeService.ts 使用类型安全的全局变量访问

* refactor(editor): 提取项目和场景操作到独立 hooks

- 创建 useProjectActions hook 封装项目操作
- 创建 useSceneActions hook 封装场景操作
- 为渐进式重构 App.tsx 做准备

* refactor(editor): 清理冗余代码和未使用文件

删除的目录和文件:
- application/state/ - 重复的状态管理(与 stores/ 重复)
- 8 个孤立 CSS 文件(对应组件不存在)
- AssetBrowser.tsx - 仅为 ContentBrowser 的向后兼容包装
- AssetPicker.tsx - 未被使用
- AssetPickerDialog.tsx (顶级) - 已被 dialogs/ 版本取代
- EntityInspector.tsx (顶级) - 已被 inspectors/views/ 版本取代

修复:
- 移除 App.tsx 中未使用的导入
- 更新 application/index.ts 移除已删除模块
- 修复 useProjectActions.ts 的 MutableRefObject 类型

* refactor(editor): 统一 inspectors 模块导出结构

- 在 inspectors/index.ts 重新导出 PropertyInspector
- 创建 inspectors/fields/index.ts barrel export
- 导出 views、fields、common 子模块
- 更新 EntityInspector 使用统一入口导入

* refactor(editor): 删除废弃的 Profiler 组件

删除未使用的组件(共 1059 行):
- ProfilerPanel.tsx (229 行)
- ProfilerWindow.tsx (589 行)
- ProfilerDockPanel.tsx (241 行)
- ProfilerPanel.css
- ProfilerDockPanel.css

保留:AdvancedProfiler + AdvancedProfilerWindow(正在使用)

* refactor(runtime-core): 统一依赖处理与插件状态管理

- 新增 DependencyUtils 统一拓扑排序和依赖验证
- 新增 PluginState 定义插件生命周期状态机
- 合并 UnifiedPluginLoader 到 PluginLoader
- 清理 index.ts 移除不必要的 Token re-exports
- 新增 RuntimeMode/UserCodeRealm/ImportMapGenerator

* refactor(editor-core): 使用统一的 ImportMapGenerator

- WebBuildPipeline 使用 runtime-core 的 generateImportMap
- UserCodeService 添加 ImportMap 相关接口

* feat(compiler): 增强 esbuild 查找策略

- 支持本地 node_modules、pnpm exec、npx、全局多种来源
- EngineService 使用 RuntimeMode

* refactor(runtime-core): 简化 GameRuntime 代码

- 合并 _disableGameLogicSystems/_enableGameLogicSystems 为 _setGameLogicSystemsEnabled
- 精简本地 Token 定义的注释

* refactor(editor-core): 引入 BaseRegistry 基类消除代码重复

- 新增 BaseRegistry 和 PrioritizedRegistry 基类
- 重构 CompilerRegistry, InspectorRegistry, FieldEditorRegistry
- 统一注册表的日志记录和错误处理

* refactor(editor-core): 扩展 BaseRegistry 重构

- ComponentInspectorRegistry 继承 PrioritizedRegistry
- EditorComponentRegistry 继承 BaseRegistry
- EntityCreationRegistry 继承 BaseRegistry
- PropertyRendererRegistry 继承 PrioritizedRegistry
- 导出 BaseRegistry 基类供外部使用
- 统一双语注释格式

* refactor(editor-core): 代码优雅性优化

CommandManager:
- 提取 tryMergeWithLast() 和 pushToUndoStack() 消除重复代码
- 统一双语注释格式

FileActionRegistry:
- 提取 normalizeExtension() 消除扩展名规范化重复
- 统一私有属性命名风格(_前缀)
- 使用 createRegistryToken 统一 Token 创建

BaseRegistry:
- 添加 IOrdered 接口
- 添加 sortByOrder() 排序辅助方法

EntityCreationRegistry:
- 使用 sortByOrder() 简化排序逻辑

* refactor(editor-core): 统一日志系统 & 代码规范优化

- GizmoRegistry: 使用 createLogger 替代 console.warn
- VirtualNodeRegistry: 使用 createLogger 替代 console.warn
- WindowRegistry: 使用 logger、添加 _ 前缀、导出 IWindowRegistry token
- EditorViewportService: 使用 createLogger 替代 console.warn
- ComponentActionRegistry: 使用 logger、添加 _ 前缀、返回值改进
- SettingsRegistry: 使用 logger、提取 ensureCategory/ensureSection 方法
- 添加 WindowRegistry 到主导出

* refactor(editor-core): ModuleRegistry 使用 logger 替代 console

* refactor(editor-core): SerializerRegistry/UIRegistry 添加 token 和 _ 前缀

* refactor(editor-core): UIRegistry 代码优雅性 & Token 命名统一

- UIRegistry: 提取 _sortByOrder 消除 6 处重复排序逻辑
- UIRegistry: 添加分节注释和双语文档
- FieldEditorRegistry: Token 重命名为 FieldEditorRegistryToken
- PropertyRendererRegistry: Token 重命名为 PropertyRendererRegistryToken

* refactor(core): 统一日志系统 - console 替换为 logger

- ComponentSerializer: 使用 logger 替代 console.warn
- ComponentRegistry: console.warn → logger.warn (已有 logger)
- SceneSerializer: 添加 logger,替换 console.warn/error
- SystemScheduler: 添加 logger,替换 console.warn
- VersionMigration: 添加 logger,替换所有 console.warn
- RuntimeModeService: console.error → logger.error
- Core.ts: _logger 改为 readonly,双语错误消息
- SceneSerializer 修复:使用 getComponentTypeName 替代 constructor.name

* fix(core): 修复 constructor.name 压缩后失效问题

- Scene.ts: 使用 system.systemName 替代 system.constructor.name
- CommandBuffer.ts: 使用 getComponentTypeName() 替代 constructor.name

* refactor(editor-core): 代码规范优化 - 私有方法命名 & 日志统一

- BuildService: console → logger
- FileActionRegistry: 添加 logger, 私有方法 _ 前缀
- SettingsRegistry: 私有方法 _ 前缀 (ensureCategory → _ensureCategory)

* refactor(core): Scene.ts 私有变量命名规范化

- logger → _logger (遵循私有变量 _ 前缀规范)

* refactor(editor-core): 服务类私有成员命名规范化

- CommandManager: 私有变量/方法添加 _ 前缀
  - undoStack/redoStack/config/isExecuting
  - tryMergeWithLast/pushToUndoStack
- LocaleService: 私有变量/方法添加 _ 前缀
  - currentLocale/translations/changeListeners
  - deepMerge/getNestedValue/loadSavedLocale/saveLocale

* refactor(core): 私有成员命名规范化 & 单例模式优化

- Component.ts: _idGenerator 私有静态变量规范化
- PlatformManager.ts: _instance, _adapter, _logger 规范化
- AutoProfiler.ts: _instance, _config 及所有私有方法规范化
- ProfilerSDK.ts: _instance, _config 及所有私有方法规范化
- ComponentPoolManager: _instance, _pools, _usageTracker 规范化
- GlobalEventBus: _instance 规范化
- 添加中英双语 JSDoc 注释

* refactor(editor-app,behavior-tree-editor): 私有成员 & 单例模式命名规范化

editor-app:
- EngineService: private static instance → _instance
- EditorEngineSync: 所有私有成员添加 _ 前缀
- RuntimeResolver: 所有私有成员和方法添加 _ 前缀
- SettingsService: 所有私有成员和方法添加 _ 前缀

behavior-tree-editor:
- GlobalBlackboardService: 所有私有成员和方法添加 _ 前缀
- NotificationService: private static instance → _instance
- NodeRegistryService: 所有私有成员和方法添加 _ 前缀
- TreeStateAdapter: private static instance → _instance

* fix(editor-runtime): 添加 editor-core 到 external 避免传递依赖问题

将 @esengine/editor-core 添加到 vite external 配置,
避免 editor-core → runtime-core → ecs-engine-bindgen 的传递依赖
被错误地打包进 editor-runtime.js,导致 CI 构建失败。

* fix(core): 修复空接口 lint 错误

将 IByteDanceMiniGameAPI、IAlipayMiniGameAPI、IBaiduMiniGameAPI 从空接口改为类型别名,修复 no-empty-object-type 规则报错
2025-12-24 20:57:08 +08:00

202 lines
6.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Gizmo Registry
* Gizmo 注册表
*
* Manages gizmo providers for different component types.
* Uses registry pattern instead of prototype modification for cleaner architecture.
* 管理不同组件类型的 gizmo 提供者。
* 使用注册表模式替代原型修改,实现更清晰的架构。
*/
import { createLogger, type Component, type ComponentType, type Entity } from '@esengine/ecs-framework';
import type { IGizmoProvider, IGizmoRenderData } from './IGizmoProvider';
const logger = createLogger('GizmoRegistry');
/**
* Gizmo provider function type
* Gizmo 提供者函数类型
*
* A function that generates gizmo data for a specific component instance.
* 为特定组件实例生成 gizmo 数据的函数。
*/
export type GizmoProviderFn<T extends Component = Component> = (
component: T,
entity: Entity,
isSelected: boolean
) => IGizmoRenderData[];
/**
* Gizmo Registry Service
* Gizmo 注册表服务
*
* Centralized registry for component gizmo providers.
* Allows plugins to register gizmo rendering for any component type
* without modifying the component class itself.
*
* 组件 gizmo 提供者的中心化注册表。
* 允许插件为任何组件类型注册 gizmo 渲染,
* 而无需修改组件类本身。
*
* @example
* ```typescript
* // Register a gizmo provider for SpriteComponent
* GizmoRegistry.register(SpriteComponent, (sprite, entity, isSelected) => {
* const transform = entity.getComponent(TransformComponent);
* return [{
* type: 'rect',
* x: transform.position.x,
* y: transform.position.y,
* width: sprite.width,
* height: sprite.height,
* // ...
* }];
* });
*
* // Get gizmo data for a component
* const gizmos = GizmoRegistry.getGizmoData(spriteComponent, entity, true);
* ```
*/
export class GizmoRegistry {
private static providers = new Map<ComponentType, GizmoProviderFn>();
/**
* Register a gizmo provider for a component type.
* 为组件类型注册 gizmo 提供者。
*
* @param componentType - The component class to register for
* @param provider - Function that generates gizmo data
*/
static register<T extends Component>(
componentType: ComponentType<T>,
provider: GizmoProviderFn<T>
): void {
this.providers.set(componentType, provider as GizmoProviderFn);
}
/**
* Unregister a gizmo provider for a component type.
* 取消注册组件类型的 gizmo 提供者。
*
* @param componentType - The component class to unregister
*/
static unregister(componentType: ComponentType): void {
this.providers.delete(componentType);
}
/**
* Check if a component type has a registered gizmo provider.
* 检查组件类型是否有注册的 gizmo 提供者。
*
* @param componentType - The component class to check
*/
static hasProvider(componentType: ComponentType): boolean {
return this.providers.has(componentType);
}
/**
* Get the gizmo provider for a component type.
* 获取组件类型的 gizmo 提供者。
*
* @param componentType - The component class
* @returns The provider function or undefined
*/
static getProvider(componentType: ComponentType): GizmoProviderFn | undefined {
return this.providers.get(componentType);
}
/**
* Get gizmo data for a component instance.
* 获取组件实例的 gizmo 数据。
*
* @param component - The component instance
* @param entity - The entity owning the component
* @param isSelected - Whether the entity is selected
* @returns Array of gizmo render data, or empty array if no provider
*/
static getGizmoData(
component: Component,
entity: Entity,
isSelected: boolean
): IGizmoRenderData[] {
const componentType = component.constructor as ComponentType;
const provider = this.providers.get(componentType);
if (provider) {
try {
return provider(component, entity, isSelected);
} catch (e) {
logger.warn(`Error in gizmo provider for ${componentType.name}:`, e);
return [];
}
}
return [];
}
/**
* Get all gizmo data for an entity (from all components with providers).
* 获取实体的所有 gizmo 数据(来自所有有提供者的组件)。
*
* @param entity - The entity to get gizmos for
* @param isSelected - Whether the entity is selected
* @returns Array of all gizmo render data
*/
static getAllGizmoDataForEntity(entity: Entity, isSelected: boolean): IGizmoRenderData[] {
const allGizmos: IGizmoRenderData[] = [];
for (const component of entity.components) {
const gizmos = this.getGizmoData(component, entity, isSelected);
allGizmos.push(...gizmos);
}
return allGizmos;
}
/**
* Check if an entity has any components with gizmo providers.
* 检查实体是否有任何带有 gizmo 提供者的组件。
*
* @param entity - The entity to check
*/
static hasAnyGizmoProvider(entity: Entity): boolean {
for (const component of entity.components) {
const componentType = component.constructor as ComponentType;
if (this.providers.has(componentType)) {
return true;
}
}
return false;
}
/**
* Get all registered component types.
* 获取所有已注册的组件类型。
*/
static getRegisteredTypes(): ComponentType[] {
return Array.from(this.providers.keys());
}
/**
* Clear all registered providers.
* 清除所有已注册的提供者。
*/
static clear(): void {
this.providers.clear();
}
}
/**
* Adapter to make GizmoRegistry work with the IGizmoProvider interface.
* 使 GizmoRegistry 与 IGizmoProvider 接口兼容的适配器。
*
* This allows components to optionally implement IGizmoProvider directly,
* while also supporting the registry pattern.
* 这允许组件可选地直接实现 IGizmoProvider
* 同时也支持注册表模式。
*/
export function isGizmoProviderRegistered(component: Component): boolean {
const componentType = component.constructor as ComponentType;
return GizmoRegistry.hasProvider(componentType);
}