main.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. 'use strict';
  2. let reEditing = false;
  3. let reSaving = false;
  4. let reEditingModelString = null;
  5. let reEditingUuid = null;
  6. let reEditingName = null;
  7. module.exports = {
  8. load () {
  9. // 当 package 被正确加载的时候执行
  10. //console.log("behaviortree-editor loaded");
  11. },
  12. unload () {
  13. // 当 package 被正确卸载的时候执行
  14. //console.log("behaviortree-editor unloaded");
  15. },
  16. messages: {
  17. 'test' (e,arg){
  18. Editor.log(arg);
  19. Editor.log(Editor.metas);
  20. },
  21. 're-open-by-comp' (e,arg) {
  22. if(reEditing){
  23. Editor.Dialog.messageBox ({
  24. type:"none",
  25. buttons: ["shut up"],
  26. title:"tips",
  27. message: "you are locked in re-editing mode.",
  28. detail:"leave the re-editing mode and try again. maybe you should save first."
  29. },function(){});
  30. return};
  31. reEditing = true;
  32. Editor.Panel.open("behaviortree-editor");
  33. //Editor.Ipc.sendToPanel('behaviortree-editor','load-data',);
  34. //Editor.log(arg.uuid);
  35. Editor.Ipc.sendToMain("asset-db:query-path-by-uuid",arg.uuid,function(e,result){
  36. //Editor.log(e);
  37. //Editor.log(result);
  38. let fs_handler = require('fs');
  39. fs_handler.readFile(result, "utf-8", function(err, data) {
  40. //Editor.log(data);
  41. let modelString= data.match(/\/\/#########################################.*#############################################/)[0].replace(/#*/g,"").replace(/^\/\//,"");
  42. reEditingModelString = modelString;
  43. reEditingUuid = arg.uuid;
  44. reEditingName = arg.name;
  45. //Editor.log(reEditingName);
  46. //Editor.log(modelData);
  47. //Editor.Ipc.sendToPanel("behaviortree-editor","re-modify-by-comp",{modelString:modelString,uuid:arg.uuid});
  48. //require('electron').ipcMain.send('behaviortree-editor:re-modify-by-comp',{modelString:modelString,uuid:arg.uuid});
  49. //Editor.log(Editor.Ipc);
  50. });
  51. });
  52. },
  53. 'load-data-of-comp' (e,arg){
  54. if(!reEditing){Editor.Dialog.messageBox ({
  55. type:"none",
  56. buttons: ["shut up"],
  57. title:"tips",
  58. message: "you are not in re-editing mode",
  59. detail:"you can enter the re-editing mode from behaviortree-Component."
  60. },function(){});
  61. e.reply(null,{error: true});
  62. }else{
  63. if(reSaving){Editor.log(Editor.Dialog.messageBox ({
  64. type:"none",
  65. buttons: ["shut up"],
  66. title:"tips",
  67. message: "please wait the temp saving",
  68. detail:"after saving, you can load from lasteat saved data if in re-editing mode."
  69. },function(){}));e.reply(null,{error:true})}
  70. else{
  71. e.reply(null,{error: false, reEditingModelString:reEditingModelString, reEditingName: reEditingName});
  72. }
  73. }
  74. },
  75. 'leave-re-editing-mode' (e){
  76. reEditing = false;
  77. Editor.log(Editor.Dialog.messageBox ({
  78. type:"none",
  79. buttons: ["shut up"],
  80. title:"tips",
  81. message: "you leave re-editing mode",
  82. detail:"in new mode the file would saved as default way.and just close the edit-panel would not leave re-editing mode."
  83. },function(){}));e.reply(null,{error:true})
  84. e.reply(null,{});
  85. },
  86. 'open' () {
  87. Editor.Panel.open("behaviortree-editor");
  88. },
  89. 'receive-json' (e,arg) {
  90. let modelAsObj = arg;
  91. //console.log(modelAsObj);
  92. let nodeDataArray = modelAsObj.nodeDataArray;
  93. let getNodeByType = function(type){
  94. for(let node of nodeDataArray){
  95. if(node.type == type){
  96. return node;
  97. }
  98. }
  99. };
  100. let getNodesByParentKey = function(key){
  101. let nodes = [];
  102. for(let node of nodeDataArray){
  103. if(node.parent!== undefined && node.parent == key){
  104. nodes.push(node);
  105. }
  106. }
  107. return nodes;
  108. };
  109. let orderFromTopToDown = function(a,b){
  110. let ay = a.loc.split(" ")[1];
  111. let by = b.loc.split(" ")[1];
  112. //Editor.log(ay,by,(ay - by) | 0);
  113. return (ay - by) | 0;
  114. }
  115. let rootNode = getNodeByType("Root");
  116. let generateTreeLayerString = function(parentNode,childNodes){
  117. let children = [];
  118. for(let childNode of childNodes){
  119. if(childNode.name == childNode.type){
  120. children.push("new b3." + childNode.type + "(" + "##key" + childNode.key +"##" +")");
  121. }else{
  122. children.push("new " + childNode.name + "(" +"##key" + childNode.key +"##"+ ")");
  123. }
  124. // if(childNode.parameter){
  125. // console.log(childNode.parameter.replace(/\"/g,"'"));
  126. // }
  127. }
  128. let tempParameter = JSON.parse(parentNode.parameter);
  129. let resultObj = {};
  130. resultObj.parameter = parentNode.parameter.replace(/"/g,"'");
  131. switch(parentNode.type){
  132. case 'Limiter':
  133. case 'RepeaterUntilFailure':
  134. case 'RepeaterUntilSuccess':
  135. case 'Repeater':{resultObj.maxLoop = tempParameter.maxLoop; break;}
  136. }
  137. switch(parentNode.type){
  138. case 'MaxTime': {resultObj.maxTime = rtempParameter.maxTime; break;}
  139. }
  140. switch(parentNode.type){
  141. case 'Wait': {resultObj.milliseconds = tempParameter.milliseconds; break;}
  142. }
  143. switch(parentNode.catagory){
  144. case 'Composite': {resultObj.children = children; break;}
  145. }
  146. switch(parentNode.catagory){
  147. case 'Decorator': {resultObj.child = children[0]; break;}
  148. }
  149. return JSON.stringify(resultObj);
  150. }
  151. let nodeQuene = [];
  152. nodeQuene.push(rootNode);
  153. let finalString = "new b3.Sequence(##key" + rootNode.key +"##)";
  154. while(nodeQuene.length != 0){
  155. let node = nodeQuene.shift();
  156. let childNodes = getNodesByParentKey(node.key);
  157. let orderedChildNodes = childNodes.sort(orderFromTopToDown);
  158. nodeQuene = nodeQuene.concat(orderedChildNodes);
  159. let gString = generateTreeLayerString(node,orderedChildNodes);
  160. finalString = finalString.replace("##key"+node.key+"##",gString);
  161. }
  162. //console.log(finalString);
  163. let customNodeString = "let self = this;\n";
  164. let hasGeneratedNodes = [];
  165. for(let node of nodeDataArray){
  166. if(hasGeneratedNodes[node.name] != undefined){continue;}
  167. if(node.name != node.type || node.type == 'Action' || node.type == 'Condition' || node.type == 'Composite' || node.type == 'Decorator'){
  168. hasGeneratedNodes[node.name] = true;
  169. customNodeString += "let "+node.name+" = b3.Class(b3."+node.type+");\n" +
  170. node.name+".prototype.name = '"+node.name+"';\n" +
  171. node.name+".prototype.__"+node.catagory+"_initialize = "+node.name+".prototype.initialize;\n" +
  172. node.name+".prototype.initialize = function(settings){\n" +
  173. " settings = settings || {};\n" +
  174. " this.__"+node.catagory+"_initialize();\n" +
  175. " this.parameter = settings.parameter;\n";
  176. switch(node.type){
  177. case 'Limiter':
  178. case 'RepeaterUntilFailure':
  179. case 'RepeaterUntilSuccess':
  180. case 'Repeater':{customNodeString += "this.maxLoop = settings.maxLoop;\n";break;}
  181. }
  182. switch(node.type){
  183. case 'MaxTime': {customNodeString += "this.maxTime = settings.maxTime;\n";break;}
  184. }
  185. switch(node.type){
  186. case 'Wait': {customNodeString += "this.milliseconds = settings.milliseconds;\n";break;}
  187. }
  188. switch(node.catagory){
  189. case 'Composite': {customNodeString += "this.children = settings.children;\n";break;}
  190. }
  191. switch(node.catagory){
  192. case 'Decorator': {customNodeString += "this.child = settings.child;\n";break;}
  193. }
  194. customNodeString += "}\n" +
  195. node.name+".prototype.enter = function(tick){\n" +
  196. " return self.getComponent('"+node.name+"').enter(tick,b3,this);\n" +
  197. "}\n" +
  198. node.name+".prototype.open = function(tick) {\n" +
  199. " return self.getComponent('"+node.name+"').open(tick,b3,this);\n" +
  200. "}\n" +
  201. node.name+".prototype.tick = function(tick) {\n" +
  202. " return self.getComponent('"+node.name+"').tick(tick,b3,this);\n" +
  203. "}\n" +
  204. node.name+".prototype.close = function(tick) {\n" +
  205. " return self.getComponent('"+node.name+"').close(tick,b3,this);\n" +
  206. "}\n" +
  207. node.name+".prototype.exit = function(tick) {\n" +
  208. " return self.getComponent('"+node.name+"').exit(tick,b3,this);\n" +
  209. "}\n";
  210. }
  211. }
  212. let tipsString = "//Don't modify this if you want to re-modify the behaviortree in the future\n";
  213. let modelString = "//#########################################" + JSON.stringify(modelAsObj) + "#############################################\n";
  214. //添加js脚本
  215. // let mainString = tipsString +
  216. // modelString +
  217. // "\n" +
  218. // "\n" +
  219. // "cc.Class({\n" +
  220. // "extends: cc.Component,\n" +
  221. // "editor: {\n" +
  222. // "inspector: 'packages://behaviortree-editor/bt-inspector.js'\n"+
  223. // "},\n" +
  224. // "properties: {\n" +
  225. // "},\n" +
  226. // "onLoad: function () {\n" +
  227. // "let b3 = require('b3core.0.1.0module');\n"+
  228. // customNodeString +
  229. // "let tree = new b3.BehaviorTree();\n"+
  230. // "tree.root = " + finalString.replace(/"/g,"") + ";\n"+
  231. // "this.tree = tree;\n"+
  232. // "this.blackboard = new b3.Blackboard();\n" +
  233. // "this.b3 = b3;\n" +
  234. // "},\n" +
  235. // "tick: function(target){\n"+
  236. // "let t = {};\n" +
  237. // "if(target != undefined){t = target;}\n" +
  238. // "this.tree.tick(t,this.blackboard)\n" +
  239. // "}" +
  240. // "});\n";
  241. // 添加ts脚本
  242. let mainString = tipsString +
  243. modelString +
  244. "\n" +
  245. "\n" +
  246. "const {ccclass, property} = cc._decorator;\n" +
  247. "export default class newClass extends cc.Component {\n" +
  248. "editor: {\n" +
  249. "inspector: 'packages://behaviortree-editor/bt-inspector.js'\n"+
  250. "},\n" +
  251. // "properties: {\n" +
  252. // "},\n" +
  253. "onLoad () {\n" +
  254. "let b3 = require('b3core.0.1.0module');\n"+
  255. customNodeString +
  256. "let tree = new b3.BehaviorTree();\n"+
  257. "tree.root = " + finalString.replace(/"/g,"") + ";\n"+
  258. "this.tree = tree;\n"+
  259. "this.blackboard = new b3.Blackboard();\n" +
  260. "this.b3 = b3;\n" +
  261. "},\n" +
  262. "tick(target){\n"+
  263. "let t = {};\n" +
  264. "if(target != undefined){t = target;}\n" +
  265. "this.tree.tick(t,this.blackboard)\n" +
  266. "}" +
  267. "});\n"; +
  268. "}\n";
  269. //console.log(mainString);
  270. let fs_handler = require("fs");
  271. if(reEditing){
  272. Editor.Ipc.sendToMain("asset-db:query-url-by-uuid",reEditingUuid,function(e,result){
  273. fs_handler.writeFileSync(Editor.url(result),mainString);
  274. Editor.Ipc.sendToMain("asset-db:refresh",result,function(err,results){
  275. reSaving = true;
  276. fs_handler.readFile(Editor.url(result), "utf-8", function(err, data) {
  277. let modelString= data.match(/\/\/#########################################.*#############################################/)[0].replace(/#*/g,"").replace(/^\/\//,"");
  278. reEditingModelString = modelString;
  279. reSaving = false;
  280. Editor.log(Editor.Dialog.messageBox ({
  281. type:"none",
  282. buttons: ["shut up"],
  283. title:"tips",
  284. message: "file of re-edit saved",
  285. detail:"you could see something blink blink in assetdb. take care of the component name."
  286. },function(){}));
  287. });
  288. });
  289. });
  290. }
  291. else{
  292. //生成行为树组件脚本
  293. //添加js脚本
  294. // fs_handler.writeFileSync(Editor.url("db://assets/BehaviorTree.js"),mainString);
  295. // Editor.Ipc.sendToMain("asset-db:refresh","db://assets/BehaviorTree.js",function(err,results){
  296. //添加ts脚本
  297. fs_handler.writeFileSync(Editor.url("db://assets/script/behaviorTrees/BehaviorTree.ts"),mainString);
  298. Editor.Ipc.sendToMain("asset-db:refresh","db://assets/script/behaviorTrees/BehaviorTree.ts",function(err,results){
  299. Editor.log(Editor.Dialog.messageBox ({
  300. type:"none",
  301. buttons: ["shut up"],
  302. title:"tips",
  303. message: "file of new saved",
  304. detail:"you could see something new(maybe) in assetdb. take care of the component name."
  305. },function(){}));
  306. });
  307. }
  308. },
  309. 'add-lib' () {
  310. let fs_handler = require("fs");
  311. fs_handler.writeFileSync(Editor.url("db://assets/script/behaviorTrees/b3core.0.1.0module.js"), fs_handler.readFileSync(Editor.url("packages://behaviortree-editor/b3core.0.1.0module.js")));
  312. Editor.Ipc.sendToMain("asset-db:refresh","db://assets/script/behaviorTrees/b3core.0.1.0module.js",function(err,results){
  313. Editor.log(Editor.Dialog.messageBox ({
  314. type:"none",
  315. buttons: ["shut up"],
  316. title:"tips",
  317. message: "behaviortree lib added",
  318. detail:"even though the lib name is ugly, but don't modify it please."
  319. },function(){}));
  320. });
  321. },
  322. 'generate-tree-node-template' (){
  323. // 添加js脚本
  324. // let mainString = "cc.Class({\n" +
  325. // "extends: cc.Component,\n" +
  326. // "\n" +
  327. // "properties: {\n" +
  328. // "\n" +
  329. // "},\n" +
  330. // "\n" +
  331. // "\n" +
  332. // "onLoad: function () {\n" +
  333. // "\n" +
  334. // "},\n" +
  335. // "enter: function(tick,b3,treeNode){\n" +
  336. // "\n" +
  337. // "},\n"+
  338. // "open: function(tick,b3,treeNode){\n" +
  339. // "\n"+
  340. // "},\n" +
  341. // "tick: function(tick,b3,treeNode){\n" +
  342. // "\n"+
  343. // "},\n" +
  344. // "close: function(tick,b3,treeNode){\n" +
  345. // "\n" +
  346. // "},\n" +
  347. // "exit: function(tick,b3,treeNode){\n" +
  348. // "\n" +
  349. // "},\n" +
  350. // "\n" +
  351. // "});\n";
  352. // 添加ts脚本
  353. let mainString = "const {ccclass, property} = cc._decorator;\n" +
  354. "export default class newClass extends cc.Component {\n" +
  355. "\n" +
  356. // "properties: {\n" +
  357. // "\n" +
  358. // "},\n" +
  359. "\n" +
  360. "\n" +
  361. "onLoad () {\n" +
  362. "\n" +
  363. "},\n" +
  364. "enter (tick,b3,treeNode){\n" +
  365. "\n" +
  366. "},\n"+
  367. "open (tick,b3,treeNode){\n" +
  368. "\n"+
  369. "},\n" +
  370. "tick (tick,b3,treeNode){\n" +
  371. "\n"+
  372. "},\n" +
  373. "close (tick,b3,treeNode){\n" +
  374. "\n" +
  375. "},\n" +
  376. "exit (tick,b3,treeNode){\n" +
  377. "\n" +
  378. "},\n" +
  379. "\n" +
  380. "});\n"; +
  381. "}\n";
  382. let fs_handler = require("fs");
  383. // 添加js脚本
  384. // fs_handler.writeFileSync(Editor.url("db://assets/TreeNodeTemplate.js"), mainString);
  385. // Editor.Ipc.sendToMain("asset-db:refresh","db://assets/TreeNodeTemplate.js",function(err,results){
  386. // 添加ts脚本
  387. fs_handler.writeFileSync(Editor.url("db://assets/script/behaviorTrees/TreeNodeTemplate.ts"), mainString);
  388. Editor.Ipc.sendToMain("asset-db:refresh","db://assets/script/behaviorTrees/TreeNodeTemplate.ts",function(err,results){
  389. Editor.log(Editor.Dialog.messageBox ({
  390. type:"none",
  391. buttons: ["shut up"],
  392. title:"tips",
  393. message: "treenode code template generated",
  394. detail:"look more about the code and the src in behaviortree lib to get more tips"
  395. },function(){}));
  396. });
  397. },
  398. },
  399. };