Merge pull request #1 from dhb118/master
export all trees to single json file support
This commit is contained in:
3 files changed
+158
-90
No files matched your search
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"endOfLine": "lf",
|
||||
"semi": true,
|
||||
"tabWidth": 4,
|
||||
"printWidth": 100,
|
||||
"trailingComma": "es5"
|
||||
}
|
||||
+110
-80
@@ -1,9 +1,17 @@
|
||||
import { Menu, app, dialog, BrowserWindow, 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';
|
||||
import {
|
||||
Menu,
|
||||
app,
|
||||
dialog,
|
||||
BrowserWindow,
|
||||
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 {
|
||||
private mainProcess: MainProcess;
|
||||
@@ -34,28 +42,28 @@ export default class AppMenu {
|
||||
label: path,
|
||||
click: () => {
|
||||
console.log("open recent file", path);
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
return new MenuItem({
|
||||
label: "行为树",
|
||||
submenu: [
|
||||
{
|
||||
label: "新建",
|
||||
accelerator: 'ctrl+n',
|
||||
accelerator: "ctrl+n",
|
||||
click: () => {
|
||||
(async () => {
|
||||
const res = await dialog.showSaveDialog({
|
||||
properties: ['showOverwriteConfirmation'],
|
||||
filters: [
|
||||
{ name: "Json", extensions: ['json'] }
|
||||
]
|
||||
properties: ["showOverwriteConfirmation"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (!res.canceled) {
|
||||
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);
|
||||
}
|
||||
})();
|
||||
@@ -67,10 +75,8 @@ export default class AppMenu {
|
||||
click: () => {
|
||||
(async () => {
|
||||
const res = await dialog.showOpenDialog({
|
||||
properties: ['openFile'],
|
||||
filters: [
|
||||
{ name: "Json", extensions: ['json'] }
|
||||
]
|
||||
properties: ["openFile"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (res.filePaths.length > 0) {
|
||||
const path = res.filePaths[0];
|
||||
@@ -82,61 +88,83 @@ export default class AppMenu {
|
||||
this.webContents.send(MainEventType.OPEN_FILE, path);
|
||||
}
|
||||
})();
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "最近打开",
|
||||
submenu: fileItems,
|
||||
},
|
||||
|
||||
{ type: 'separator' },
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "保存",
|
||||
accelerator: 'ctrl+s',
|
||||
accelerator: "ctrl+s",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.SAVE);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "全部保存",
|
||||
accelerator: 'ctrl+shift+s',
|
||||
accelerator: "ctrl+shift+s",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.SAVE_ALL);
|
||||
},
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: '新建节点',
|
||||
accelerator: 'insert',
|
||||
label: "合并导出Json",
|
||||
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: '删除节点',
|
||||
accelerator: 'delete',
|
||||
label: "删除节点",
|
||||
accelerator: "delete",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.DELETE_NODE);
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: '复制节点',
|
||||
accelerator: 'ctrl+c',
|
||||
role: 'copy',
|
||||
label: "复制节点",
|
||||
accelerator: "ctrl+c",
|
||||
role: "copy",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.COPY_NODE);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '粘贴节点',
|
||||
accelerator: 'ctrl+v',
|
||||
label: "粘贴节点",
|
||||
accelerator: "ctrl+v",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.PASTE_NODE);
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -147,15 +175,17 @@ export default class AppMenu {
|
||||
curWorkspace.load();
|
||||
this.settings.pushRecentWorkspace(path);
|
||||
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 = () => {
|
||||
(async () => {
|
||||
const res = await dialog.showSaveDialog({
|
||||
properties: ['showOverwriteConfirmation'],
|
||||
filters: [
|
||||
{ name: "Json", extensions: ['json'] }
|
||||
]
|
||||
properties: ["showOverwriteConfirmation"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (!res.canceled) {
|
||||
this.settings.curWorkspace.setFilepath(res.filePath);
|
||||
@@ -163,7 +193,7 @@ export default class AppMenu {
|
||||
openWorkspace(res.filePath);
|
||||
}
|
||||
})();
|
||||
}
|
||||
};
|
||||
const recentItems: MenuItemConstructorOptions[] = [];
|
||||
for (let path of this.settings.recentWorkspaces) {
|
||||
recentItems.push({
|
||||
@@ -171,8 +201,8 @@ export default class AppMenu {
|
||||
click: () => {
|
||||
console.log("open recent workspace", path);
|
||||
openWorkspace(path);
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
}
|
||||
return new MenuItem({
|
||||
label: "工作区",
|
||||
@@ -182,16 +212,14 @@ export default class AppMenu {
|
||||
click: () => {
|
||||
(async () => {
|
||||
const res = await dialog.showOpenDialog({
|
||||
properties: ['openFile'],
|
||||
filters: [
|
||||
{ name: "Json", extensions: ['json'] }
|
||||
]
|
||||
properties: ["openFile"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (res.filePaths.length > 0) {
|
||||
openWorkspace(res.filePaths[0]);
|
||||
}
|
||||
})();
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "保存",
|
||||
@@ -201,10 +229,10 @@ export default class AppMenu {
|
||||
} else {
|
||||
saveToNewPath();
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '另存为',
|
||||
label: "另存为",
|
||||
click: () => {
|
||||
saveToNewPath();
|
||||
},
|
||||
@@ -213,7 +241,7 @@ export default class AppMenu {
|
||||
label: "最近打开",
|
||||
submenu: recentItems,
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "打开目录",
|
||||
accelerator: "Ctrl+Shift+O",
|
||||
@@ -224,17 +252,21 @@ export default class AppMenu {
|
||||
}
|
||||
(async () => {
|
||||
const res = await dialog.showOpenDialog({
|
||||
properties: ['openDirectory']
|
||||
properties: ["openDirectory"],
|
||||
});
|
||||
if (res.filePaths.length > 0) {
|
||||
const curWorkspace = this.settings.curWorkspace;
|
||||
const path = res.filePaths[0];
|
||||
curWorkspace.setWorkdir(path);
|
||||
curWorkspace.save();
|
||||
this.webContents.send(MainEventType.OPEN_DIR, path, curWorkspace.getFilepath());
|
||||
this.webContents.send(
|
||||
MainEventType.OPEN_DIR,
|
||||
path,
|
||||
curWorkspace.getFilepath()
|
||||
);
|
||||
}
|
||||
})();
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "节点定义",
|
||||
@@ -244,10 +276,8 @@ export default class AppMenu {
|
||||
click: () => {
|
||||
(async () => {
|
||||
const res = await dialog.showOpenDialog({
|
||||
properties: ['openFile'],
|
||||
filters: [
|
||||
{ name: "Json", extensions: ['json'] }
|
||||
]
|
||||
properties: ["openFile"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (res.filePaths.length > 0) {
|
||||
const nodeConfigPath = res.filePaths[0];
|
||||
@@ -255,20 +285,20 @@ export default class AppMenu {
|
||||
this.mainProcess.rebuildMenu();
|
||||
}
|
||||
})();
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ label: this.settings.nodeConfPath, }
|
||||
]
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ type: "separator" },
|
||||
{ label: this.settings.nodeConfPath },
|
||||
],
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "关闭",
|
||||
click: () => {
|
||||
app.quit();
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -281,22 +311,22 @@ export default class AppMenu {
|
||||
accelerator: "Ctrl+Shift+I",
|
||||
click: (_, browserWindow) => {
|
||||
browserWindow.webContents.toggleDevTools();
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "重载",
|
||||
accelerator: "Ctrl+R",
|
||||
click: (_, browserWindow) => {
|
||||
browserWindow.reload();
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
private createNodeMenu() {
|
||||
const classifyItems: MenuItemConstructorOptions[] = [];
|
||||
const map: { [key: string]: MenuItemConstructorOptions } = {}
|
||||
const map: { [key: string]: MenuItemConstructorOptions } = {};
|
||||
for (let t of this.settings.nodeClassify) {
|
||||
let item: MenuItemConstructorOptions = {
|
||||
id: t.classify,
|
||||
@@ -307,7 +337,7 @@ export default class AppMenu {
|
||||
map[t.classify] = item;
|
||||
}
|
||||
const other: MenuItemConstructorOptions = {
|
||||
id: 'other',
|
||||
id: "other",
|
||||
label: "其它",
|
||||
submenu: [],
|
||||
};
|
||||
@@ -319,8 +349,8 @@ export default class AppMenu {
|
||||
click: () => {
|
||||
console.log("create node", node.name);
|
||||
this.webContents.send(MainEventType.CREATE_NODE, node.name);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
let typeItem = map[node.type];
|
||||
if (!typeItem) {
|
||||
typeItem = other;
|
||||
@@ -339,7 +369,7 @@ export default class AppMenu {
|
||||
|
||||
return new MenuItem({
|
||||
label: "新建节点",
|
||||
submenu: classifyItems
|
||||
submenu: classifyItems,
|
||||
});
|
||||
}
|
||||
}
|
||||
+41
-10
@@ -1,6 +1,7 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { BehaviorNodeTypeModel } from '../common/BehaviorTreeModel';
|
||||
import * as fs from "fs";
|
||||
import { BehaviorNodeTypeModel } from "../common/BehaviorTreeModel";
|
||||
import * as glob from "glob";
|
||||
import * as path from "path";
|
||||
|
||||
export interface WorkspaceModel {
|
||||
isRelative?: boolean;
|
||||
@@ -9,10 +10,10 @@ export interface WorkspaceModel {
|
||||
}
|
||||
|
||||
const unknowNodeType: BehaviorNodeTypeModel = {
|
||||
name: 'unknow',
|
||||
desc: '新建节点',
|
||||
type: 'Action',
|
||||
}
|
||||
name: "unknow",
|
||||
desc: "新建节点",
|
||||
type: "Action",
|
||||
};
|
||||
|
||||
export default class Workspace {
|
||||
private filepath: string;
|
||||
@@ -68,13 +69,36 @@ export default class Workspace {
|
||||
this.nodeConfPath = path;
|
||||
this.initNodeConf();
|
||||
}
|
||||
getWorkdir() {
|
||||
getWorkdir(): string {
|
||||
return this.workdir;
|
||||
}
|
||||
setWorkdir(workdir: string) {
|
||||
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) {
|
||||
if (filepath) {
|
||||
this.filepath = filepath;
|
||||
@@ -82,10 +106,17 @@ export default class Workspace {
|
||||
if (!this.filepath) {
|
||||
return;
|
||||
}
|
||||
fs.writeFileSync(this.filepath, JSON.stringify({
|
||||
fs.writeFileSync(
|
||||
this.filepath,
|
||||
JSON.stringify(
|
||||
{
|
||||
nodeConfPath: this.nodeConfPath,
|
||||
workdir: this.workdir,
|
||||
}, null, 2))
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
get nodeConf() {
|
||||
|
||||
Reference in new issue
Block a user