From b5f4db4a7c50f60e392cd790c7fbe5163412ec0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Thu, 11 Jul 2024 21:23:18 +0800 Subject: [PATCH] =?UTF-8?q?=E7=89=A9=E7=BC=96=E4=BF=AE=E6=94=B9=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.json | 3 +- src/editorTable/editor.ts | 36 +++++++++------- src/editorTable/editorTable.ts | 35 ++++++++++++--- src/y3-helper.ts | 26 +++++++++++- template/object/1.js | 31 ++++++++++++++ template/object/y3-helper.d.ts | 78 ++++++++++++++++++++++++++++++---- 6 files changed, 176 insertions(+), 33 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 1fd36a6..a92601c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -26,6 +26,7 @@ "out", "dist", "3rd", - "**/*.d.ts" + "**/*.d.ts", + "template" ] } diff --git a/src/editorTable/editor.ts b/src/editorTable/editor.ts index 822ef60..641ff17 100644 --- a/src/editorTable/editor.ts +++ b/src/editorTable/editor.ts @@ -21,20 +21,20 @@ function makeSandbox() { }; } -export async function runEditor(uri: vscode.Uri) { +export async function runEditor(uri: vscode.Uri, funcName: string = 'main') { y3.log.show(); try { const file = await y3.fs.readFile(uri); let content = file!.string; - content = content + '\n\nmodule.exports = main'; + content = content + `\n\nmodule.exports = ${funcName}`; let script = new vm.Script(content, { filename: uri.path, }); - let main = script.runInNewContext(vm.createContext(makeSandbox())); - if (typeof main !== 'function') { - throw new Error('没有导出 main 函数'); + let func = script.runInNewContext(vm.createContext(makeSandbox())); + if (typeof func !== 'function') { + throw new Error('没有找到要执行的函数'); } - await main(); + await func(); y3.log.info(`执行 "${uri.path.split('/').pop()}" 成功!`); } catch (error) { vscode.window.showErrorMessage(`运行物编脚本出错:${error}`); @@ -43,13 +43,19 @@ export async function runEditor(uri: vscode.Uri) { class RunButtonProvider implements vscode.CodeLensProvider { public provideCodeLenses(document: vscode.TextDocument): vscode.CodeLens[] | undefined { - return [ - new vscode.CodeLens(new vscode.Range(0, 0, 0, 0), { - title: '$(debug-start)运行', - command: 'y3-helper.runObjectEditor', - arguments: [document.uri], - }), - ]; + let codeLens: vscode.CodeLens[] = []; + for (let i = 0; i < document.lineCount; i++) { + const line = document.lineAt(i); + const name = line.text.match(/^async\s+function\s+([\w_]+)/)?.[1]; + if (name) { + codeLens.push(new vscode.CodeLens(new vscode.Range(i, 0, i, 0), { + title: `$(debug-start)运行 ${name} 函数`, + command: 'y3-helper.runObjectEditor', + arguments: [document.uri, name], + })); + } + } + return codeLens; } } @@ -79,14 +85,14 @@ export function init() { } }); - vscode.commands.registerCommand('y3-helper.runObjectEditor', async (uri?: vscode.Uri) => { + vscode.commands.registerCommand('y3-helper.runObjectEditor', async (uri?: vscode.Uri, funcName?: string) => { if (!uri) { uri = vscode.window.activeTextEditor?.document.uri; if (!uri) { return; } } - await runEditor(uri); + await runEditor(uri, funcName); }); vscode.languages.registerCodeLensProvider({ diff --git a/src/editorTable/editorTable.ts b/src/editorTable/editorTable.ts index 0581f5a..91a9a9b 100644 --- a/src/editorTable/editorTable.ts +++ b/src/editorTable/editorTable.ts @@ -84,12 +84,15 @@ export class EditorObject { private _name?: string; public text?: string; public uri?: vscode.Uri; - constructor(public tableName: Table.NameCN, public key: number) {} + constructor(public tableName: N, public key: number) {} toString() { return `{物编对象|${this.name}|${this.tableName}-${this.key}}`; } + /** + * 获取对象的json数据语法树 + */ public get json(): y3.json.Json | undefined { if (this._json === undefined) { if (!this.text) { @@ -100,6 +103,9 @@ export class EditorObject { return this._json; } + /** + * 获取对象的物编数据 + */ private _data?: EditorData; public get data(): EditorData { if (this._data === undefined) { @@ -227,6 +233,9 @@ export class EditorObject { return res; } + /** + * 获取对象的名称 + */ public get name(): string { if (!this._name) { let name = this.text?.match(/"name"\s*:\s*(\-?\d*)/); @@ -313,7 +322,7 @@ export class EditorObject { } } -async function loadObject(tableName: Table.NameCN, key: number) { +async function loadObject(tableName: N, key: number) { let table = openTable(tableName); let uri = table.getUri(key); let file = await y3.fs.readFile(uri); @@ -377,7 +386,7 @@ export class EditorTable extends vscode.Disposable { */ public async get(key: number): Promise | undefined> { if (this._objectCache[key] === undefined) { - this._objectCache[key] = await loadObject(this.name, key); + this._objectCache[key] = await loadObject(this.name, key); } return this._objectCache[key] ?? undefined; } @@ -454,10 +463,18 @@ export class EditorTable extends vscode.Disposable { * 生成一个可用的新key * @returns */ - public async makeNewKey() { + public async makeNewKey(copyKey?: number) { let list = await this.getList(); - let max = list[list.length - 1]; - return max ? max + 1 : 100001; + if (copyKey) { + let i = copyKey + 1; + while (list.includes(i)) { + i++; + } + return i; + } else { + let max = list[list.length - 1]; + return max ? max + 1 : 100001; + } } /** @@ -467,6 +484,7 @@ export class EditorTable extends vscode.Disposable { */ public async create(options?: CreateOptions): Promise | undefined>{ let name = options?.name ?? `新建${this.name}`; + let key: number; if (options?.key) { key = options.key; @@ -474,7 +492,10 @@ export class EditorTable extends vscode.Disposable { return undefined; } } else { - key = await this.makeNewKey(); + let copyKey = options?.copyFrom instanceof EditorObject + ? options.copyFrom.key + : options?.copyFrom; + key = await this.makeNewKey(copyKey); } let templateJson: string; diff --git a/src/y3-helper.ts b/src/y3-helper.ts index 7dfa51f..21a7240 100644 --- a/src/y3-helper.ts +++ b/src/y3-helper.ts @@ -1,5 +1,5 @@ import * as vscode from 'vscode'; -import { fs } from './tools'; +import { fs, log } from './tools'; export * as excel from './editorTable/EXCEL'; export * as table from './editorTable/editorTable'; @@ -9,6 +9,10 @@ export * as const from './constants'; export { env } from './env'; export let helper: vscode.ExtensionContext; +/** + * 拼接路径为 Uri + * @returns + */ export function uri(base: vscode.Uri | string, ...paths: string[]): vscode.Uri { if (typeof base === 'string') { if (fs.isAbsolutePath(base)) { @@ -20,6 +24,10 @@ export function uri(base: vscode.Uri | string, ...paths: string[]): vscode.Uri { return vscode.Uri.joinPath(base, ...paths); } +/** + * 获取《Y3开发助手》插件的相对路径 + * @returns + */ export function extensionPath(...paths: string[]): vscode.Uri { return vscode.Uri.joinPath(helper.extensionUri, ...paths); } @@ -28,6 +36,22 @@ export function setContext(ctx: vscode.ExtensionContext) { helper = ctx; } +/** + * 打印内容,也会打印到日志窗口中 + * @param args 要打印的内容 + */ export function print(...args: any[]) { vscode.window.showInformationMessage(args.join(' ')); + log.info(args.join(' ')); +} + +/** + * 在VSCode中打开文件 + * @param uri 文件路径 + */ +export function open(uri: vscode.Uri | string) { + if (typeof uri === 'string') { + uri = vscode.Uri.parse(uri); + } + vscode.commands.executeCommand('vscode.open', uri); } diff --git a/template/object/1.js b/template/object/1.js index e69de29..dd0bc4a 100644 --- a/template/object/1.js +++ b/template/object/1.js @@ -0,0 +1,31 @@ +let y3 = require('y3-helper') + +// 定义一个函数,然后点击运行函数按钮即可执行 +async function example() { + //1. 先来创建一个新的单位 + let unitTable = y3.table.openTable('单位') // 打开单位表 + + // 创建单位需要一些时间(往硬盘写入文件),因此需要加上 await + let unit1 = await unitTable.create({ + name: '演示单位1', // 起个名字 + key: 11037, // 这个单位的key,如果不填,会自动生成一个可用的key + overwrite: true, // 如果指定了key,是否允许覆盖已有的单位;否则可能会创建失败 + }) + + y3.print('演示单位1创建完成', unit1) + + //2. 复制一个已有的单位 + let unit2 = await unitTable.create({ + copyFrom: unit1, // 要复制的单位,也可以用数字key + name: '演示单位2', + key: 11038, + overwrite: true, + }) + + y3.print('演示单位2创建完成', unit2) + + //3. 修改单位的数据 + unit2.data.ori_speed = 5 // 修改移动速度 + + y3.print('移动速度修改完成') +} diff --git a/template/object/y3-helper.d.ts b/template/object/y3-helper.d.ts index 7c4e07b..5821606 100644 --- a/template/object/y3-helper.d.ts +++ b/template/object/y3-helper.d.ts @@ -50,18 +50,25 @@ declare module 'y3-helper/editorTable/editorTable' { } type EditorData = N extends '单位' ? UnitData : N extends '声音' ? SoundData : N extends '技能' ? AbilityData : N extends '装饰物' ? DecorationData : N extends '可破坏物' ? DestructibleData : N extends '物品' ? ItemData : N extends '魔法效果' ? ModifierData : N extends '投射物' ? ProjectileData : N extends '科技' ? TechData : never; export class EditorObject { - tableName: Table.NameCN; + tableName: N; key: number; text?: string; uri?: vscode.Uri; - constructor(tableName: Table.NameCN, key: number); + constructor(tableName: N, key: number); + toString(): string; + /** + * 获取对象的json数据语法树 + */ get json(): y3.json.Json | undefined; get data(): EditorData; + /** + * 获取对象的名称 + */ get name(): string; getFieldInfo(field: string): y3.table.FieldInfo | undefined; listFields(): string[]; } - interface CreateOptions { + interface CreateOptions { /** * 新对象的名称,如果不填则使用默认名称 */ @@ -73,14 +80,14 @@ declare module 'y3-helper/editorTable/editorTable' { /** * 从哪个对象复制,如果不填则从模板复制为空对象 */ - copyFrom?: number; + copyFrom?: number | EditorObject; /** * 如果目标key已存在,是否覆盖 */ overwrite?: boolean; } export class EditorTable extends vscode.Disposable { - nameCN: N; + name: N; uri: vscode.Uri; nameEN: { readonly 单位: "unit"; @@ -93,23 +100,76 @@ declare module 'y3-helper/editorTable/editorTable' { readonly 可破坏物: "destructible"; readonly 声音: "sound"; }[N]; - constructor(nameCN: N); + constructor(name: N); + toString(): string; + /** + * 获取具体的对象 + * @param key 对象的key(一串数字) + * @returns 对象 + */ get(key: number): Promise | undefined>; fetch(key: number): EditorObject | undefined; + /** + * 获取这个类型下的所有对象的key + * @returns 这个类型下的所有对象的key + */ getList(): Promise; fetchList(): number[] | undefined; + /** + * 删除一个对象 + * @param key 对象的key + */ delete(key: number): Promise; + /** + * 检查一个key是否可以使用 + * @param key 要检查的key + * @param overwirte 是否允许覆盖已有的key,默认不允许 + * @returns + */ canUseKey(key: number, overwirte?: boolean): Promise; - makeNewKey(): Promise; - create(options?: CreateOptions): Promise | undefined>; + /** + * 生成一个可用的新key + * @returns + */ + makeNewKey(copyKey?: number): Promise; + /** + * 创建一个对象 + * @param options 创建的参数 + * @returns + */ + create(options?: CreateOptions): Promise | undefined>; + /** + * 获取对象在硬盘中的文件路径 + * @param key 对象的key + * @returns 对象的路径 + */ getUri(key: number): vscode.Uri; getFieldInfo(field: string): FieldInfo | undefined; listFields(): string[]; onDidChange(callback: () => void): vscode.Disposable; } + /** + * 打开物编表 + * @param tableName 哪种表 + * @returns 表对象 + */ export function openTable(tableName: N): EditorTable; + /** + * 根据文件名获取文件对应的key + * @param fileName 文件名 + * @returns 文件名对应的key + */ export function getFileKey(fileName: string): number | undefined; - export function getObject(uri: vscode.Uri): Promise | undefined>; + /** + * 根据文件路径获取对象 + * @param uri 文件路径 + * @returns 对象 + */ + export function getObject(uri: vscode.Uri | string): Promise | undefined>; + /** + * 获取所有的对象(速度比较慢) + * @returns 所有对象 + */ export function getAllObjects(): Promise[]>; export function init(): void; export {};