更新生成代码工具

This commit is contained in:
YHH
2025-06-17 10:46:47 +08:00
parent e6789e49e4
commit 7808f64fe5
22 changed files with 1345 additions and 1248 deletions

View File

@@ -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
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "80dcbaf5-21f7-4bb1-aff4-2cdbb0b5d364",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -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. 专业的ECS框架开发助手为Cocos Creator提供完整的实体组件系统(ECS)开发工具链。
The panel is based on Vue3.x.
## Development Environment ## 🎯 主要功能
Node.js ### 📦 一键安装管理
- **自动检测**实时检测ECS框架安装状态和版本信息
- **一键安装**:快速安装 `@esengine/ecs-framework` 到当前项目
- **版本管理**:自动检查更新,支持一键更新到最新版本
- **智能卸载**:安全卸载框架,保护项目完整性
## Install ### 🚀 代码生成器
- **智能生成**:输入功能名称,自动生成对应的组件和系统代码
- **多种系统类型**支持EntitySystem、ProcessingSystem、IntervalSystem、PassiveSystem
- **组件配置**:可选择添加属性、注释等定制化选项
- **组件过滤**:支持生成带组件过滤的高级系统
```bash ### 🛠️ 项目模板
# Install dependent modules - **快速启动**一键生成完整的ECS项目结构
npm install - **预设组件**包含位置、速度、Cocos节点等常用组件
# build - **系统示例**:提供移动系统、节点同步系统等实用示例
npm run build - **工厂模式**:包含实体工厂和场景管理器模板
```
## 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开发变得简单高效专注于游戏逻辑而非框架配置

View File

@@ -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` 方法。

View File

@@ -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"}; "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."};

View File

@@ -1 +1 @@
"use strict";module.exports={open_panel:"默认面板",send_to_panel:"发送消息给面板",description:"含有一个基于Vue3.x开发的面板的扩展"}; "use strict";module.exports={open_panel:"默认面板",send_to_panel:"发送消息给面板",description:"专业的ECS框架开发助手一键安装@esengine/ecs-framework智能代码生成器快速创建组件和系统项目模板生成实时状态检测和版本管理。提供欢迎面板、调试面板和代码生成器让Cocos Creator的ECS开发更高效便捷。"};

View File

@@ -10,12 +10,14 @@
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"vue": "^3.1.4" "vue": "^3.1.4",
"ws": "^8.14.2"
}, },
"devDependencies": { "devDependencies": {
"@cocos/creator-types": "^3.8.6", "@cocos/creator-types": "^3.8.6",
"@types/fs-extra": "^9.0.5", "@types/fs-extra": "^9.0.5",
"@types/node": "^18.17.1", "@types/node": "^18.17.1",
"@types/ws": "^8.5.10",
"typescript": "^5.8.2" "typescript": "^5.8.2"
} }
}, },
@@ -57,6 +59,15 @@
"undici-types": "~5.26.4" "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": { "node_modules/@vue/compiler-core": {
"version": "3.3.4", "version": "3.3.4",
"license": "MIT", "license": "MIT",
@@ -282,6 +293,26 @@
"@vue/server-renderer": "3.3.4", "@vue/server-renderer": "3.3.4",
"@vue/shared": "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
}
}
} }
} }
} }

View File

@@ -13,12 +13,14 @@
"main": "./dist/main.js", "main": "./dist/main.js",
"dependencies": { "dependencies": {
"vue": "^3.1.4", "vue": "^3.1.4",
"fs-extra": "^10.0.0" "fs-extra": "^10.0.0",
"ws": "^8.14.2"
}, },
"devDependencies": { "devDependencies": {
"@cocos/creator-types": "^3.8.6", "@cocos/creator-types": "^3.8.6",
"@types/fs-extra": "^9.0.5", "@types/fs-extra": "^9.0.5",
"@types/node": "^18.17.1", "@types/node": "^18.17.1",
"@types/ws": "^8.5.10",
"typescript": "^5.8.2" "typescript": "^5.8.2"
}, },
"panels": { "panels": {
@@ -33,17 +35,6 @@
"height": 800 "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": { "debug": {
"title": "ECS Framework - 调试面板", "title": "ECS Framework - 调试面板",
"type": "dockable", "type": "dockable",
@@ -54,6 +45,17 @@
"width": 500, "width": 500,
"height": 600 "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": { "contributions": {
@@ -68,13 +70,13 @@
}, },
{ {
"path": "i18n:menu.panel/ECS Framework", "path": "i18n:menu.panel/ECS Framework",
"label": "插件设置", "label": "调试面板",
"message": "open-settings" "message": "open-debug"
}, },
{ {
"path": "i18n:menu.panel/ECS Framework", "path": "i18n:menu.panel/ECS Framework",
"label": "调试面板", "label": "代码生成器",
"message": "open-debug" "message": "open-generator"
}, },
{ {
"path": "i18n:menu.develop/ECS Framework", "path": "i18n:menu.develop/ECS Framework",
@@ -113,35 +115,25 @@
"create-ecs-template" "create-ecs-template"
] ]
}, },
"open-settings": {
"methods": [
"open-settings"
]
},
"open-project-analysis": {
"methods": [
"open-project-analysis"
]
},
"open-component-library": {
"methods": [
"open-component-library"
]
},
"open-github": { "open-github": {
"methods": [ "methods": [
"open-github" "open-github"
] ]
}, },
"settings-updated": { "open-qq-group": {
"methods": [ "methods": [
"settings-updated" "open-qq-group"
] ]
}, },
"open-debug": { "open-debug": {
"methods": [ "methods": [
"open-debug" "open-debug"
] ]
},
"open-generator": {
"methods": [
"open-generator"
]
} }
} }
} }

View File

@@ -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<void> {
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<void> {
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}) {
// 添加处理逻辑
}`;
}
}

View File

@@ -2,9 +2,11 @@
import packageJSON from '../package.json'; import packageJSON from '../package.json';
import { exec } from 'child_process'; import { exec } from 'child_process';
import * as path from 'path'; import * as path from 'path';
import * as fs from 'fs';
import { readFileSync, outputFile } from 'fs-extra'; import { readFileSync, outputFile } from 'fs-extra';
import { join } from 'path'; import { join } from 'path';
import { TemplateGenerator } from './TemplateGenerator'; import { TemplateGenerator } from './TemplateGenerator';
import { CodeGenerator } from './CodeGenerator';
/** /**
* @en Registration method for the main process of Extension * @en Registration method for the main process of Extension
@@ -120,16 +122,28 @@ export const methods: { [key: string]: (...any: any) => any } = {
* 打开文档 * 打开文档
*/ */
'open-documentation'() { 'open-documentation'() {
// 使用系统默认命令打开链接
const url = 'https://github.com/esengine/ecs-framework/blob/master/README.md'; const url = 'https://github.com/esengine/ecs-framework/blob/master/README.md';
exec(`start "" "${url}"`, (error) => {
if (error) { try {
console.error('Failed to open documentation:', error); // 使用Electron的shell模块打开外部链接推荐方法
Editor.Dialog.info('打开文档', { const { shell } = require('electron');
detail: `请手动访问以下链接查看文档:\n\n${url}`, 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'() { 'open-github'() {
console.log('Opening ECS Framework settings panel...'); const url = 'https://github.com/esengine/ecs-framework';
try { try {
// 正确的打开特定面板的方法 // 使用Electron的shell模块打开外部链接推荐方法
Editor.Panel.open(packageJSON.name + '.settings'); const { shell } = require('electron');
console.log('Settings panel opened successfully'); shell.openExternal(url);
console.log('GitHub link opened successfully');
} catch (error) { } catch (error) {
console.error('Failed to open settings panel:', error); console.error('Failed to open GitHub with shell.openExternal, trying exec:', error);
Editor.Dialog.error('打开设置失败', {
detail: `无法打开设置面板:\n\n${error}\n\n请尝试重启Cocos Creator编辑器。`, // 备用方法:使用系统命令
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'() { 'open-qq-group'() {
Editor.Dialog.info('项目分析', { const url = 'https://qm.qq.com/cgi-bin/qm/qr?k=1DMoPJEsY5xUpTAcmjIHK8whgHJHYQTL&authKey=%2FklVb3S0Momc1q1J%2FWHncuwMVHGrDbwV1Y6gAfa5e%2FgHCvyYUL2gpA6hSOU%2BVSa5&noverify=0&group_code=481923584';
detail: '项目分析功能开发中...\n\n将在下个版本提供以下分析功能\n• ECS架构合理性分析\n• 性能瓶颈检测\n• 组件使用统计\n• 系统执行效率分析\n• 内存使用优化建议',
buttons: ['好的'], 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);
'open-component-library'() {
Editor.Dialog.info('组件库', { // 备用方法:使用系统命令
detail: '组件库功能开发中...\n\n将在下个版本提供\n• 常用组件模板库\n• 系统模板库\n• 一键生成组件代码\n• 社区组件分享\n• 组件文档和示例', exec(`start "" "${url}"`, (execError) => {
buttons: ['好的'], 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`,
/** });
* 打开GitHub仓库 } else {
*/ console.log('QQ group link opened successfully with exec');
'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}`,
});
}
});
}, },
/** /**
@@ -268,36 +285,18 @@ export const methods: { [key: string]: (...any: any) => any } = {
}, },
/** /**
* 处理设置更新 * 打开代码生成器面板
*/ */
'settings-updated'(settings: any) { 'open-generator'() {
console.log('ECS Framework settings updated:', settings); console.log('Opening ECS Framework code generator panel...');
try {
// 这里可以根据设置更新做一些处理 // 正确的打开特定面板的方法
// 比如重新配置框架、更新性能监控等 Editor.Panel.open(packageJSON.name + '.generator');
console.log('Generator panel opened successfully');
// 示例:根据设置更新性能监控 } catch (error) {
if (settings?.performance?.enableMonitoring) { console.error('Failed to open generator panel:', error);
console.log('Performance monitoring enabled with thresholds:', { Editor.Dialog.error('打开代码生成器失败', {
warning: settings.performance.warningThreshold, detail: `无法打开代码生成器面板:\n\n${error}\n\n请尝试重启Cocos Creator编辑器。`,
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
}); });
} }
}, },

View File

@@ -1,7 +1,8 @@
import { readFileSync } from 'fs-extra'; import { readFileSync } from 'fs-extra';
import { join } from 'path'; import { join } from 'path';
import { createApp, App, defineComponent, ref, reactive, onMounted, onUnmounted } from 'vue'; 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<any, App>(); const panelDataMap = new WeakMap<any, App>();
@@ -15,7 +16,7 @@ interface GameInstance {
lastUpdateTime: number; lastUpdateTime: number;
isActive: boolean; isActive: boolean;
debugData?: any; debugData?: any;
ws?: any; // WebSocket连接 ws?: WebSocket; // WebSocket连接
} }
/** /**
@@ -136,7 +137,7 @@ class ECSDebugServer {
try { try {
this.wss = new WebSocketServer({ port: this.port }); 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 instanceId = this.generateInstanceId();
const instance: GameInstance = { const instance: GameInstance = {
id: instanceId, id: instanceId,
@@ -151,7 +152,7 @@ class ECSDebugServer {
this.gameInstances.set(instanceId, instance); this.gameInstances.set(instanceId, instance);
console.log(`[ECS Debug Server] New instance connected: ${instance.name}`); console.log(`[ECS Debug Server] New instance connected: ${instance.name}`);
ws.on('message', (data) => { ws.on('message', (data: Buffer) => {
try { try {
const message = JSON.parse(data.toString()); const message = JSON.parse(data.toString());
this.handleMessage(instanceId, message); 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); console.error(`[ECS Debug Server] WebSocket error for ${instanceId}:`, error);
}); });

View File

@@ -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 = () => { const openGithub = () => {
Editor.Message.send('cocos-ecs-extension', 'open-github'); 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(() => { onMounted(() => {
setupMessageListeners(); setupMessageListeners();
@@ -510,10 +506,9 @@ module.exports = Editor.Panel.define({
checkForUpdates, checkForUpdates,
openDocumentation, openDocumentation,
createEcsTemplate, createEcsTemplate,
openSettings, openGithub,
openProjectAnalysis, joinQQGroup,
openComponentLibrary, openGenerator
openGithub
}; };
}, },
template: readFileSync(join(__dirname, '../../../static/template/vue/welcome.html'), 'utf-8'), template: readFileSync(join(__dirname, '../../../static/template/vue/welcome.html'), 'utf-8'),

View File

@@ -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<any, App>();
module.exports = Editor.Panel.define({
listeners: {
show() { },
hide() { },
},
template: `<div id="app"></div>`,
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);
}
},
});

View File

@@ -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<any, App>();
/**
* 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: `<div id="app"></div>`,
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);
}
},
});

View File

@@ -356,7 +356,41 @@
transform: none; 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) { @media (max-width: 600px) {
.welcome-container { .welcome-container {
padding: 16px; padding: 16px;
@@ -377,7 +411,6 @@
} }
} }
/* 确保按钮文本不被截断 */
.management-buttons ui-button { .management-buttons ui-button {
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -0,0 +1,111 @@
<div class="ecs-generator">
<div class="generator-container">
<!-- 头部区域 -->
<div class="generator-header">
<h1>🛠️ ECS 代码生成器</h1>
<p>输入功能名称,快速生成组件和系统代码</p>
</div>
<!-- 表单区域 -->
<div class="generator-form">
<div class="form-title">📝 基础设置</div>
<!-- 功能名称输入 -->
<div class="input-group">
<label class="input-label">功能名称</label>
<input
v-model="featureName"
@input="updatePreview"
type="text"
class="feature-input"
placeholder="例如Health、Movement、Combat"
maxlength="50"
/>
<div class="input-hint">
💡 使用英文名称首字母大写例如Health、Movement、Combat
</div>
</div>
<!-- 生成选项 -->
<div class="options-group">
<label class="input-label">生成内容</label>
<div class="option-item">
<label class="checkbox-wrapper">
<input type="checkbox" v-model="options.generateComponent" @change="updatePreview">
<span class="option-title">📦 生成组件 (Component)</span>
</label>
</div>
<div class="option-description" v-if="options.generateComponent">
创建基础组件类包含reset()方法和基本结构
</div>
<div class="option-item">
<label class="checkbox-wrapper">
<input type="checkbox" v-model="options.generateSystem" @change="updatePreview">
<span class="option-title">⚙️ 生成系统 (System)</span>
</label>
</div>
<div class="option-description" v-if="options.generateSystem">
创建处理组件的系统类,包含完整的生命周期方法
</div>
<!-- 系统详细配置 -->
<div class="system-config" v-if="options.generateSystem">
<!-- 组件过滤选项 -->
<div class="config-section">
<label class="config-label">🔍 组件过滤</label>
<div class="filter-option">
<label class="checkbox-wrapper">
<input type="checkbox" v-model="systemOptions.filterByComponent" @change="updatePreview">
<span class="option-title">过滤包含组件的实体</span>
</label>
</div>
<div class="option-description" v-if="systemOptions.filterByComponent">
系统只处理包含指定组件的实体。如果勾选了"生成组件",会自动过滤{{featureName}}Component
</div>
</div>
<!-- 系统类型选择 -->
<div class="config-section">
<label class="config-label">🎯 系统类型</label>
<div class="system-type-cards">
<div
v-for="type in systemTypes"
:key="type.value"
class="system-card"
:class="{ active: systemOptions.systemType === type.value }"
@click="selectSystemType(type.value)">
<div class="card-header">
<span class="card-icon">{{ type.icon }}</span>
<span class="card-title">{{ type.name }}</span>
</div>
<div class="card-description">{{ type.description }}</div>
<div class="card-usage">{{ type.usage }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 预览区域 -->
<div class="preview-section" v-if="showPreview">
<div class="preview-title">👀 生成预览</div>
<div class="preview-content">{{ previewCode }}</div>
</div>
<!-- 生成按钮 -->
<div class="action-section">
<button
class="generate-btn"
:disabled="isGenerating || (!options.generateComponent && !options.generateSystem) || !featureName.trim()"
@click="generateCode">
<span class="btn-icon" :class="{ spinning: isGenerating }">
{{ isGenerating ? '⏳' : '🚀' }}
</span>
{{ isGenerating ? '生成中...' : '生成代码' }}
</button>
</div>
</div>
</div>

View File

@@ -1,322 +0,0 @@
<div id="app">
<div class="settings-container">
<!-- 头部 -->
<div class="settings-header">
<div class="header-title">
<h1>🔧 ECS Framework 设置</h1>
<p>配置ECS框架的行为和性能选项</p>
</div>
<div class="header-actions">
<ui-button class="save-button" :class="{ dirty: isDirty, saving: saving }"
@click="saveCurrentSettings" :disabled="saving">
<ui-icon value="confirm" v-if="!saving"></ui-icon>
<ui-icon value="loading" class="spin" v-if="saving"></ui-icon>
{{ saving ? '保存中...' : (isDirty ? '保存 *' : '保存') }}
</ui-button>
<ui-button class="export-button" @click="exportSettings">
<ui-icon value="download"></ui-icon>
导出
</ui-button>
<ui-button class="import-button" @click="importSettings">
<ui-icon value="upload"></ui-icon>
导入
</ui-button>
<ui-button class="reset-button" @click="resetSettings">
<ui-icon value="reset"></ui-icon>
重置
</ui-button>
</div>
</div>
<!-- 状态栏 -->
<div class="status-bar" v-if="lastSaved">
<span class="status-text">最后保存: {{ lastSaved }}</span>
</div>
<!-- 设置内容 -->
<div class="settings-content">
<!-- 代码生成设置 -->
<div class="settings-section">
<div class="section-header">
<h2>📝 代码生成设置</h2>
<p>配置自动生成代码的格式和选项</p>
</div>
<div class="settings-grid">
<div class="setting-item">
<label>模板语言</label>
<ui-select v-model="settings.codeGeneration.template" @change="markDirty">
<option value="typescript">TypeScript</option>
<option value="javascript">JavaScript</option>
</ui-select>
</div>
<div class="setting-item">
<label>组件后缀</label>
<ui-input v-model="settings.codeGeneration.componentSuffix"
@change="markDirty" placeholder="Component"></ui-input>
</div>
<div class="setting-item">
<label>系统后缀</label>
<ui-input v-model="settings.codeGeneration.systemSuffix"
@change="markDirty" placeholder="System"></ui-input>
</div>
<div class="setting-item">
<label>缩进风格</label>
<ui-select v-model="settings.codeGeneration.indentStyle" @change="markDirty">
<option value="spaces">空格</option>
<option value="tabs">制表符</option>
</ui-select>
</div>
<div class="setting-item">
<label>缩进大小</label>
<ui-num-input v-model="settings.codeGeneration.indentSize"
@change="markDirty" :min="1" :max="8"></ui-num-input>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.codeGeneration.useStrictMode" @change="markDirty">
启用严格模式
</ui-checkbox>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.codeGeneration.generateComments" @change="markDirty">
生成注释
</ui-checkbox>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.codeGeneration.generateImports" @change="markDirty">
自动添加导入语句
</ui-checkbox>
</div>
</div>
</div>
<!-- 性能监控设置 -->
<div class="settings-section">
<div class="section-header">
<h2>⚡ 性能监控设置</h2>
<p>配置性能监控和优化建议</p>
</div>
<div class="settings-grid">
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.performance.enableMonitoring" @change="markDirty">
启用性能监控
</ui-checkbox>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.performance.enableFpsMonitoring" @change="markDirty">
启用FPS监控
</ui-checkbox>
</div>
<div class="setting-item">
<label>目标FPS</label>
<ui-num-input v-model="settings.performance.targetFps"
@change="markDirty" :min="30" :max="120"></ui-num-input>
</div>
<div class="setting-item">
<label>执行时间警告阈值 (ms)</label>
<ui-num-input v-model="settings.performance.warningThreshold"
@change="markDirty" :min="1" :max="100" :step="0.1"></ui-num-input>
</div>
<div class="setting-item">
<label>执行时间严重阈值 (ms)</label>
<ui-num-input v-model="settings.performance.criticalThreshold"
@change="markDirty" :min="1" :max="200" :step="0.1"></ui-num-input>
</div>
<div class="setting-item">
<label>内存警告阈值 (MB)</label>
<ui-num-input v-model="settings.performance.memoryWarningMB"
@change="markDirty" :min="10" :max="1000"></ui-num-input>
</div>
<div class="setting-item">
<label>内存严重阈值 (MB)</label>
<ui-num-input v-model="settings.performance.memoryCriticalMB"
@change="markDirty" :min="50" :max="2000"></ui-num-input>
</div>
<div class="setting-item">
<label>性能采样数量</label>
<ui-num-input v-model="settings.performance.maxRecentSamples"
@change="markDirty" :min="10" :max="300"></ui-num-input>
</div>
</div>
</div>
<!-- 调试设置 -->
<div class="settings-section">
<div class="section-header">
<h2>🐛 调试设置</h2>
<p>配置调试模式和日志选项</p>
</div>
<div class="settings-grid">
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.debugging.enableDebugMode" @change="markDirty">
启用调试模式
</ui-checkbox>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.debugging.showEntityCount" @change="markDirty">
显示实体数量
</ui-checkbox>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.debugging.showSystemExecutionTime" @change="markDirty">
显示系统执行时间
</ui-checkbox>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.debugging.enablePerformanceWarnings" @change="markDirty">
启用性能警告
</ui-checkbox>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.debugging.enableDetailedLogs" @change="markDirty">
启用详细日志
</ui-checkbox>
</div>
<div class="setting-item">
<label>日志级别</label>
<ui-select v-model="settings.debugging.logLevel" @change="markDirty">
<option value="none"></option>
<option value="error">错误</option>
<option value="warn">警告</option>
<option value="info">信息</option>
<option value="debug">调试</option>
</ui-select>
</div>
</div>
</div>
<!-- 编辑器集成设置 -->
<div class="settings-section">
<div class="section-header">
<h2>⚙️ 编辑器集成</h2>
<p>配置与Cocos Creator的集成选项</p>
</div>
<div class="settings-grid">
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.editor.autoRefreshAssets" @change="markDirty">
自动刷新资源
</ui-checkbox>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.editor.showWelcomePanelOnStartup" @change="markDirty">
启动时显示欢迎面板
</ui-checkbox>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.editor.enableAutoUpdates" @change="markDirty">
启用自动更新
</ui-checkbox>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.editor.enableNotifications" @change="markDirty">
启用通知
</ui-checkbox>
</div>
<div class="setting-item">
<label>更新频道</label>
<ui-select v-model="settings.editor.updateChannel" @change="markDirty">
<option value="stable">稳定版</option>
<option value="beta">测试版</option>
<option value="alpha">开发版</option>
</ui-select>
</div>
</div>
</div>
<!-- 项目模板设置 -->
<div class="settings-section">
<div class="section-header">
<h2>📁 项目模板设置</h2>
<p>配置生成项目模板的默认选项</p>
</div>
<div class="settings-grid">
<div class="setting-item">
<label>默认实体名称</label>
<ui-input v-model="settings.template.defaultEntityName"
@change="markDirty" placeholder="GameEntity"></ui-input>
</div>
<div class="setting-item">
<label>默认组件名称</label>
<ui-input v-model="settings.template.defaultComponentName"
@change="markDirty" placeholder="CustomComponent"></ui-input>
</div>
<div class="setting-item">
<label>默认系统名称</label>
<ui-input v-model="settings.template.defaultSystemName"
@change="markDirty" placeholder="CustomSystem"></ui-input>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.template.createExampleFiles" @change="markDirty">
创建示例文件
</ui-checkbox>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.template.includeDocumentation" @change="markDirty">
包含文档
</ui-checkbox>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.template.useFactoryPattern" @change="markDirty">
使用工厂模式
</ui-checkbox>
</div>
</div>
</div>
<!-- 事件系统设置 -->
<div class="settings-section">
<div class="section-header">
<h2>📡 事件系统设置</h2>
<p>配置事件系统的行为和性能</p>
</div>
<div class="settings-grid">
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.events.enableEventSystem" @change="markDirty">
启用事件系统
</ui-checkbox>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.events.enableAsyncEvents" @change="markDirty">
启用异步事件
</ui-checkbox>
</div>
<div class="setting-item checkbox-item">
<ui-checkbox v-model="settings.events.enableEventBatching" @change="markDirty">
启用事件批处理
</ui-checkbox>
</div>
<div class="setting-item">
<label>默认事件优先级</label>
<ui-num-input v-model="settings.events.defaultEventPriority"
@change="markDirty" :min="-100" :max="100"></ui-num-input>
</div>
<div class="setting-item">
<label>批处理大小</label>
<ui-num-input v-model="settings.events.batchSize"
@change="markDirty" :min="1" :max="100"></ui-num-input>
</div>
<div class="setting-item">
<label>批处理延迟 (ms)</label>
<ui-num-input v-model="settings.events.batchDelay"
@change="markDirty" :min="1" :max="1000"></ui-num-input>
</div>
<div class="setting-item">
<label>最大事件监听器数</label>
<ui-num-input v-model="settings.events.maxEventListeners"
@change="markDirty" :min="10" :max="1000"></ui-num-input>
</div>
</div>
</div>
</div>
<!-- 底部提示 -->
<div class="settings-footer">
<div class="footer-info">
<ui-icon value="info"></ui-icon>
<span>设置将保存到项目目录的 .ecs-framework-settings.json 文件中</span>
</div>
<div class="footer-actions">
<span class="dirty-indicator" v-if="isDirty">● 有未保存的更改</span>
</div>
</div>
</div>
</div>

View File

@@ -100,7 +100,7 @@
<p v-else>安装@esengine/ecs-framework到当前项目</p> <p v-else>安装@esengine/ecs-framework到当前项目</p>
</div> </div>
<div class="action-card" :class="{ disabled: !ecsInstalled }" @click="openDocumentation"> <div class="action-card" @click="openDocumentation">
<h3> <h3>
<span class="icon">📚</span> <span class="icon">📚</span>
查看文档 查看文档
@@ -134,36 +134,29 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="action-card" @click="openSettings"> <!-- 代码生成工具区域 -->
<div class="actions-section" v-if="ecsInstalled">
<div class="status-title">🛠️ 代码生成工具</div>
<div class="action-card special" @click="openGenerator">
<h3> <h3>
<span class="icon">⚙️</span> <span class="icon">🚀</span>
插件设置 代码生成器
</h3> </h3>
<p>配置ECS插件的各项设置和偏好</p> <p>一站式代码生成工具,输入功能名称快速生成组件和系统代码</p>
</div> </div>
<div class="action-card" @click="openProjectAnalysis">
<h3>
<span class="icon">📊</span>
项目分析
</h3>
<p>分析当前项目的ECS使用情况和性能建议</p>
</div>
<div class="action-card" @click="openComponentLibrary">
<h3>
<span class="icon">🧩</span>
组件库
</h3>
<p>浏览和管理项目中的ECS组件</p>
</div>
</div> </div>
<!-- 底部信息 --> <!-- 底部信息 -->
<div class="footer"> <div class="footer">
<p>ECS Framework Plugin v{{pluginVersion}} | 基于Vue 3.x构建</p> <p>ECS Framework Plugin v{{pluginVersion}} | 基于Vue 3.x构建</p>
<p>更多信息请访问: <a href="#" @click="openGithub">GitHub Repository</a></p> <p>
更多信息请访问: <a href="#" @click="openGithub">GitHub Repository</a> |
<a href="#" @click="joinQQGroup">💬 加入QQ群交流</a>
</p>
<p v-if="lastCheckTime" class="last-check">最后检查时间: {{lastCheckTime}}</p> <p v-if="lastCheckTime" class="last-check">最后检查时间: {{lastCheckTime}}</p>
</div> </div>
</div> </div>

View File

@@ -10,9 +10,9 @@
} }
}, },
"node_modules/@esengine/ecs-framework": { "node_modules/@esengine/ecs-framework": {
"version": "2.1.19", "version": "2.1.20",
"resolved": "https://registry.npmjs.org/@esengine/ecs-framework/-/ecs-framework-2.1.19.tgz", "resolved": "https://registry.npmjs.org/@esengine/ecs-framework/-/ecs-framework-2.1.20.tgz",
"integrity": "sha512-yS6g1Swdd/FvnIrdmaxBh6ml5r+Oh4edIhGwVfEbzQMHUmrZQbva7/NGyOhTsJ6qsIGVyNin8o46tTud2YCj4g==", "integrity": "sha512-L6PJ1uoXIttzjYt66shZPdmJ4lU38SyqRnEcVJexcR+V6iyQ/U7H8yjvQjeTIlBb0u7JDBEC6a8B4Cr6VlsF9Q==",
"engines": { "engines": {
"node": ">=16.0.0" "node": ">=16.0.0"
} }

View File

@@ -1,2 +1,2 @@
export { ComponentPool } from '../ComponentPool'; export { ComponentPool, ComponentPoolManager } from '../ComponentPool';
export { ComponentStorage } from '../ComponentStorage'; export { ComponentStorage } from '../ComponentStorage';