"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.genCSCode = genCSCode; var FairyEditor = CS.FairyEditor; var System = CS.System; const CodeWriter_1 = require("./CodeWriter"); const GenCodeSettings_1 = require("./GenCodeSettings"); const LanguageSettings_1 = require("./LanguageSettings"); const File = System.IO.File; const Directory = System.IO.Directory; const App = FairyEditor.App; var allSuperClassNameByUrl = {}; var allCustomNameByUrl = {}; var namespaceName = ""; var setNamespaceName = false; var exportCodePath = ""; var existScriptPaths = {}; var packageName = ''; //获取所有的文件的路径 function getAllDirector(path, list) { let dirs = Directory.GetDirectories(path); for (let index = 0; index < dirs.Length; index++) { let dir = dirs.get_Item(index); getAllFile(dir, list); let dirs2 = Directory.GetDirectories(dir); if (dirs2.Length > 0) { getAllDirector(dir, list); } } } function getAllFile(dir, list) { let files = Directory.GetFiles(dir, "*.cs"); for (let f = 0; f < files.Length; f++) { list.push(files.get_Item(f)); } } class WhootCodeWriterConfig { blockStart; blockEnd; blockFromNewLine; usingTabs; endOfLine; fileMark; } function genCSCode(handler) { console.log("gencode==========--------------========"); let settings = handler.project.GetSettings("Publish").codeGeneration; let codePkgName = handler.ToFilename(handler.pkg.name); exportCodePath = handler.exportCodePath; // + '/' + codePkgName; console.log("exportCodePath=", exportCodePath); let pkgId = handler.pkg.id; packageName = handler.pkg.name; existScriptPaths = {}; let list = []; getAllFile(exportCodePath, list); //开始前,先遍历整个生成目录。找寻所有文件。用以判断生成的文件存放地址 getAllDirector(exportCodePath, list); for (let index = 0; index < list.length; index++) { let path = list[index]; var newPath = path.replace(/\\/g, '/'); let arrs = newPath.split('/'); let key = arrs[arrs.length - 1]; existScriptPaths[key] = path; } namespaceName = ""; setNamespaceName = false; if (settings.packageName) { namespaceName = settings.packageName; setNamespaceName = true; } let classes = handler.CollectClasses(settings.ignoreNoname, settings.ignoreNoname, null); let getMemberByName = true; //默认使用名称获取对象//settings.getMemberByName; console.log(codePkgName, namespaceName, getMemberByName); let classCnt = classes.Count; allCustomNameByUrl = {}; allSuperClassNameByUrl = {}; let dependPackages = []; //因为没有文档,同时返回内容限制,先保存子类基类关系。用于后续判断是否使用自定义类 for (let i = 0; i < classCnt; i++) { let classInfo = classes.get_Item(i); let url = classInfo.res.GetURL(); allSuperClassNameByUrl[url] = classInfo.superClassName; let config = GenCodeSettings_1.default.getComponentSetting(url); if (config != null) { if (config.isCustomName) { allCustomNameByUrl[url] = settings.classNamePrefix + config.customName; } } //获取依赖的包 for (let index = 0; index < classInfo.members.Count; index++) { let element = classInfo.members.get_Item(index); if (element.res != null && element.res.owner != null) { let pname = element.res.owner.name; if (dependPackages.indexOf(pname) < 0 && pname != codePkgName) { dependPackages.push(pname); } } } } let componentClassNameArr = []; for (let i = 0; i < classCnt; i++) { let classInfo = classes.get_Item(i); let url = classInfo.res.GetURL(); let config = GenCodeSettings_1.default.getComponentSetting(url); if (config != null) { console.log(config.name, config.scriptType); if (config.scriptType == "panel") { genPanelCode(classInfo, config, codePkgName, pkgId, dependPackages); } else if (config.scriptType == "component") { let ComponentClassName = genComponentCode(classInfo, config, codePkgName, pkgId); componentClassNameArr.push(ComponentClassName); } } else { console.log(classInfo.resName + "未配置导出,忽略"); } } console.log("生成Binder,count=" + componentClassNameArr.length); genBinder(codePkgName, componentClassNameArr); genLanguage(); } function getScriptName(className, comUrl) { if (allCustomNameByUrl.hasOwnProperty(comUrl)) { className = allCustomNameByUrl[comUrl]; } return className; } function genPanelCode(classInfo, config, codePkgName, pkgId, dependPackages) { let codeConfig = new WhootCodeWriterConfig(); codeConfig.fileMark = "/**本脚本为自动生成,每次生成会覆盖!请勿手动修改,生成插件文档及项目地址:https://git.whoot.com/whoot-games/whoot.fguieditorplugin**/"; let comUrl = classInfo.res.GetURL(); //先生成 .Designer部分 let writer = new CodeWriter_1.default(codeConfig); writer.writeln('using FairyGUI;'); writer.writeln('using FairyGUI.Utils;'); writer.writeln('using NBC;'); writer.writeln('using System.Collections.Generic;'); writer.writeln(); let className = getScriptName(classInfo.className, comUrl); if (setNamespaceName) { writer.writeln('namespace %s', namespaceName); writer.startBlock(); writer.writeln("/// %s ", config.annotation); writer.writeln('public partial class %s', className); writer.startBlock(); } else { writer.writeln("/// %s ", config.annotation); writer.writeln('public partial class %s', className); writer.startBlock(); } writer.writeln("public GObject this[string aKey] => ContentPane.GetChild(aKey);"); writer.writeln('public override string UIPackName => "%s";', codePkgName); writer.writeln('public override string UIResName => "%s";', classInfo.res.name); writer.writeln(); let members = classInfo.members; let memberCnt = members.Count; for (let j = 0; j < memberCnt; j++) { let memberInfo = members.get_Item(j); if (memberInfo.res != null) { let superClassName = getComponentUseClassName(memberInfo, comUrl); writer.writeln('[AutoFind(Name = "%s")]', memberInfo.name); //判断配置,是否需要使用生成的类 writer.writeln('public %s %s;', superClassName, memberInfo.varName); } else { writer.writeln('[AutoFind(Name = "%s")]', memberInfo.name); writer.writeln('public %s %s;', memberInfo.type, memberInfo.varName); } } let url = `ui://${pkgId}${classInfo.resId}`; if (dependPackages != null) { let str = ""; let len = dependPackages.length - 1; for (let index = 0; index <= len; index++) { let pname = dependPackages[index]; str += `"${pname}"`; if (index < len) { str += ","; } } writer.writeln(`public override string[] GetDependPackages(){ return new string[] {${str}}; }`); writer.writeln(); } writer.writeln(`public static void Show(object param = null){ App.UI.OpenUI<${className}>(param); }`); writer.writeln(); writer.writeln(`public static void Hide(){ App.UI.HideUI<${className}>(); }`); writer.writeln(); writer.writeln(`public static void Del(){ App.UI.DestroyUI<${className}>(); }`); writer.writeln(); writer.endBlock(); if (setNamespaceName) { writer.endBlock(); } let fileName = className + ".Designer" + '.cs'; let savePath = exportCodePath + '/' + fileName; if (existScriptPaths.hasOwnProperty(fileName)) { console.log("脚本已经有同名的,替换地址=", fileName, existScriptPaths[fileName]); savePath = existScriptPaths[fileName]; } writer.save(savePath); // 判断模块脚本是否存在。如果不存在,创建默认模板脚本 let defFileName = className + '.cs'; if (!existScriptPaths.hasOwnProperty(defFileName)) { let mainSavePath = exportCodePath + '/' + defFileName; console.log("Panel的主脚本不存在,生成默认=", mainSavePath); writer.reset(); codeConfig.fileMark = "// 本脚本只在不存在时会生成一次。已存在不会再次生成覆盖"; writer = new CodeWriter_1.default(codeConfig); writer.writeln('using UnityEngine;'); writer.writeln('using NBC;'); writer.writeln(); if (setNamespaceName) { writer.writeln('namespace %s', namespaceName); writer.startBlock(); writer.writeln('public partial class %s : UIPanel', className); writer.startBlock(); } else { writer.writeln('public partial class %s : UIPanel', className); writer.startBlock(); } // writer.writeln('protected override void OnInit()'); // writer.startBlock(); // writer.writeln('base.OnInit();'); // writer.endBlock(); // writer.writeln(); // writer.writeln('protected override void OnShow()'); // writer.startBlock(); // writer.writeln('base.OnShow();'); // writer.endBlock(); // writer.writeln(); // writer.writeln('protected override void OnHide()'); // writer.startBlock(); // writer.writeln('base.OnHide();'); // writer.endBlock(); // writer.writeln(); // writer.writeln('protected override void OnDestroy()'); // writer.startBlock(); // writer.writeln('base.OnDestroy();'); // writer.endBlock(); writer.endBlock(); if (setNamespaceName) { writer.endBlock(); } writer.save(mainSavePath); } } function getComponentUseClassName(memberInfo, comUrl) { let name = memberInfo.type; let useCustomScript = false; if (memberInfo.res != null) { let comUrl = memberInfo.res.GetURL(); //是自定义组件,改为使用原生,不适用自定义 let superClassName = allSuperClassNameByUrl[comUrl]; let config = GenCodeSettings_1.default.getComponentSetting(comUrl); if (config != null && config.scriptType == "component") { superClassName = memberInfo.res.name; useCustomScript = true; } if (superClassName == null || superClassName == undefined) { superClassName = memberInfo.type; } name = superClassName; } return name; //{ name: name, useCustomScript: useCustomScript } } function genComponentCode(classInfo, config, codePkgName, pkgId) { let codeConfig = new WhootCodeWriterConfig(); codeConfig.fileMark = "/**本脚本为自动生成,每次生成会覆盖!请勿手动修改,生成插件文档及项目地址:https://git.whoot.com/whoot-games/whoot.fguieditorplugin**/"; let comUrl = classInfo.res.GetURL(); let className = getScriptName(classInfo.className, comUrl); let writer = new CodeWriter_1.default(codeConfig); writer.writeln(); writer.writeln('using FairyGUI;'); writer.writeln('using FairyGUI.Utils;'); writer.writeln('using NBC;'); writer.writeln(); if (setNamespaceName) { writer.writeln('namespace %s', namespaceName); writer.startBlock(); writer.writeln('public partial class %s', className); writer.startBlock(); } else { writer.writeln('public partial class %s', className); writer.startBlock(); } writer.writeln('public const string URL = "ui://%s%s";', pkgId, classInfo.resId); writer.writeln(); //生成成员变量 let members = classInfo.members; let memberCnt = members.Count; for (let j = 0; j < memberCnt; j++) { let memberInfo = members.get_Item(j); if (memberInfo.res != null) { let superClassName = getComponentUseClassName(memberInfo, comUrl); writer.writeln('public %s %s;', superClassName, memberInfo.varName); } else { writer.writeln('public %s %s;', memberInfo.type, memberInfo.varName); } } writer.writeln(); writer.writeln('public override void ConstructFromXML(XML xml)'); writer.startBlock(); writer.writeln('base.ConstructFromXML(xml);'); writer.writeln(); for (let j = 0; j < memberCnt; j++) { let memberInfo = members.get_Item(j); if (memberInfo.group == 0) { let superClassName = memberInfo.type; let useExtend = false; if (memberInfo.res != null) { superClassName = getComponentUseClassName(memberInfo, comUrl); } writer.writeln('%s = (%s)GetChild("%s");', memberInfo.varName, superClassName, memberInfo.name); } else if (memberInfo.group == 1) { writer.writeln('%s = GetController("%s");', memberInfo.varName, memberInfo.name); } else { writer.writeln('%s = GetTransition("%s");', memberInfo.varName, memberInfo.name); } } writer.writeln('OnInited();'); writer.writeln('UILanguage.TrySetComponentLanguage(this);'); writer.endBlock(); writer.endBlock(); if (setNamespaceName) { writer.endBlock(); } let fileName = className + ".Designer" + '.cs'; let savePath = exportCodePath + '/' + fileName; if (existScriptPaths.hasOwnProperty(fileName)) { console.log("脚本已经有同名的,替换地址=", fileName, existScriptPaths[fileName]); savePath = existScriptPaths[fileName]; } writer.save(savePath); // 判断模块脚本是否存在。如果不存在,创建默认模板脚本 let defFileName = className + '.cs'; if (!existScriptPaths.hasOwnProperty(defFileName)) { let mainSavePath = exportCodePath + '/' + defFileName; console.log("Component的主脚本不存在,生成默认"); writer.reset(); codeConfig.fileMark = "// 本脚本只在不存在时会生成一次。组件逻辑写在当前脚本内。已存在不会再次生成覆盖 "; writer = new CodeWriter_1.default(codeConfig); writer.writeln('using UnityEngine;'); writer.writeln('using FairyGUI;'); writer.writeln('using NBC;'); writer.writeln(); if (setNamespaceName) { writer.writeln('namespace %s', namespaceName); writer.startBlock(); writer.writeln('public partial class %s : %s', className, classInfo.superClassName); writer.startBlock(); } else { writer.writeln('public partial class %s : %s', className, classInfo.superClassName); writer.startBlock(); } writer.writeln('private void OnInited()'); writer.startBlock(); writer.endBlock(); writer.endBlock(); if (setNamespaceName) { writer.endBlock(); } writer.save(mainSavePath); } return className; } /** * 生成自定义脚本绑定关系 * @param codePkgName * @param componentClassNameArr */ function genBinder(codePkgName, componentClassNameArr) { let binderName = codePkgName + 'Binder'; let codeConfig = new WhootCodeWriterConfig(); codeConfig.fileMark = "/**注册组件绑定关系。本脚本为自动生成,每次生成会覆盖!请勿手动修改,生成插件文档及项目地址:https://git.whoot.com/whoot-games/whoot.fguieditorplugin**/"; let writer = new CodeWriter_1.default(codeConfig); writer.reset(); writer.writeln('using FairyGUI;'); writer.writeln(); if (setNamespaceName) { writer.writeln('namespace %s', namespaceName); writer.startBlock(); } writer.writeln('public static class %s', binderName); writer.startBlock(); writer.writeln('[UIExtensionAutoBind]'); writer.writeln('public static void BindAll()'); writer.startBlock(); for (let i = 0; i < componentClassNameArr.length; i++) { //let classInfo = classes.get_Item(i); let name = componentClassNameArr[i]; writer.writeln('UIObjectFactory.SetPackageItemExtension(%s.URL, typeof(%s));', name, name); } writer.endBlock(); //bindall writer.endBlock(); //class if (setNamespaceName) { writer.endBlock(); //namespace } let fileName = binderName + '.cs'; let savePath = exportCodePath + '/' + fileName; console.log("生成binder 1=", fileName); if (existScriptPaths.hasOwnProperty(fileName)) { savePath = existScriptPaths[fileName]; } writer.save(savePath); } /** * 生成多语言 */ function genLanguage() { let binderName = 'UILangeageConfig'; let languageMap = LanguageSettings_1.default.getAllPackage(); //getPackage let codeConfig = new WhootCodeWriterConfig(); codeConfig.fileMark = "/**注册组件多语言绑定。本脚本为自动生成,每次生成会覆盖!请勿手动修改,生成插件文档及项目地址:https://git.whoot.com/whoot-games/whoot.fguieditorplugin**/"; let writer = new CodeWriter_1.default(codeConfig); writer.reset(); writer.writeln('using System.Collections.Generic;'); writer.writeln('using FairyGUI;'); writer.writeln('using NBC;'); writer.writeln(); if (setNamespaceName) { writer.writeln('namespace %s', namespaceName); writer.startBlock(); } writer.writeln('public class %s : UIComponentLanguagePack', binderName); writer.startBlock(); writer.writeln('public UILangeageConfig()'); writer.startBlock(); writer.writeln('AddData();'); writer.endBlock(); writer.writeln('private void AddData()'); writer.startBlock(); let keys = languageMap.keys(); for (let key of keys) { let pack = languageMap.get(key); let languageData = pack.components; for (let comUrl in languageData) { let comObj = languageData[comUrl]; if (comObj == undefined) continue; writer.writeln('Add("%s", new UIComponentLanguage()', comUrl); writer.startBlock(); for (let key2 in comObj) { var cfg = comObj[key2]; let useable = cfg['useable']; let languageKey = cfg["key"]; if (useable != 1) continue; writer.writeln('{ "%s", "%s" },', key2, languageKey); } writer.endBlock(); writer.writeln(');'); } writer.writeln(); } // for (let comUrl in languageData) { // let comObj = languageData[comUrl]; // if (comObj != undefined) { // for (let key in comObj) { // var cfg = comObj[key] // let useable = cfg['useable'] // let languageKey = cfg["key"] // if (useable == 1) { // console.log("comurl:" + comUrl + " key:" + key + " lan:" + languageKey) // } // } // } // } writer.endBlock(); //bindall writer.endBlock(); //class if (setNamespaceName) { writer.endBlock(); //namespace } let fileName = binderName + '.cs'; let savePath = exportCodePath + '/' + fileName; console.log("生成 language=", fileName); if (existScriptPaths.hasOwnProperty(fileName)) { savePath = existScriptPaths[fileName]; } writer.save(savePath); }