From 7808f64fe5c693ac976847181175bb405f3decd8 Mon Sep 17 00:00:00 2001 From: YHH <359807859@qq.com> Date: Tue, 17 Jun 2025 10:46:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=94=9F=E6=88=90=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cocos-ecs/.ecs-framework-settings.json | 54 +++ .../assets/scripts/ecs/factories.meta | 9 + .../extensions/cocos-ecs-extension/README.md | 88 +++- .../cocos-ecs-extension/README.zh-CN.md | 24 -- .../extensions/cocos-ecs-extension/i18n/en.js | 2 +- .../extensions/cocos-ecs-extension/i18n/zh.js | 2 +- .../cocos-ecs-extension/package-lock.json | 33 +- .../cocos-ecs-extension/package.json | 58 ++- .../source/CodeGenerator.ts | 274 +++++++++++++ .../cocos-ecs-extension/source/main.ts | 157 ++++---- .../source/panels/debug/index.ts | 11 +- .../source/panels/default/index.ts | 27 +- .../source/panels/generator/index.ts | 240 +++++++++++ .../source/panels/settings/index.ts | 370 ----------------- .../static/style/default/index.css | 37 +- .../static/style/generator/index.css | 378 ++++++++++++++++++ .../static/style/settings/index.css | 353 ---------------- .../static/template/generator/index.html | 111 +++++ .../static/template/settings/index.html | 322 --------------- .../static/template/vue/welcome.html | 35 +- extensions/cocos/cocos-ecs/package-lock.json | 6 +- src/ECS/Core/Storage/index.ts | 2 +- 22 files changed, 1345 insertions(+), 1248 deletions(-) create mode 100644 extensions/cocos/cocos-ecs/.ecs-framework-settings.json create mode 100644 extensions/cocos/cocos-ecs/assets/scripts/ecs/factories.meta delete mode 100644 extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/README.zh-CN.md create mode 100644 extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/CodeGenerator.ts create mode 100644 extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/generator/index.ts delete mode 100644 extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/settings/index.ts create mode 100644 extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/style/generator/index.css delete mode 100644 extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/style/settings/index.css create mode 100644 extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/template/generator/index.html delete mode 100644 extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/template/settings/index.html diff --git a/extensions/cocos/cocos-ecs/.ecs-framework-settings.json b/extensions/cocos/cocos-ecs/.ecs-framework-settings.json new file mode 100644 index 00000000..62dce418 --- /dev/null +++ b/extensions/cocos/cocos-ecs/.ecs-framework-settings.json @@ -0,0 +1,54 @@ +{ + "codeGeneration": { + "template": "typescript", + "useStrictMode": true, + "generateComments": true, + "generateImports": true, + "componentSuffix": "Component", + "systemSuffix": "System", + "indentStyle": "spaces", + "indentSize": 4 + }, + "performance": { + "enableMonitoring": true, + "warningThreshold": 16.67, + "criticalThreshold": 33.33, + "memoryWarningMB": 100, + "memoryCriticalMB": 200, + "maxRecentSamples": 60, + "enableFpsMonitoring": true, + "targetFps": 60 + }, + "debugging": { + "enableDebugMode": true, + "showEntityCount": true, + "showSystemExecutionTime": true, + "enablePerformanceWarnings": true, + "logLevel": "info", + "enableDetailedLogs": false + }, + "editor": { + "autoRefreshAssets": true, + "showWelcomePanelOnStartup": true, + "enableAutoUpdates": false, + "updateChannel": "stable", + "enableNotifications": true + }, + "template": { + "defaultEntityName": "GameEntity", + "defaultComponentName": "CustomComponent", + "defaultSystemName": "CustomSystem", + "createExampleFiles": true, + "includeDocumentation": true, + "useFactoryPattern": true + }, + "events": { + "enableEventSystem": true, + "defaultEventPriority": 0, + "enableAsyncEvents": true, + "enableEventBatching": false, + "batchSize": 10, + "batchDelay": 16, + "maxEventListeners": 100 + } +} \ No newline at end of file diff --git a/extensions/cocos/cocos-ecs/assets/scripts/ecs/factories.meta b/extensions/cocos/cocos-ecs/assets/scripts/ecs/factories.meta new file mode 100644 index 00000000..8d4aa6b2 --- /dev/null +++ b/extensions/cocos/cocos-ecs/assets/scripts/ecs/factories.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "80dcbaf5-21f7-4bb1-aff4-2cdbb0b5d364", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/README.md b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/README.md index 4f713e6d..a75e1491 100644 --- a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/README.md +++ b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/README.md @@ -1,25 +1,81 @@ -# Project Title +# ECS Framework for Cocos Creator - 开发扩展插件 -An extension that shows how to open and communicate with the panel through messages and menus. -The panel is based on Vue3.x. +专业的ECS框架开发助手,为Cocos Creator提供完整的实体组件系统(ECS)开发工具链。 -## Development Environment +## 🎯 主要功能 -Node.js +### 📦 一键安装管理 +- **自动检测**:实时检测ECS框架安装状态和版本信息 +- **一键安装**:快速安装 `@esengine/ecs-framework` 到当前项目 +- **版本管理**:自动检查更新,支持一键更新到最新版本 +- **智能卸载**:安全卸载框架,保护项目完整性 -## Install +### 🚀 代码生成器 +- **智能生成**:输入功能名称,自动生成对应的组件和系统代码 +- **多种系统类型**:支持EntitySystem、ProcessingSystem、IntervalSystem、PassiveSystem +- **组件配置**:可选择添加属性、注释等定制化选项 +- **组件过滤**:支持生成带组件过滤的高级系统 -```bash -# Install dependent modules -npm install -# build -npm run build -``` +### 🛠️ 项目模板 +- **快速启动**:一键生成完整的ECS项目结构 +- **预设组件**:包含位置、速度、Cocos节点等常用组件 +- **系统示例**:提供移动系统、节点同步系统等实用示例 +- **工厂模式**:包含实体工厂和场景管理器模板 -## Usage +### 🔍 调试工具 +- **实时监控**:查看ECS框架运行状态和性能数据 +- **组件池监控**:实时监控组件对象池使用情况 +- **性能分析**:提供详细的性能统计和优化建议 -After enabling the extension, click `Panel -> cocos-ecs-extension -> Default Panel` in the main menu bar to open the default panel of the extension. +## 📋 面板介绍 -To send a message to the default panel, click `Developer -> cocos-ecs-extension -> Send Message to Panel` at the top of the menu. If the default panel exists, the `hello` method of the panel will be called. +### 欢迎面板 +- ECS框架安装状态检测 +- 一键安装、更新、卸载操作 +- 项目模板生成 +- 快速访问文档和GitHub -After clicking `Send Message to Panel`, a message `send-to-panel` will be sent to the extension as defined by `contributions.menu` in `package.json`. When the extension receives the `send-to-panel` message, it will cause the `default` panel to call the `hello` method as defined by `contributions.messages` in `package.json`. +### 代码生成器 +- 可视化代码生成界面 +- 实时预览生成的代码结构 +- 支持批量生成多个文件 + +### 调试面板 +- 实时性能监控 +- 组件池状态查看 +- 系统运行统计 + +## 🔧 开发环境 + +- **Cocos Creator**: >= 3.8.6 +- **Node.js**: >= 14.0.0 +- **依赖框架**: @esengine/ecs-framework + +## 📥 安装使用 + +1. 将插件复制到项目的 `extensions` 目录 +2. 在Cocos Creator中启用插件 +3. 通过菜单 `面板 -> ECS Framework -> 欢迎面板` 打开主界面 +4. 按照界面提示安装ECS框架并开始开发 + +## 🚀 快速开始 + +1. **安装框架**:在欢迎面板点击"安装 ECS Framework" +2. **创建模板**:点击"创建ECS模板"生成项目结构 +3. **生成代码**:使用代码生成器快速创建组件和系统 +4. **开始开发**:基于生成的模板开始您的ECS游戏开发 + +## 📚 更多资源 + +- **GitHub仓库**:[https://github.com/esengine/ecs-framework](https://github.com/esengine/ecs-framework) +- **完整文档**:包含详细的API文档和教程 +- **技术交流**:加入QQ群获取技术支持和交流 + +## ⭐ 特色优势 + +- **零配置**:开箱即用,无需复杂配置 +- **可视化**:图形化界面,操作简单直观 +- **高效率**:大幅减少重复代码编写 +- **专业性**:基于成熟的ECS框架设计模式 + +让ECS开发变得简单高效,专注于游戏逻辑而非框架配置! diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/README.zh-CN.md b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/README.zh-CN.md deleted file mode 100644 index 487ea877..00000000 --- a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/README.zh-CN.md +++ /dev/null @@ -1,24 +0,0 @@ -# 项目简介 - -一份包含面板的扩展,该面板基于 vue3.x 开发,展示了如何通过消息和菜单打开面板,以及与面板通讯。 - -## 开发环境 - -Node.js - -## 安装 - -```bash -# 安装依赖模块 -npm install -# 构建 -npm run build -``` - -## 用法 - -启用扩展后,点击主菜单栏中的 `面板 -> cocos-ecs-extension -> 默认面板`,即可打开扩展的默认面板。 - -依次点击顶部菜单的 `开发者 -> cocos-ecs-extension -> 发送消息给面板` 即可发送消息给默认面板,如果此时存在默认面板,将会调用面板的 `hello` 方法。 - -点击 `发送消息给面板` 后,根据 `package.json` 中 `contributions.menu` 的定义将发送一条消息 `send-to-panel` 给扩展。根据 `package.json` 中 `contributions.messages` 的定义当扩展收到 `send-to-panel` 后将会使 `default` 面板调用 `hello` 方法。 diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/i18n/en.js b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/i18n/en.js index 1b1ffa76..7b93061e 100644 --- a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/i18n/en.js +++ b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/i18n/en.js @@ -1 +1 @@ -"use strict";module.exports={open_panel:"Default Panel",send_to_panel:"Send message to Default Panel",description:"Extension with a panel based on Vue3.x"}; \ No newline at end of file +"use strict";module.exports={open_panel:"Default Panel",send_to_panel:"Send message to Default Panel",description:"Professional ECS Framework Development Assistant: One-click install @esengine/ecs-framework, intelligent code generator for components and systems, project template generation, real-time status monitoring and version management. Features welcome panel, debug panel and code generator to make ECS development in Cocos Creator more efficient and convenient."}; \ No newline at end of file diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/i18n/zh.js b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/i18n/zh.js index ead340af..f7c2c61b 100644 --- a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/i18n/zh.js +++ b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/i18n/zh.js @@ -1 +1 @@ -"use strict";module.exports={open_panel:"默认面板",send_to_panel:"发送消息给面板",description:"含有一个基于Vue3.x开发的面板的扩展"}; \ No newline at end of file +"use strict";module.exports={open_panel:"默认面板",send_to_panel:"发送消息给面板",description:"专业的ECS框架开发助手:一键安装@esengine/ecs-framework,智能代码生成器快速创建组件和系统,项目模板生成,实时状态检测和版本管理。提供欢迎面板、调试面板和代码生成器,让Cocos Creator的ECS开发更高效便捷。"}; \ No newline at end of file diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/package-lock.json b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/package-lock.json index 6bef86e9..eaa3a068 100644 --- a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/package-lock.json +++ b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/package-lock.json @@ -10,12 +10,14 @@ "hasInstallScript": true, "dependencies": { "fs-extra": "^10.0.0", - "vue": "^3.1.4" + "vue": "^3.1.4", + "ws": "^8.14.2" }, "devDependencies": { "@cocos/creator-types": "^3.8.6", "@types/fs-extra": "^9.0.5", "@types/node": "^18.17.1", + "@types/ws": "^8.5.10", "typescript": "^5.8.2" } }, @@ -57,6 +59,15 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@vue/compiler-core": { "version": "3.3.4", "license": "MIT", @@ -282,6 +293,26 @@ "@vue/server-renderer": "3.3.4", "@vue/shared": "3.3.4" } + }, + "node_modules/ws": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", + "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } } } } diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/package.json b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/package.json index 135ca452..52b960c7 100644 --- a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/package.json +++ b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/package.json @@ -13,12 +13,14 @@ "main": "./dist/main.js", "dependencies": { "vue": "^3.1.4", - "fs-extra": "^10.0.0" + "fs-extra": "^10.0.0", + "ws": "^8.14.2" }, "devDependencies": { "@cocos/creator-types": "^3.8.6", "@types/fs-extra": "^9.0.5", "@types/node": "^18.17.1", + "@types/ws": "^8.5.10", "typescript": "^5.8.2" }, "panels": { @@ -33,17 +35,6 @@ "height": 800 } }, - "settings": { - "title": "ECS Framework - 设置", - "type": "dockable", - "main": "dist/panels/settings/index.js", - "size": { - "min-width": 600, - "min-height": 700, - "width": 800, - "height": 900 - } - }, "debug": { "title": "ECS Framework - 调试面板", "type": "dockable", @@ -54,6 +45,17 @@ "width": 500, "height": 600 } + }, + "generator": { + "title": "ECS Framework - 代码生成器", + "type": "dockable", + "main": "dist/panels/generator/index.js", + "size": { + "min-width": 600, + "min-height": 500, + "width": 900, + "height": 700 + } } }, "contributions": { @@ -68,13 +70,13 @@ }, { "path": "i18n:menu.panel/ECS Framework", - "label": "插件设置", - "message": "open-settings" + "label": "调试面板", + "message": "open-debug" }, { "path": "i18n:menu.panel/ECS Framework", - "label": "调试面板", - "message": "open-debug" + "label": "代码生成器", + "message": "open-generator" }, { "path": "i18n:menu.develop/ECS Framework", @@ -113,35 +115,25 @@ "create-ecs-template" ] }, - "open-settings": { - "methods": [ - "open-settings" - ] - }, - "open-project-analysis": { - "methods": [ - "open-project-analysis" - ] - }, - "open-component-library": { - "methods": [ - "open-component-library" - ] - }, "open-github": { "methods": [ "open-github" ] }, - "settings-updated": { + "open-qq-group": { "methods": [ - "settings-updated" + "open-qq-group" ] }, "open-debug": { "methods": [ "open-debug" ] + }, + "open-generator": { + "methods": [ + "open-generator" + ] } } } diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/CodeGenerator.ts b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/CodeGenerator.ts new file mode 100644 index 00000000..68dec643 --- /dev/null +++ b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/CodeGenerator.ts @@ -0,0 +1,274 @@ +import { ensureDir, writeFile } from 'fs-extra'; +import { join } from 'path'; + +/** + * 代码生成器工具类 + * 用于生成基础的ECS框架代码 + */ + +interface ComponentOptions { + includeComments: boolean; + addProperties: string[]; +} + +interface SystemOptions { + includeComments: boolean; + systemType: 'EntitySystem' | 'ProcessingSystem' | 'IntervalSystem' | 'PassiveSystem'; + requiredComponents: string[]; +} + +export class CodeGenerator { + + /** + * 生成组件代码 + */ + public async generateComponent( + name: string, + targetDir: string, + options: ComponentOptions = { + includeComments: true, + addProperties: [] + } + ): Promise { + const className = `${name}Component`; + const fileName = `${className}.ts`; + const filePath = join(targetDir, fileName); + + await ensureDir(targetDir); + + const comments = options.includeComments ? this.generateComponentComments(className) : ''; + const properties = this.generateComponentProperties(options.addProperties); + + const content = `import { Component } from '@esengine/ecs-framework'; + +${comments} +export class ${className} extends Component { +${properties} + + constructor() { + super(); + } + + /** + * 重置组件状态 + */ + public reset(): void { + // 重置组件属性到默认值 +${this.generateResetCode(options.addProperties)} + } +} +`; + + await writeFile(filePath, content, 'utf-8'); + } + + /** + * 生成系统代码 + */ + public async generateSystem( + name: string, + targetDir: string, + options: SystemOptions = { + includeComments: true, + systemType: 'EntitySystem', + requiredComponents: [] + } + ): Promise { + const className = `${name}System`; + const fileName = `${className}.ts`; + const filePath = join(targetDir, fileName); + + await ensureDir(targetDir); + + const comments = options.includeComments ? this.generateSystemComments(className, options.systemType) : ''; + const imports = this.getSystemImports(options.systemType, options.requiredComponents); + const matcherSetup = options.requiredComponents.length > 0 ? + `Matcher.empty().all(${options.requiredComponents.join(', ')})` : + `Matcher.empty()`; + + const processMethod = this.generateProcessMethod(options.systemType, options.requiredComponents, className); + + const content = `${imports} + +${comments} +export class ${className} extends ${options.systemType} { + + constructor() { + super(${matcherSetup}${options.systemType === 'IntervalSystem' ? ', 1000 / 60 // 60fps' : ''}); + } + +${processMethod} + + /** + * 系统开始时调用 + */ + public begin(): void { + super.begin(); + // 添加系统初始化逻辑 + } + + /** + * 系统结束时调用 + */ + public end(): void { + // 添加系统清理逻辑 + super.end(); + } +} +`; + + await writeFile(filePath, content, 'utf-8'); + } + + // ============ 辅助方法 ============ + + private generateComponentComments(className: string): string { + return `/** + * ${className} + * + * 组件描述 + * + * @example + * \`\`\`typescript + * const entity = scene.createEntity("Example"); + * const component = entity.addComponent(new ${className}()); + * \`\`\` + */`; + } + + private generateSystemComments(className: string, systemType: string): string { + const descriptions = { + 'EntitySystem': '处理拥有特定组件的实体', + 'ProcessingSystem': '执行全局游戏逻辑', + 'IntervalSystem': '按时间间隔处理实体', + 'PassiveSystem': '被动响应事件或手动调用' + }; + + return `/** + * ${className} + * + * ${descriptions[systemType as keyof typeof descriptions] || '处理游戏逻辑'} + * + * @example + * \`\`\`typescript + * const system = new ${className}(); + * scene.addEntityProcessor(system); + * \`\`\` + */`; + } + + private generateComponentProperties(properties: string[]): string { + if (properties.length === 0) { + return ' // 添加组件属性\n // public value: number = 0;'; + } + + return properties.map(prop => { + const [name, type = 'number', defaultValue = '0'] = prop.split(':'); + return ` public ${name}: ${type} = ${defaultValue};`; + }).join('\n'); + } + + private generateResetCode(properties: string[]): string { + if (properties.length === 0) { + return ' // this.value = 0;'; + } + + return properties.map(prop => { + const [name, , defaultValue = '0'] = prop.split(':'); + return ` this.${name} = ${defaultValue};`; + }).join('\n'); + } + + private getSystemImports(systemType: string, requiredComponents: string[]): string { + const imports = [systemType, 'Entity']; + + // 所有系统类型都可能需要Matcher来过滤组件 + if (requiredComponents.length > 0 || systemType === 'EntitySystem' || systemType === 'IntervalSystem' || systemType === 'PassiveSystem') { + imports.push('Matcher'); + } + + return `import { ${imports.join(', ')} } from '@esengine/ecs-framework';${requiredComponents.length > 0 ? '\n' + this.generateComponentImports(requiredComponents) : ''}`; + } + + private generateComponentImports(components: string[]): string { + return components.map(comp => `import { ${comp} } from '../components/${comp}';`).join('\n'); + } + + private generateProcessMethod(systemType: string, requiredComponents: string[], className: string): string { + switch (systemType) { + case 'EntitySystem': + return ` protected process(entities: Entity[]): void { + for (const entity of entities) { + this.processEntity(entity); + } + } + + private processEntity(entity: Entity): void { +${this.generateProcessingLogic(requiredComponents)} + }`; + + case 'ProcessingSystem': + return ` public processSystem(): void { + // 添加全局系统逻辑 + console.log('${className} processSystem called'); + }`; + + case 'IntervalSystem': + return ` protected process(entities: Entity[]): void { + const intervalDelta = this.getIntervalDelta(); + console.log(\`${className} executing with interval delta: \${intervalDelta}\`); + + for (const entity of entities) { + this.processEntity(entity, intervalDelta); + } + } + + private processEntity(entity: Entity, delta: number): void { +${this.generateProcessingLogic(requiredComponents)} + }`; + + case 'PassiveSystem': + return ` /** + * 被动系统不主动处理实体 + * 通常用于响应事件或被其他系统调用 + */ + public processEntity(entity: Entity): void { +${this.generateProcessingLogic(requiredComponents)} + } + + /** + * 手动触发处理 + */ + public trigger(): void { + for (const entity of this.entities) { + this.processEntity(entity); + } + }`; + + default: + return ''; + } + } + + private generateProcessingLogic(requiredComponents: string[]): string { + if (requiredComponents.length === 0) { + return ' // 添加处理逻辑'; + } + + const componentVars = requiredComponents.map((comp: string) => { + const varName = comp.replace('Component', '').toLowerCase(); + return ` const ${varName} = entity.getComponent(${comp});`; + }).join('\n'); + + const nullCheck = requiredComponents.map((comp: string) => { + const varName = comp.replace('Component', '').toLowerCase(); + return varName; + }).join(' && '); + + return `${componentVars} + + if (${nullCheck}) { + // 添加处理逻辑 + }`; + } +} \ No newline at end of file diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/main.ts b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/main.ts index 7627b4ef..000386a3 100644 --- a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/main.ts +++ b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/main.ts @@ -2,9 +2,11 @@ import packageJSON from '../package.json'; import { exec } from 'child_process'; import * as path from 'path'; +import * as fs from 'fs'; import { readFileSync, outputFile } from 'fs-extra'; import { join } from 'path'; import { TemplateGenerator } from './TemplateGenerator'; +import { CodeGenerator } from './CodeGenerator'; /** * @en Registration method for the main process of Extension @@ -120,16 +122,28 @@ export const methods: { [key: string]: (...any: any) => any } = { * 打开文档 */ 'open-documentation'() { - // 使用系统默认命令打开链接 const url = 'https://github.com/esengine/ecs-framework/blob/master/README.md'; - exec(`start "" "${url}"`, (error) => { - if (error) { - console.error('Failed to open documentation:', error); - Editor.Dialog.info('打开文档', { - detail: `请手动访问以下链接查看文档:\n\n${url}`, - }); - } - }); + + try { + // 使用Electron的shell模块打开外部链接(推荐方法) + const { shell } = require('electron'); + shell.openExternal(url); + console.log('Documentation link opened successfully'); + } catch (error) { + console.error('Failed to open documentation with shell.openExternal, trying exec:', error); + + // 备用方法:使用系统命令 + exec(`start "" "${url}"`, (execError) => { + if (execError) { + console.error('Failed to open documentation with exec:', execError); + Editor.Dialog.info('打开文档', { + detail: `请手动访问以下链接查看文档:\n\n${url}`, + }); + } else { + console.log('Documentation link opened successfully with exec'); + } + }); + } }, /** @@ -198,56 +212,59 @@ export const methods: { [key: string]: (...any: any) => any } = { }, /** - * 打开设置 + * 打开GitHub仓库 */ - 'open-settings'() { - console.log('Opening ECS Framework settings panel...'); + 'open-github'() { + const url = 'https://github.com/esengine/ecs-framework'; + try { - // 正确的打开特定面板的方法 - Editor.Panel.open(packageJSON.name + '.settings'); - console.log('Settings panel opened successfully'); + // 使用Electron的shell模块打开外部链接(推荐方法) + const { shell } = require('electron'); + shell.openExternal(url); + console.log('GitHub link opened successfully'); } catch (error) { - console.error('Failed to open settings panel:', error); - Editor.Dialog.error('打开设置失败', { - detail: `无法打开设置面板:\n\n${error}\n\n请尝试重启Cocos Creator编辑器。`, + console.error('Failed to open GitHub with shell.openExternal, trying exec:', error); + + // 备用方法:使用系统命令 + exec(`start "" "${url}"`, (execError) => { + if (execError) { + console.error('Failed to open GitHub with exec:', execError); + Editor.Dialog.info('打开GitHub', { + detail: `请手动访问以下链接:\n\n${url}`, + }); + } else { + console.log('GitHub link opened successfully with exec'); + } }); } }, /** - * 项目分析(预留) + * 打开QQ群 */ - 'analyze-project'() { - Editor.Dialog.info('项目分析', { - detail: '项目分析功能开发中...\n\n将在下个版本提供以下分析功能:\n• ECS架构合理性分析\n• 性能瓶颈检测\n• 组件使用统计\n• 系统执行效率分析\n• 内存使用优化建议', - buttons: ['好的'], - }); - }, - - /** - * 组件库(预留) - */ - 'open-component-library'() { - Editor.Dialog.info('组件库', { - detail: '组件库功能开发中...\n\n将在下个版本提供:\n• 常用组件模板库\n• 系统模板库\n• 一键生成组件代码\n• 社区组件分享\n• 组件文档和示例', - buttons: ['好的'], - }); - }, - - /** - * 打开GitHub仓库 - */ - 'open-github'() { - const url = 'https://github.com/esengine/ecs-framework'; - // 在Windows上使用正确的start命令语法 - exec(`start "" "${url}"`, (error) => { - if (error) { - console.error('Failed to open GitHub:', error); - Editor.Dialog.info('打开GitHub', { - detail: `请手动访问以下链接:\n\n${url}`, - }); - } - }); + 'open-qq-group'() { + const url = 'https://qm.qq.com/cgi-bin/qm/qr?k=1DMoPJEsY5xUpTAcmjIHK8whgHJHYQTL&authKey=%2FklVb3S0Momc1q1J%2FWHncuwMVHGrDbwV1Y6gAfa5e%2FgHCvyYUL2gpA6hSOU%2BVSa5&noverify=0&group_code=481923584'; + + try { + // 使用Electron的shell模块打开外部链接(推荐方法) + const { shell } = require('electron'); + shell.openExternal(url); + console.log('QQ group link opened successfully'); + } catch (error) { + console.error('Failed to open QQ group with shell.openExternal, trying exec:', error); + + // 备用方法:使用系统命令 + exec(`start "" "${url}"`, (execError) => { + if (execError) { + console.error('Failed to open QQ group with exec:', execError); + Editor.Dialog.info('加入QQ群', { + detail: `请手动访问以下链接加入QQ群:\n\n${url}\n\n或手动搜索QQ群号:481923584`, + }); + } else { + console.log('QQ group link opened successfully with exec'); + } + }); + } }, /** @@ -268,36 +285,18 @@ export const methods: { [key: string]: (...any: any) => any } = { }, /** - * 处理设置更新 + * 打开代码生成器面板 */ - 'settings-updated'(settings: any) { - console.log('ECS Framework settings updated:', settings); - - // 这里可以根据设置更新做一些处理 - // 比如重新配置框架、更新性能监控等 - - // 示例:根据设置更新性能监控 - if (settings?.performance?.enableMonitoring) { - console.log('Performance monitoring enabled with thresholds:', { - warning: settings.performance.warningThreshold, - critical: settings.performance.criticalThreshold, - memoryWarning: settings.performance.memoryWarningMB, - memoryCritical: settings.performance.memoryCriticalMB - }); - } - - // 示例:根据设置更新调试模式 - if (settings?.debugging?.enableDebugMode) { - console.log('Debug mode enabled with log level:', settings.debugging.logLevel); - } - - // 示例:根据设置更新事件系统 - if (settings?.events?.enableEventSystem) { - console.log('Event system configured:', { - asyncEvents: settings.events.enableAsyncEvents, - batching: settings.events.enableEventBatching, - batchSize: settings.events.batchSize, - maxListeners: settings.events.maxEventListeners + 'open-generator'() { + console.log('Opening ECS Framework code generator panel...'); + try { + // 正确的打开特定面板的方法 + Editor.Panel.open(packageJSON.name + '.generator'); + console.log('Generator panel opened successfully'); + } catch (error) { + console.error('Failed to open generator panel:', error); + Editor.Dialog.error('打开代码生成器失败', { + detail: `无法打开代码生成器面板:\n\n${error}\n\n请尝试重启Cocos Creator编辑器。`, }); } }, diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/debug/index.ts b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/debug/index.ts index 096fa00b..c51a7dd6 100644 --- a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/debug/index.ts +++ b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/debug/index.ts @@ -1,7 +1,8 @@ import { readFileSync } from 'fs-extra'; import { join } from 'path'; import { createApp, App, defineComponent, ref, reactive, onMounted, onUnmounted } from 'vue'; -import { WebSocketServer } from 'ws'; +import { WebSocketServer, WebSocket } from 'ws'; +import { IncomingMessage } from 'http'; const panelDataMap = new WeakMap(); @@ -15,7 +16,7 @@ interface GameInstance { lastUpdateTime: number; isActive: boolean; debugData?: any; - ws?: any; // WebSocket连接 + ws?: WebSocket; // WebSocket连接 } /** @@ -136,7 +137,7 @@ class ECSDebugServer { try { this.wss = new WebSocketServer({ port: this.port }); - this.wss.on('connection', (ws, req) => { + this.wss.on('connection', (ws: WebSocket, req: IncomingMessage) => { const instanceId = this.generateInstanceId(); const instance: GameInstance = { id: instanceId, @@ -151,7 +152,7 @@ class ECSDebugServer { this.gameInstances.set(instanceId, instance); console.log(`[ECS Debug Server] New instance connected: ${instance.name}`); - ws.on('message', (data) => { + ws.on('message', (data: Buffer) => { try { const message = JSON.parse(data.toString()); this.handleMessage(instanceId, message); @@ -168,7 +169,7 @@ class ECSDebugServer { } }); - ws.on('error', (error) => { + ws.on('error', (error: Error) => { console.error(`[ECS Debug Server] WebSocket error for ${instanceId}:`, error); }); diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/default/index.ts b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/default/index.ts index a0948198..d2aac148 100644 --- a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/default/index.ts +++ b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/default/index.ts @@ -462,22 +462,18 @@ module.exports = Editor.Panel.define({ }); }; - const openSettings = () => { - Editor.Message.send('cocos-ecs-extension', 'open-settings'); - }; - - const openProjectAnalysis = () => { - Editor.Message.send('cocos-ecs-extension', 'open-project-analysis'); - }; - - const openComponentLibrary = () => { - Editor.Message.send('cocos-ecs-extension', 'open-component-library'); - }; - const openGithub = () => { Editor.Message.send('cocos-ecs-extension', 'open-github'); }; + const joinQQGroup = () => { + Editor.Message.send('cocos-ecs-extension', 'open-qq-group'); + }; + + const openGenerator = () => { + Editor.Message.send('cocos-ecs-extension', 'open-generator'); + }; + // 组件挂载后检测状态 onMounted(() => { setupMessageListeners(); @@ -510,10 +506,9 @@ module.exports = Editor.Panel.define({ checkForUpdates, openDocumentation, createEcsTemplate, - openSettings, - openProjectAnalysis, - openComponentLibrary, - openGithub + openGithub, + joinQQGroup, + openGenerator }; }, template: readFileSync(join(__dirname, '../../../static/template/vue/welcome.html'), 'utf-8'), diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/generator/index.ts b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/generator/index.ts new file mode 100644 index 00000000..6e41d6fb --- /dev/null +++ b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/generator/index.ts @@ -0,0 +1,240 @@ +import { readFileSync } from 'fs-extra'; +import { join } from 'path'; +import * as path from 'path'; +import { createApp, App, defineComponent, ref, reactive } from 'vue'; +import { CodeGenerator } from '../../CodeGenerator'; + +const panelDataMap = new WeakMap(); + +module.exports = Editor.Panel.define({ + listeners: { + show() { }, + hide() { }, + }, + template: `
`, + style: readFileSync(join(__dirname, '../../../static/style/generator/index.css'), 'utf-8'), + $: { + app: '#app', + }, + ready() { + if (this.$.app) { + const app = createApp(defineComponent({ + setup() { + const featureName = ref(''); + const options = reactive({ + generateComponent: true, + generateSystem: false + }); + + // 组件选项 + const componentOptions = reactive({ + includeComments: true, + addProperties: [] + }); + + // 系统选项 + const systemOptions = reactive({ + systemType: 'EntitySystem' as 'EntitySystem' | 'ProcessingSystem' | 'IntervalSystem' | 'PassiveSystem', + includeComments: true, + requiredComponents: [], + filterByComponent: true + }); + + // 系统类型定义 + const systemTypes = [ + { + value: 'EntitySystem', + name: 'EntitySystem', + icon: '🔄', + description: '批量处理实体,适合需要遍历多个实体的逻辑', + usage: '适用场景:移动系统、渲染系统、物理碰撞系统' + }, + { + value: 'ProcessingSystem', + name: 'ProcessingSystem', + icon: '⚡', + description: '执行全局逻辑,不依赖特定实体', + usage: '适用场景:输入处理、音效管理、场景切换' + }, + { + value: 'IntervalSystem', + name: 'IntervalSystem', + icon: '⏰', + description: '按时间间隔执行,可控制执行频率', + usage: '适用场景:AI决策、状态保存、定时清理' + }, + { + value: 'PassiveSystem', + name: 'PassiveSystem', + icon: '🎯', + description: '被动响应,需要手动调用或事件触发', + usage: '适用场景:技能释放、道具使用、特殊效果' + } + ]; + + const isGenerating = ref(false); + const previewCode = ref(''); + const showPreview = ref(false); + + // 选择系统类型 + const selectSystemType = (type: string) => { + systemOptions.systemType = type as any; + updatePreview(); + }; + + // 生成代码 + const generateCode = async () => { + if (!featureName.value.trim()) { + Editor.Dialog.warn('请输入功能名称', { + detail: '请先输入一个有效的功能名称,例如:Health、Movement、Combat等' + }); + return; + } + + if (!options.generateComponent && !options.generateSystem) { + Editor.Dialog.warn('请选择生成内容', { + detail: '请至少选择一种要生成的代码类型(组件或系统)' + }); + return; + } + + isGenerating.value = true; + + try { + const projectPath = Editor.Project.path; + const ecsDir = path.join(projectPath, 'assets', 'scripts', 'ecs'); + + // 检查ECS目录是否存在 + const fs = require('fs'); + if (!fs.existsSync(ecsDir)) { + Editor.Dialog.warn('ECS目录不存在', { + detail: '请先创建ECS模板后再生成代码。\n\n您可以在欢迎面板中点击"创建ECS模板"来创建基础结构。', + }); + return; + } + + const codeGenerator = new CodeGenerator(); + const generatedFiles: string[] = []; + const baseName = featureName.value.trim(); + + // 生成组件 + if (options.generateComponent) { + const componentDir = path.join(ecsDir, 'components'); + await codeGenerator.generateComponent(baseName, componentDir, componentOptions); + generatedFiles.push(`📦 组件: ${baseName}Component.ts`); + } + + // 生成系统 + if (options.generateSystem) { + const systemDir = path.join(ecsDir, 'systems'); + // 如果选择了组件过滤且生成了组件,自动添加组件过滤 + const requiredComponents = (systemOptions.filterByComponent && options.generateComponent) ? + [`${baseName}Component`] : []; + + const systemOpts = { + ...systemOptions, + requiredComponents + }; + + await codeGenerator.generateSystem( + baseName, + systemDir, + systemOpts + ); + generatedFiles.push(`⚙️ 系统: ${baseName}System.ts`); + } + + // 成功提示 + Editor.Dialog.info('代码生成成功', { + detail: `✅ ${baseName} 功能代码已生成完成!\n\n生成的文件:\n${generatedFiles.join('\n')}\n\n请刷新资源管理器查看新创建的文件。` + }); + + // 清空输入 + featureName.value = ''; + + } catch (error) { + console.error('Failed to generate code:', error); + Editor.Dialog.error('代码生成失败', { + detail: `生成代码时发生错误:\n\n${error}` + }); + } finally { + isGenerating.value = false; + } + }; + + // 预览代码 + const previewGeneration = () => { + if (!featureName.value.trim()) { + showPreview.value = false; + return; + } + + const baseName = featureName.value.trim(); + let preview = `将要生成的文件:\n\n`; + + if (options.generateComponent) { + preview += `📦 组件: ${baseName}Component.ts\n`; + preview += ` - 位置: assets/scripts/ecs/components/\n`; + preview += ` - 基础组件模板\n\n`; + } + + if (options.generateSystem) { + const selectedType = systemTypes.find(t => t.value === systemOptions.systemType); + preview += `⚙️ 系统: ${baseName}System.ts\n`; + preview += ` - 位置: assets/scripts/ecs/systems/\n`; + preview += ` - 类型: ${selectedType?.name || systemOptions.systemType}\n`; + + if (systemOptions.filterByComponent && options.generateComponent) { + preview += ` - 过滤组件: ${baseName}Component\n`; + } else if (systemOptions.filterByComponent) { + preview += ` - 组件过滤: 需要手动配置\n`; + } else { + preview += ` - 组件过滤: 无\n`; + } + preview += `\n`; + } + + previewCode.value = preview; + showPreview.value = true; + }; + + // 监听功能名称变化 + const updatePreview = () => { + if (featureName.value.trim()) { + previewGeneration(); + } else { + showPreview.value = false; + } + }; + + return { + featureName, + options, + componentOptions, + systemOptions, + systemTypes, + isGenerating, + previewCode, + showPreview, + generateCode, + updatePreview, + selectSystemType + }; + }, + template: readFileSync(join(__dirname, '../../../static/template/generator/index.html'), 'utf-8') + })); + + app.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('ui-'); + app.mount(this.$.app); + panelDataMap.set(this, app); + } + }, + beforeClose() { }, + close() { + const app = panelDataMap.get(this); + if (app) { + app.unmount(); + panelDataMap.delete(this); + } + }, +}); \ No newline at end of file diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/settings/index.ts b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/settings/index.ts deleted file mode 100644 index 57bec974..00000000 --- a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/source/panels/settings/index.ts +++ /dev/null @@ -1,370 +0,0 @@ -import { readFileSync } from 'fs-extra'; -import { join } from 'path'; -import { createApp, App, defineComponent, ref, onMounted, reactive } from 'vue'; -import * as fs from 'fs'; -import * as path from 'path'; - -const panelDataMap = new WeakMap(); - -/** - * ECS框架设置配置接口 - */ -interface ECSSettings { - // 代码生成设置 - codeGeneration: { - template: 'typescript' | 'javascript'; - useStrictMode: boolean; - generateComments: boolean; - generateImports: boolean; - componentSuffix: string; - systemSuffix: string; - indentStyle: 'spaces' | 'tabs'; - indentSize: number; - }; - - // 性能监控设置 - performance: { - enableMonitoring: boolean; - warningThreshold: number; // 执行时间警告阈值(ms) - criticalThreshold: number; // 执行时间严重阈值(ms) - memoryWarningMB: number; // 内存警告阈值(MB) - memoryCriticalMB: number; // 内存严重阈值(MB) - maxRecentSamples: number; // 性能采样数量 - enableFpsMonitoring: boolean; - targetFps: number; - }; - - // 调试设置 - debugging: { - enableDebugMode: boolean; - showEntityCount: boolean; - showSystemExecutionTime: boolean; - enablePerformanceWarnings: boolean; - logLevel: 'none' | 'error' | 'warn' | 'info' | 'debug'; - enableDetailedLogs: boolean; - }; - - // 编辑器集成 - editor: { - autoRefreshAssets: boolean; - showWelcomePanelOnStartup: boolean; - enableAutoUpdates: boolean; - updateChannel: 'stable' | 'beta' | 'alpha'; - enableNotifications: boolean; - }; - - // 项目模板设置 - template: { - defaultEntityName: string; - defaultComponentName: string; - defaultSystemName: string; - createExampleFiles: boolean; - includeDocumentation: boolean; - useFactoryPattern: boolean; - }; - - // 事件系统设置 - events: { - enableEventSystem: boolean; - defaultEventPriority: number; - enableAsyncEvents: boolean; - enableEventBatching: boolean; - batchSize: number; - batchDelay: number; // ms - maxEventListeners: number; - }; -} - -/** - * 默认设置 - */ -const defaultSettings: ECSSettings = { - codeGeneration: { - template: 'typescript', - useStrictMode: true, - generateComments: true, - generateImports: true, - componentSuffix: 'Component', - systemSuffix: 'System', - indentStyle: 'spaces', - indentSize: 4 - }, - performance: { - enableMonitoring: true, - warningThreshold: 16.67, // 60fps - criticalThreshold: 33.33, // 30fps - memoryWarningMB: 100, - memoryCriticalMB: 200, - maxRecentSamples: 60, - enableFpsMonitoring: true, - targetFps: 60 - }, - debugging: { - enableDebugMode: true, - showEntityCount: true, - showSystemExecutionTime: true, - enablePerformanceWarnings: true, - logLevel: 'info', - enableDetailedLogs: false - }, - editor: { - autoRefreshAssets: true, - showWelcomePanelOnStartup: true, - enableAutoUpdates: false, - updateChannel: 'stable', - enableNotifications: true - }, - template: { - defaultEntityName: 'GameEntity', - defaultComponentName: 'CustomComponent', - defaultSystemName: 'CustomSystem', - createExampleFiles: true, - includeDocumentation: true, - useFactoryPattern: true - }, - events: { - enableEventSystem: true, - defaultEventPriority: 0, - enableAsyncEvents: true, - enableEventBatching: false, - batchSize: 10, - batchDelay: 16, - maxEventListeners: 100 - } -}; - -/** - * 获取设置文件路径 - */ -function getSettingsPath(): string { - const projectPath = Editor.Project.path; - return path.join(projectPath, '.ecs-framework-settings.json'); -} - -/** - * 加载设置 - */ -function loadSettings(): ECSSettings { - try { - const settingsPath = getSettingsPath(); - if (fs.existsSync(settingsPath)) { - const data = fs.readFileSync(settingsPath, 'utf-8'); - const loadedSettings = JSON.parse(data); - // 合并默认设置,确保所有字段都存在 - return deepMerge(defaultSettings, loadedSettings); - } - } catch (error) { - console.warn('Failed to load ECS settings:', error); - } - return JSON.parse(JSON.stringify(defaultSettings)); -} - -/** - * 保存设置 - */ -function saveSettings(settings: ECSSettings): boolean { - try { - const settingsPath = getSettingsPath(); - fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf-8'); - return true; - } catch (error) { - console.error('Failed to save ECS settings:', error); - return false; - } -} - -/** - * 深度合并对象 - */ -function deepMerge(target: any, source: any): any { - if (source === null || typeof source !== 'object') return source; - if (target === null || typeof target !== 'object') return source; - - const result = { ...target }; - - for (const key in source) { - if (source.hasOwnProperty(key)) { - if (typeof source[key] === 'object' && source[key] !== null && !Array.isArray(source[key])) { - result[key] = deepMerge(target[key], source[key]); - } else { - result[key] = source[key]; - } - } - } - - return result; -} - -/** - * 重置为默认设置 - */ -function resetToDefaults(): ECSSettings { - return JSON.parse(JSON.stringify(defaultSettings)); -} - -module.exports = Editor.Panel.define({ - listeners: { - show() { console.log('ECS Settings Panel Show'); }, - hide() { console.log('ECS Settings Panel Hide'); }, - }, - template: `
`, - style: readFileSync(join(__dirname, '../../../static/style/settings/index.css'), 'utf-8'), - $: { - app: '#app', - }, - ready() { - if (this.$.app) { - // 不要直接设置HTML内容,让Vue来处理 - const app = createApp(defineComponent({ - setup() { - const settings = reactive(loadSettings()); - const isDirty = ref(false); - const saving = ref(false); - const lastSaved = ref(''); - - // 监听设置变化 - const markDirty = () => { - isDirty.value = true; - }; - - // 保存设置 - const saveCurrentSettings = async () => { - saving.value = true; - try { - const success = saveSettings(settings); - if (success) { - isDirty.value = false; - lastSaved.value = new Date().toLocaleTimeString(); - - // 通知主进程设置已更新 - Editor.Message.send('cocos-ecs-extension', 'settings-updated', settings); - - Editor.Dialog.info('设置保存', { - detail: '✅ ECS框架设置已成功保存!', - }); - } else { - Editor.Dialog.error('保存失败', { - detail: '❌ 保存设置时发生错误,请检查文件权限。', - }); - } - } catch (error) { - console.error('Save settings error:', error); - Editor.Dialog.error('保存失败', { - detail: `❌ 保存设置时发生错误:\n\n${error}`, - }); - } finally { - saving.value = false; - } - }; - - // 重置设置 - const resetSettings = () => { - Editor.Dialog.warn('重置设置', { - detail: '⚠️ 您确定要重置所有设置为默认值吗?\n\n此操作无法撤销。', - buttons: ['重置', '取消'], - }).then((result: any) => { - if (result.response === 0) { - const defaults = resetToDefaults(); - Object.assign(settings, defaults); - isDirty.value = true; - - Editor.Dialog.info('设置重置', { - detail: '✅ 设置已重置为默认值,请点击保存按钮确认更改。', - }); - } - }); - }; - - // 导出设置 - const exportSettings = () => { - try { - const dataStr = JSON.stringify(settings, null, 2); - const blob = new Blob([dataStr], { type: 'application/json' }); - const url = URL.createObjectURL(blob); - - // 创建下载链接 - const a = document.createElement('a'); - a.href = url; - a.download = 'ecs-framework-settings.json'; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - URL.revokeObjectURL(url); - - Editor.Dialog.info('导出成功', { - detail: '✅ 设置已导出到下载文件夹。', - }); - } catch (error) { - console.error('Export settings error:', error); - Editor.Dialog.error('导出失败', { - detail: `❌ 导出设置时发生错误:\n\n${error}`, - }); - } - }; - - // 导入设置 - const importSettings = () => { - const input = document.createElement('input'); - input.type = 'file'; - input.accept = '.json'; - input.style.display = 'none'; - - input.onchange = (e: any) => { - const file = e.target.files[0]; - if (!file) return; - - const reader = new FileReader(); - reader.onload = (event) => { - try { - const importedSettings = JSON.parse(event.target?.result as string); - const mergedSettings = deepMerge(defaultSettings, importedSettings); - Object.assign(settings, mergedSettings); - isDirty.value = true; - - Editor.Dialog.info('导入成功', { - detail: '✅ 设置已导入,请检查并保存。', - }); - } catch (error) { - console.error('Import settings error:', error); - Editor.Dialog.error('导入失败', { - detail: `❌ 导入设置文件时发生错误:\n\n${error}\n\n请确保文件格式正确。`, - }); - } - }; - reader.readAsText(file); - }; - - document.body.appendChild(input); - input.click(); - document.body.removeChild(input); - }; - - return { - settings, - isDirty, - saving, - lastSaved, - markDirty, - saveCurrentSettings, - resetSettings, - exportSettings, - importSettings - }; - }, - template: readFileSync(join(__dirname, '../../../static/template/settings/index.html'), 'utf-8'), - })); - - app.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('ui-'); - app.mount(this.$.app); - panelDataMap.set(this, app); - } - }, - beforeClose() { }, - close() { - const app = panelDataMap.get(this); - if (app) { - app.unmount(); - panelDataMap.delete(this); - } - }, -}); \ No newline at end of file diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/style/default/index.css b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/style/default/index.css index 1580bdcb..6f2a6c54 100644 --- a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/style/default/index.css +++ b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/style/default/index.css @@ -356,7 +356,41 @@ transform: none; } -/* 响应式布局优化 */ +/* action-card样式 */ +.action-card.special { + background: linear-gradient(135deg, var(--color-primary-fill) 0%, var(--color-focus-fill) 100%); + border-color: var(--color-primary); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); +} + +.action-card.special h3 { + color: var(--color-primary-contrast); + font-weight: 700; +} + +.action-card.special p { + color: var(--color-primary-contrast); + opacity: 0.9; +} + +.action-card.special:hover { + background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-focus-border) 100%); + border-color: var(--color-focus-border); + transform: translateY(-2px); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); +} + +.action-card.special .icon { + animation: pulse 2s infinite; +} + +@keyframes pulse { + 0% { transform: scale(1); } + 50% { transform: scale(1.1); } + 100% { transform: scale(1); } +} + +/* 响应式布局 */ @media (max-width: 600px) { .welcome-container { padding: 16px; @@ -377,7 +411,6 @@ } } -/* 确保按钮文本不被截断 */ .management-buttons ui-button { white-space: nowrap; overflow: hidden; diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/style/generator/index.css b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/style/generator/index.css new file mode 100644 index 00000000..10c9c91e --- /dev/null +++ b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/style/generator/index.css @@ -0,0 +1,378 @@ +/* ECS代码生成器样式 */ +.ecs-generator { + height: 100%; + background: var(--color-panel-bg); + color: var(--color-text-normal); + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + overflow: hidden; +} + +.generator-container { + padding: 16px; + height: 100%; + display: flex; + flex-direction: column; + overflow-y: auto; + overflow-x: hidden; + max-height: 100vh; + box-sizing: border-box; +} + +/* 头部样式 */ +.generator-header { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 16px; + border-radius: 6px; + margin-bottom: 16px; + text-align: center; + flex-shrink: 0; +} + +.generator-header h1 { + margin: 0 0 6px 0; + font-size: 20px; + font-weight: 600; +} + +.generator-header p { + margin: 0; + opacity: 0.9; + font-size: 13px; +} + +/* 表单区域 */ +.generator-form { + background: var(--color-area-bg); + border: 1px solid var(--color-border); + border-radius: 6px; + padding: 16px; + margin-bottom: 16px; + flex-shrink: 0; +} + +.form-title { + font-size: 15px; + font-weight: 600; + margin-bottom: 16px; + color: var(--color-text-normal); +} + +/* 输入字段 */ +.input-group { + margin-bottom: 20px; +} + +.input-label { + display: block; + font-size: 14px; + font-weight: 500; + color: var(--color-text-normal); + margin-bottom: 8px; +} + +.feature-input { + width: 100%; + padding: 8px 12px; + font-size: 14px; + border: 1px solid var(--color-border); + border-radius: 4px; + background: var(--color-panel-bg); + color: var(--color-text-normal); + box-sizing: border-box; + transition: border-color 0.2s ease; +} + +.feature-input:focus { + outline: none; + border-color: #667eea; +} + +.input-hint { + margin-top: 6px; + font-size: 12px; + color: var(--color-text-contrast-weakest); + font-style: italic; +} + +/* 选项组 */ +.options-group { + margin-bottom: 20px; +} + +.option-item { + display: flex; + align-items: center; + padding: 8px 0; + margin-bottom: 8px; +} + +.option-item:last-child { + margin-bottom: 0; +} + +/* 复选框样式 */ +.checkbox-wrapper { + display: flex; + align-items: center; + cursor: pointer; + user-select: none; +} + +.checkbox-wrapper input[type="checkbox"] { + margin-right: 8px; + width: 16px; + height: 16px; + cursor: pointer; +} + +.option-title { + font-size: 14px; + font-weight: 500; + color: var(--color-text-normal); +} + +.option-description { + margin-left: 24px; + margin-top: 4px; + font-size: 12px; + color: var(--color-text-contrast-weakest); +} + +/* 系统配置区域 */ +.system-config { + margin-top: 16px; + padding: 16px; + background: var(--color-panel-bg); + border: 1px solid var(--color-border-soft); + border-radius: 6px; +} + +.config-section { + margin-bottom: 20px; +} + +.config-section:last-child { + margin-bottom: 0; +} + +.config-label { + display: block; + font-size: 14px; + font-weight: 600; + color: var(--color-text-normal); + margin-bottom: 12px; +} + +.filter-option { + margin-bottom: 8px; +} + +/* 系统类型卡片 */ +.system-type-cards { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 12px; +} + +.system-card { + padding: 16px; + border: 2px solid var(--color-border); + border-radius: 8px; + background: var(--color-area-bg); + cursor: pointer; + transition: all 0.2s ease; + position: relative; +} + +.system-card:hover { + border-color: #667eea; + background: var(--color-panel-bg); +} + +.system-card.active { + border-color: #667eea; + background: var(--color-panel-bg); + box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.1); +} + +.system-card.active::after { + content: '✓'; + position: absolute; + top: 8px; + right: 12px; + color: #667eea; + font-weight: bold; + font-size: 16px; +} + +.card-header { + display: flex; + align-items: center; + margin-bottom: 8px; +} + +.card-icon { + font-size: 20px; + margin-right: 8px; +} + +.card-title { + font-size: 15px; + font-weight: 600; + color: var(--color-text-normal); +} + +.card-description { + font-size: 13px; + color: var(--color-text-contrast-weak); + margin-bottom: 6px; + line-height: 1.4; +} + +.card-usage { + font-size: 12px; + color: var(--color-text-contrast-weakest); + font-style: italic; + line-height: 1.3; +} + +/* 系统类型选择 */ +.system-type-group { + margin-left: 24px; + margin-top: 8px; +} + +.system-type-select { + padding: 6px 8px; + border: 1px solid var(--color-border); + border-radius: 4px; + background: var(--color-panel-bg); + color: var(--color-text-normal); + font-size: 13px; + cursor: pointer; +} + +/* 预览区域 */ +.preview-section { + background: var(--color-area-bg); + border: 1px solid var(--color-border); + border-radius: 6px; + padding: 16px; + margin-bottom: 16px; + flex: 1; + min-height: 200px; + display: flex; + flex-direction: column; +} + +.preview-title { + font-size: 15px; + font-weight: 600; + margin-bottom: 12px; + color: var(--color-text-normal); +} + +.preview-content { + flex: 1; + background: var(--color-panel-bg); + border: 1px solid var(--color-border-soft); + border-radius: 4px; + padding: 12px; + font-family: 'Courier New', monospace; + font-size: 12px; + color: var(--color-text-contrast-weak); + overflow-y: auto; + white-space: pre-wrap; +} + +/* 操作按钮区域 */ +.action-section { + background: var(--color-area-bg); + border: 1px solid var(--color-border); + border-radius: 6px; + padding: 16px; + flex-shrink: 0; +} + +.generate-btn { + width: 100%; + padding: 12px 16px; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + border: none; + border-radius: 6px; + font-size: 14px; + font-weight: 600; + cursor: pointer; + transition: opacity 0.2s ease; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; +} + +.generate-btn:hover:not(:disabled) { + opacity: 0.9; +} + +.generate-btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.btn-icon { + font-size: 16px; +} + +.btn-icon.spinning { + animation: spin 1s linear infinite; +} + +@keyframes spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } +} + +/* 滚动条样式 */ +.generator-container::-webkit-scrollbar, +.preview-content::-webkit-scrollbar { + width: 8px; +} + +.generator-container::-webkit-scrollbar-track, +.preview-content::-webkit-scrollbar-track { + background: var(--color-area-bg); +} + +.generator-container::-webkit-scrollbar-thumb, +.preview-content::-webkit-scrollbar-thumb { + background: var(--color-border); + border-radius: 4px; +} + +.generator-container::-webkit-scrollbar-thumb:hover, +.preview-content::-webkit-scrollbar-thumb:hover { + background: var(--color-border-emphasis); +} + +/* 响应式设计 */ +@media (max-width: 600px) { + .generator-container { + padding: 12px; + } + + .generator-header h1 { + font-size: 18px; + } + + .feature-input { + font-size: 16px; + } +} + + + + + + \ No newline at end of file diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/style/settings/index.css b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/style/settings/index.css deleted file mode 100644 index edcb9020..00000000 --- a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/style/settings/index.css +++ /dev/null @@ -1,353 +0,0 @@ -/* ECS Framework 设置面板样式 */ -.settings-container { - height: 100%; - display: flex; - flex-direction: column; - background: var(--color-normal-fill); - font-family: var(--font-family); -} - -/* 头部样式 */ -.settings-header { - display: flex; - justify-content: space-between; - align-items: flex-start; - padding: 16px 20px; - background: var(--color-info-fill); - border-bottom: 1px solid var(--color-normal-border); - flex-shrink: 0; -} - -.header-title h1 { - margin: 0; - font-size: 18px; - font-weight: 600; - color: var(--color-default-text); -} - -.header-title p { - margin: 4px 0 0 0; - font-size: 12px; - color: var(--color-focus-text); - opacity: 0.8; -} - -.header-actions { - display: flex; - gap: 8px; -} - -.header-actions ui-button { - min-width: 80px; - height: 28px; - font-size: 12px; -} - -/* 保存按钮状态 */ -.save-button.dirty { - background: var(--color-warn-fill) !important; - border-color: var(--color-warn-border) !important; - color: var(--color-warn-text) !important; -} - -.save-button.saving { - background: var(--color-info-fill) !important; - opacity: 0.7; -} - -/* 图标动画 */ -.spin { - animation: spin 1s linear infinite; -} - -@keyframes spin { - from { transform: rotate(0deg); } - to { transform: rotate(360deg); } -} - -/* 状态栏 */ -.status-bar { - padding: 8px 20px; - background: var(--color-success-fill); - border-bottom: 1px solid var(--color-normal-border); - flex-shrink: 0; -} - -.status-text { - font-size: 12px; - color: var(--color-success-text); -} - -/* 设置内容区域 */ -.settings-content { - flex: 1; - overflow-y: auto; - overflow-x: hidden; - padding: 0 20px 20px 20px; - max-height: calc(100vh - 140px); /* 确保有固定的滚动区域 */ - scroll-behavior: smooth; /* 平滑滚动 */ -} - -/* 设置分组 */ -.settings-section { - margin-bottom: 32px; - background: var(--color-default-fill); - border: 1px solid var(--color-normal-border); - border-radius: 8px; - overflow: hidden; -} - -.section-header { - padding: 16px 20px; - background: var(--color-focus-fill); - border-bottom: 1px solid var(--color-normal-border); -} - -.section-header h2 { - margin: 0; - font-size: 16px; - font-weight: 600; - color: var(--color-default-text); -} - -.section-header p { - margin: 4px 0 0 0; - font-size: 12px; - color: var(--color-focus-text); - opacity: 0.8; -} - -/* 设置网格 */ -.settings-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: 16px; - padding: 20px; -} - -/* 设置项 */ -.setting-item { - display: flex; - flex-direction: column; - gap: 6px; -} - -.setting-item label { - font-size: 12px; - font-weight: 500; - color: var(--color-default-text); -} - -.setting-item ui-input, -.setting-item ui-select, -.setting-item ui-num-input { - width: 100%; - height: 26px; - font-size: 12px; -} - -/* 复选框项样式 */ -.checkbox-item { - flex-direction: row; - align-items: center; - gap: 8px; -} - -.checkbox-item ui-checkbox { - margin: 0; -} - -/* 全宽设置项 */ -.setting-item.full-width { - grid-column: 1 / -1; -} - -/* 底部区域 */ -.settings-footer { - display: flex; - justify-content: space-between; - align-items: center; - padding: 12px 20px; - background: var(--color-focus-fill); - border-top: 1px solid var(--color-normal-border); - flex-shrink: 0; -} - -.footer-info { - display: flex; - align-items: center; - gap: 6px; - font-size: 11px; - color: var(--color-focus-text); - opacity: 0.8; -} - -.footer-info ui-icon { - width: 14px; - height: 14px; -} - -.footer-actions { - display: flex; - align-items: center; -} - -.dirty-indicator { - font-size: 11px; - color: var(--color-warn-text); - font-weight: 500; -} - -/* 响应式设计 */ -@media (max-width: 768px) { - .settings-header { - flex-direction: column; - gap: 12px; - align-items: stretch; - } - - .header-actions { - justify-content: flex-end; - } - - .settings-grid { - grid-template-columns: 1fr; - } - - .settings-footer { - flex-direction: column; - gap: 8px; - align-items: stretch; - text-align: center; - } -} - -/* 深色主题支持 */ -@media (prefers-color-scheme: dark) { - .settings-container { - background: #2c2c2c; - } - - .settings-section { - background: #3c3c3c; - border-color: #555; - } - - .section-header { - background: #404040; - border-color: #555; - } - - .settings-header { - background: #333; - border-color: #555; - } - - .status-bar { - background: #2d5a2d; - } - - .settings-footer { - background: #333; - border-color: #555; - } -} - -/* 优化滚动条样式 */ -.settings-content::-webkit-scrollbar { - width: 10px; -} - -.settings-content::-webkit-scrollbar-track { - background: var(--color-normal-fill); - border-radius: 5px; - margin: 2px; -} - -.settings-content::-webkit-scrollbar-thumb { - background: var(--color-focus-border); - border-radius: 5px; - transition: background-color 0.2s ease; - min-height: 30px; -} - -.settings-content::-webkit-scrollbar-thumb:hover { - background: var(--color-warn-border); -} - -.settings-content::-webkit-scrollbar-thumb:active { - background: var(--color-danger-border); -} - -/* 表单元素统一样式 */ -.setting-item ui-input, -.setting-item ui-select, -.setting-item ui-num-input { - border: 1px solid var(--color-normal-border); - border-radius: 4px; - padding: 4px 8px; - background: var(--color-default-fill); - color: var(--color-default-text); - transition: border-color 0.2s ease; -} - -.setting-item ui-input:focus, -.setting-item ui-select:focus, -.setting-item ui-num-input:focus { - border-color: var(--color-focus-border); - outline: none; - box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1); -} - -/* 复选框样式 */ -.setting-item ui-checkbox { - font-size: 12px; - color: var(--color-default-text); -} - -/* 按钮样式覆盖 */ -.header-actions .export-button { - background: var(--color-info-fill); - border-color: var(--color-info-border); - color: var(--color-info-text); -} - -.header-actions .import-button { - background: var(--color-warn-fill); - border-color: var(--color-warn-border); - color: var(--color-warn-text); -} - -.header-actions .reset-button { - background: var(--color-danger-fill); - border-color: var(--color-danger-border); - color: var(--color-danger-text); -} - -/* 工具提示样式 */ -.setting-item[title] { - cursor: help; -} - -/* 加载状态 */ -.loading-overlay { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.1); - display: flex; - align-items: center; - justify-content: center; - z-index: 1000; -} - -.loading-spinner { - width: 32px; - height: 32px; - border: 3px solid var(--color-normal-border); - border-top: 3px solid var(--color-focus-border); - border-radius: 50%; - animation: spin 1s linear infinite; -} \ No newline at end of file diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/template/generator/index.html b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/template/generator/index.html new file mode 100644 index 00000000..41abd80c --- /dev/null +++ b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/template/generator/index.html @@ -0,0 +1,111 @@ +
+
+ +
+

🛠️ ECS 代码生成器

+

输入功能名称,快速生成组件和系统代码

+
+ + +
+
📝 基础设置
+ + +
+ + +
+ 💡 使用英文名称,首字母大写,例如:Health、Movement、Combat +
+
+ + +
+ + +
+ +
+
+ 创建基础组件类,包含reset()方法和基本结构 +
+ +
+ +
+
+ 创建处理组件的系统类,包含完整的生命周期方法 +
+ + +
+ +
+ +
+ +
+
+ 系统只处理包含指定组件的实体。如果勾选了"生成组件",会自动过滤{{featureName}}Component +
+
+ + +
+ +
+
+
+ {{ type.icon }} + {{ type.name }} +
+
{{ type.description }}
+
{{ type.usage }}
+
+
+
+
+
+
+ + +
+
👀 生成预览
+
{{ previewCode }}
+
+ + +
+ +
+
+
\ No newline at end of file diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/template/settings/index.html b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/template/settings/index.html deleted file mode 100644 index c126b3ac..00000000 --- a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/template/settings/index.html +++ /dev/null @@ -1,322 +0,0 @@ -
-
- -
-
-

🔧 ECS Framework 设置

-

配置ECS框架的行为和性能选项

-
-
- - - - {{ saving ? '保存中...' : (isDirty ? '保存 *' : '保存') }} - - - - 导出 - - - - 导入 - - - - 重置 - -
-
- - -
- 最后保存: {{ lastSaved }} -
- - -
- -
-
-

📝 代码生成设置

-

配置自动生成代码的格式和选项

-
-
-
- - - - - -
-
- - -
-
- - -
-
- - - - - -
-
- - -
-
- - 启用严格模式 - -
-
- - 生成注释 - -
-
- - 自动添加导入语句 - -
-
-
- - -
-
-

⚡ 性能监控设置

-

配置性能监控和优化建议

-
-
-
- - 启用性能监控 - -
-
- - 启用FPS监控 - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
- - -
-
-

🐛 调试设置

-

配置调试模式和日志选项

-
-
-
- - 启用调试模式 - -
-
- - 显示实体数量 - -
-
- - 显示系统执行时间 - -
-
- - 启用性能警告 - -
-
- - 启用详细日志 - -
-
- - - - - - - - -
-
-
- - -
-
-

⚙️ 编辑器集成

-

配置与Cocos Creator的集成选项

-
-
-
- - 自动刷新资源 - -
-
- - 启动时显示欢迎面板 - -
-
- - 启用自动更新 - -
-
- - 启用通知 - -
-
- - - - - - -
-
-
- - -
-
-

📁 项目模板设置

-

配置生成项目模板的默认选项

-
-
-
- - -
-
- - -
-
- - -
-
- - 创建示例文件 - -
-
- - 包含文档 - -
-
- - 使用工厂模式 - -
-
-
- - -
-
-

📡 事件系统设置

-

配置事件系统的行为和性能

-
-
-
- - 启用事件系统 - -
-
- - 启用异步事件 - -
-
- - 启用事件批处理 - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-
- - - -
-
\ No newline at end of file diff --git a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/template/vue/welcome.html b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/template/vue/welcome.html index 8f6db2e7..ffc612d3 100644 --- a/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/template/vue/welcome.html +++ b/extensions/cocos/cocos-ecs/extensions/cocos-ecs-extension/static/template/vue/welcome.html @@ -100,7 +100,7 @@

安装@esengine/ecs-framework到当前项目

-
+

📚 查看文档 @@ -134,36 +134,29 @@

+ -
+ +
+
🛠️ 代码生成工具
+ +

- ⚙️ - 插件设置 + 🚀 + 代码生成器

-

配置ECS插件的各项设置和偏好

+

一站式代码生成工具,输入功能名称快速生成组件和系统代码

-
-

- 📊 - 项目分析 -

-

分析当前项目的ECS使用情况和性能建议

-
- -
-

- 🧩 - 组件库 -

-

浏览和管理项目中的ECS组件

-
\ No newline at end of file diff --git a/extensions/cocos/cocos-ecs/package-lock.json b/extensions/cocos/cocos-ecs/package-lock.json index 86d3844b..6339e326 100644 --- a/extensions/cocos/cocos-ecs/package-lock.json +++ b/extensions/cocos/cocos-ecs/package-lock.json @@ -10,9 +10,9 @@ } }, "node_modules/@esengine/ecs-framework": { - "version": "2.1.19", - "resolved": "https://registry.npmjs.org/@esengine/ecs-framework/-/ecs-framework-2.1.19.tgz", - "integrity": "sha512-yS6g1Swdd/FvnIrdmaxBh6ml5r+Oh4edIhGwVfEbzQMHUmrZQbva7/NGyOhTsJ6qsIGVyNin8o46tTud2YCj4g==", + "version": "2.1.20", + "resolved": "https://registry.npmjs.org/@esengine/ecs-framework/-/ecs-framework-2.1.20.tgz", + "integrity": "sha512-L6PJ1uoXIttzjYt66shZPdmJ4lU38SyqRnEcVJexcR+V6iyQ/U7H8yjvQjeTIlBb0u7JDBEC6a8B4Cr6VlsF9Q==", "engines": { "node": ">=16.0.0" } diff --git a/src/ECS/Core/Storage/index.ts b/src/ECS/Core/Storage/index.ts index c035be7a..12b1d337 100644 --- a/src/ECS/Core/Storage/index.ts +++ b/src/ECS/Core/Storage/index.ts @@ -1,2 +1,2 @@ -export { ComponentPool } from '../ComponentPool'; +export { ComponentPool, ComponentPoolManager } from '../ComponentPool'; export { ComponentStorage } from '../ComponentStorage'; \ No newline at end of file