Merge pull request #1 from dhb118/master

export all trees to single json file support
This commit is contained in:
战斗鸡 authored and GitHub committed 2020-11-12 17:02:35 +08:00
commit c3ea18e307
3 files changed
+158 -90

No files matched your search

+7
View File
@@ -0,0 +1,7 @@
{
"endOfLine": "lf",
"semi": true,
"tabWidth": 4,
"printWidth": 100,
"trailingComma": "es5"
}
+110 -80
View File
@@ -1,9 +1,17 @@
import { Menu, app, dialog, BrowserWindow, MenuItem, WebContents, MenuItemConstructorOptions } from 'electron'; import {
import * as fs from 'fs'; Menu,
import * as Utils from '../common/Utils'; app,
import MainEventType from '../common/MainEventType'; dialog,
import { MainProcess } from './MainProcess'; BrowserWindow,
import Settings from './Settings'; MenuItem,
WebContents,
MenuItemConstructorOptions,
} from "electron";
import * as fs from "fs";
import * as Utils from "../common/Utils";
import MainEventType from "../common/MainEventType";
import { MainProcess } from "./MainProcess";
import Settings from "./Settings";
export default class AppMenu { export default class AppMenu {
private mainProcess: MainProcess; private mainProcess: MainProcess;
@@ -34,28 +42,28 @@ export default class AppMenu {
label: path, label: path,
click: () => { click: () => {
console.log("open recent file", path); console.log("open recent file", path);
},
});
} }
})
}
return new MenuItem({ return new MenuItem({
label: "行为树", label: "行为树",
submenu: [ submenu: [
{ {
label: "新建", label: "新建",
accelerator: 'ctrl+n', accelerator: "ctrl+n",
click: () => { click: () => {
(async () => { (async () => {
const res = await dialog.showSaveDialog({ const res = await dialog.showSaveDialog({
properties: ['showOverwriteConfirmation'], properties: ["showOverwriteConfirmation"],
filters: [ filters: [{ name: "Json", extensions: ["json"] }],
{ name: "Json", extensions: ['json'] }
]
}); });
if (!res.canceled) { if (!res.canceled) {
const path = res.filePath; const path = res.filePath;
fs.writeFileSync(path, JSON.stringify(Utils.createNewTree(path), null, 2)); fs.writeFileSync(
path,
JSON.stringify(Utils.createNewTree(path), null, 2)
);
this.webContents.send(MainEventType.CREATE_TREE, path); this.webContents.send(MainEventType.CREATE_TREE, path);
} }
})(); })();
@@ -67,10 +75,8 @@ export default class AppMenu {
click: () => { click: () => {
(async () => { (async () => {
const res = await dialog.showOpenDialog({ const res = await dialog.showOpenDialog({
properties: ['openFile'], properties: ["openFile"],
filters: [ filters: [{ name: "Json", extensions: ["json"] }],
{ name: "Json", extensions: ['json'] }
]
}); });
if (res.filePaths.length > 0) { if (res.filePaths.length > 0) {
const path = res.filePaths[0]; const path = res.filePaths[0];
@@ -82,61 +88,83 @@ export default class AppMenu {
this.webContents.send(MainEventType.OPEN_FILE, path); this.webContents.send(MainEventType.OPEN_FILE, path);
} }
})(); })();
}
}, },
{ type: 'separator' }, },
{ type: "separator" },
{ {
label: "最近打开", label: "最近打开",
submenu: fileItems, submenu: fileItems,
}, },
{ type: 'separator' }, { type: "separator" },
{ {
label: "保存", label: "保存",
accelerator: 'ctrl+s', accelerator: "ctrl+s",
click: () => { click: () => {
this.webContents.send(MainEventType.SAVE); this.webContents.send(MainEventType.SAVE);
}, },
}, },
{ {
label: "全部保存", label: "全部保存",
accelerator: 'ctrl+shift+s', accelerator: "ctrl+shift+s",
click: () => { click: () => {
this.webContents.send(MainEventType.SAVE_ALL); this.webContents.send(MainEventType.SAVE_ALL);
}, },
}, },
{ type: 'separator' },
{ {
label: '新建节点', label: "合并导出Json",
accelerator: 'insert',
click: () => { click: () => {
this.webContents.send(MainEventType.CREATE_NODE, 'unknow'); (async () => {
const res = await dialog.showSaveDialog({
properties: ["showOverwriteConfirmation"],
filters: [{ name: "Json", extensions: ["json"] }],
});
if (res.filePath) {
const curWorkspace = this.settings.curWorkspace;
curWorkspace.writeAllTrees(res.filePath,(err)=>{
const msg = err?err:"导出成功";
dialog.showMessageBox({
type:"info",
buttons:["ok"],
message:msg
})
});
} }
})();
},
},
{ type: "separator" },
{
label: "新建节点",
accelerator: "insert",
click: () => {
this.webContents.send(MainEventType.CREATE_NODE, "unknow");
},
}, },
{ {
label: '删除节点', label: "删除节点",
accelerator: 'delete', accelerator: "delete",
click: () => { click: () => {
this.webContents.send(MainEventType.DELETE_NODE); this.webContents.send(MainEventType.DELETE_NODE);
}
}, },
{ type: 'separator' }, },
{ type: "separator" },
{ {
label: '复制节点', label: "复制节点",
accelerator: 'ctrl+c', accelerator: "ctrl+c",
role: 'copy', role: "copy",
click: () => { click: () => {
this.webContents.send(MainEventType.COPY_NODE); this.webContents.send(MainEventType.COPY_NODE);
} },
}, },
{ {
label: '粘贴节点', label: "粘贴节点",
accelerator: 'ctrl+v', accelerator: "ctrl+v",
click: () => { click: () => {
this.webContents.send(MainEventType.PASTE_NODE); this.webContents.send(MainEventType.PASTE_NODE);
} },
} },
] ],
}); });
} }
@@ -147,15 +175,17 @@ export default class AppMenu {
curWorkspace.load(); curWorkspace.load();
this.settings.pushRecentWorkspace(path); this.settings.pushRecentWorkspace(path);
this.mainProcess.rebuildMenu(); this.mainProcess.rebuildMenu();
this.webContents.send(MainEventType.OPEN_DIR, curWorkspace.getWorkdir(), curWorkspace.getFilepath()); this.webContents.send(
MainEventType.OPEN_DIR,
curWorkspace.getWorkdir(),
curWorkspace.getFilepath()
);
}; };
const saveToNewPath = () => { const saveToNewPath = () => {
(async () => { (async () => {
const res = await dialog.showSaveDialog({ const res = await dialog.showSaveDialog({
properties: ['showOverwriteConfirmation'], properties: ["showOverwriteConfirmation"],
filters: [ filters: [{ name: "Json", extensions: ["json"] }],
{ name: "Json", extensions: ['json'] }
]
}); });
if (!res.canceled) { if (!res.canceled) {
this.settings.curWorkspace.setFilepath(res.filePath); this.settings.curWorkspace.setFilepath(res.filePath);
@@ -163,7 +193,7 @@ export default class AppMenu {
openWorkspace(res.filePath); openWorkspace(res.filePath);
} }
})(); })();
} };
const recentItems: MenuItemConstructorOptions[] = []; const recentItems: MenuItemConstructorOptions[] = [];
for (let path of this.settings.recentWorkspaces) { for (let path of this.settings.recentWorkspaces) {
recentItems.push({ recentItems.push({
@@ -171,8 +201,8 @@ export default class AppMenu {
click: () => { click: () => {
console.log("open recent workspace", path); console.log("open recent workspace", path);
openWorkspace(path); openWorkspace(path);
} },
}) });
} }
return new MenuItem({ return new MenuItem({
label: "工作区", label: "工作区",
@@ -182,16 +212,14 @@ export default class AppMenu {
click: () => { click: () => {
(async () => { (async () => {
const res = await dialog.showOpenDialog({ const res = await dialog.showOpenDialog({
properties: ['openFile'], properties: ["openFile"],
filters: [ filters: [{ name: "Json", extensions: ["json"] }],
{ name: "Json", extensions: ['json'] }
]
}); });
if (res.filePaths.length > 0) { if (res.filePaths.length > 0) {
openWorkspace(res.filePaths[0]); openWorkspace(res.filePaths[0]);
} }
})(); })();
} },
}, },
{ {
label: "保存", label: "保存",
@@ -201,10 +229,10 @@ export default class AppMenu {
} else { } else {
saveToNewPath(); saveToNewPath();
} }
} },
}, },
{ {
label: '另存为', label: "另存为",
click: () => { click: () => {
saveToNewPath(); saveToNewPath();
}, },
@@ -213,7 +241,7 @@ export default class AppMenu {
label: "最近打开", label: "最近打开",
submenu: recentItems, submenu: recentItems,
}, },
{ type: 'separator' }, { type: "separator" },
{ {
label: "打开目录", label: "打开目录",
accelerator: "Ctrl+Shift+O", accelerator: "Ctrl+Shift+O",
@@ -224,17 +252,21 @@ export default class AppMenu {
} }
(async () => { (async () => {
const res = await dialog.showOpenDialog({ const res = await dialog.showOpenDialog({
properties: ['openDirectory'] properties: ["openDirectory"],
}); });
if (res.filePaths.length > 0) { if (res.filePaths.length > 0) {
const curWorkspace = this.settings.curWorkspace; const curWorkspace = this.settings.curWorkspace;
const path = res.filePaths[0]; const path = res.filePaths[0];
curWorkspace.setWorkdir(path); curWorkspace.setWorkdir(path);
curWorkspace.save(); curWorkspace.save();
this.webContents.send(MainEventType.OPEN_DIR, path, curWorkspace.getFilepath()); this.webContents.send(
MainEventType.OPEN_DIR,
path,
curWorkspace.getFilepath()
);
} }
})(); })();
} },
}, },
{ {
label: "节点定义", label: "节点定义",
@@ -244,10 +276,8 @@ export default class AppMenu {
click: () => { click: () => {
(async () => { (async () => {
const res = await dialog.showOpenDialog({ const res = await dialog.showOpenDialog({
properties: ['openFile'], properties: ["openFile"],
filters: [ filters: [{ name: "Json", extensions: ["json"] }],
{ name: "Json", extensions: ['json'] }
]
}); });
if (res.filePaths.length > 0) { if (res.filePaths.length > 0) {
const nodeConfigPath = res.filePaths[0]; const nodeConfigPath = res.filePaths[0];
@@ -255,20 +285,20 @@ export default class AppMenu {
this.mainProcess.rebuildMenu(); this.mainProcess.rebuildMenu();
} }
})(); })();
}
}, },
{ type: 'separator' },
{ label: this.settings.nodeConfPath, }
]
}, },
{ type: 'separator' }, { type: "separator" },
{ label: this.settings.nodeConfPath },
],
},
{ type: "separator" },
{ {
label: "关闭", label: "关闭",
click: () => { click: () => {
app.quit(); app.quit();
} },
} },
] ],
}); });
} }
@@ -281,22 +311,22 @@ export default class AppMenu {
accelerator: "Ctrl+Shift+I", accelerator: "Ctrl+Shift+I",
click: (_, browserWindow) => { click: (_, browserWindow) => {
browserWindow.webContents.toggleDevTools(); browserWindow.webContents.toggleDevTools();
} },
}, },
{ {
label: "重载", label: "重载",
accelerator: "Ctrl+R", accelerator: "Ctrl+R",
click: (_, browserWindow) => { click: (_, browserWindow) => {
browserWindow.reload(); browserWindow.reload();
}
}, },
] },
],
}); });
} }
private createNodeMenu() { private createNodeMenu() {
const classifyItems: MenuItemConstructorOptions[] = []; const classifyItems: MenuItemConstructorOptions[] = [];
const map: { [key: string]: MenuItemConstructorOptions } = {} const map: { [key: string]: MenuItemConstructorOptions } = {};
for (let t of this.settings.nodeClassify) { for (let t of this.settings.nodeClassify) {
let item: MenuItemConstructorOptions = { let item: MenuItemConstructorOptions = {
id: t.classify, id: t.classify,
@@ -307,7 +337,7 @@ export default class AppMenu {
map[t.classify] = item; map[t.classify] = item;
} }
const other: MenuItemConstructorOptions = { const other: MenuItemConstructorOptions = {
id: 'other', id: "other",
label: "其它", label: "其它",
submenu: [], submenu: [],
}; };
@@ -319,8 +349,8 @@ export default class AppMenu {
click: () => { click: () => {
console.log("create node", node.name); console.log("create node", node.name);
this.webContents.send(MainEventType.CREATE_NODE, node.name); this.webContents.send(MainEventType.CREATE_NODE, node.name);
} },
} };
let typeItem = map[node.type]; let typeItem = map[node.type];
if (!typeItem) { if (!typeItem) {
typeItem = other; typeItem = other;
@@ -339,7 +369,7 @@ export default class AppMenu {
return new MenuItem({ return new MenuItem({
label: "新建节点", label: "新建节点",
submenu: classifyItems submenu: classifyItems,
}); });
} }
} }
+41 -10
View File
@@ -1,6 +1,7 @@
import * as fs from 'fs'; import * as fs from "fs";
import * as path from 'path'; import { BehaviorNodeTypeModel } from "../common/BehaviorTreeModel";
import { BehaviorNodeTypeModel } from '../common/BehaviorTreeModel'; import * as glob from "glob";
import * as path from "path";
export interface WorkspaceModel { export interface WorkspaceModel {
isRelative?: boolean; isRelative?: boolean;
@@ -9,10 +10,10 @@ export interface WorkspaceModel {
} }
const unknowNodeType: BehaviorNodeTypeModel = { const unknowNodeType: BehaviorNodeTypeModel = {
name: 'unknow', name: "unknow",
desc: '新建节点', desc: "新建节点",
type: 'Action', type: "Action",
} };
export default class Workspace { export default class Workspace {
private filepath: string; private filepath: string;
@@ -68,13 +69,36 @@ export default class Workspace {
this.nodeConfPath = path; this.nodeConfPath = path;
this.initNodeConf(); this.initNodeConf();
} }
getWorkdir() { getWorkdir(): string {
return this.workdir; return this.workdir;
} }
setWorkdir(workdir: string) { setWorkdir(workdir: string) {
this.workdir = workdir; this.workdir = workdir;
} }
writeAllTrees(outFilePath: string, cb?: (err: string) => void) {
if (!fs.existsSync(this.getWorkdir())) {
cb && cb("请先打开工作区");
return;
}
glob.glob(path.join(this.getWorkdir(), "**/*.json"), function (err, files) {
if (err) {
console.error(err);
cb && cb(err.message);
return;
}
let result = new Array();
files.forEach((file) => {
const data = fs.readFileSync(file, "utf8");
result.push(JSON.parse(data));
});
fs.writeFileSync(outFilePath, JSON.stringify(result, null, 2));
cb && cb(null);
});
}
save(filepath?: string) { save(filepath?: string) {
if (filepath) { if (filepath) {
this.filepath = filepath; this.filepath = filepath;
@@ -82,10 +106,17 @@ export default class Workspace {
if (!this.filepath) { if (!this.filepath) {
return; return;
} }
fs.writeFileSync(this.filepath, JSON.stringify({ fs.writeFileSync(
this.filepath,
JSON.stringify(
{
nodeConfPath: this.nodeConfPath, nodeConfPath: this.nodeConfPath,
workdir: this.workdir, workdir: this.workdir,
}, null, 2)) },
null,
2
)
);
} }
get nodeConf() { get nodeConf() {