123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- ---@class HotfixCodeGenHandler 热更层代码生成器
- local HotfixCodeGenHandler = {}
- --- 执行生成热更层代码
- ---@param handler CS.FairyEditor.PublishHandler
- ---@param codeGenConfig CodeGenConfig
- function HotfixCodeGenHandler.Do(handler, codeGenConfig)
- local codePkgName = handler:ToFilename(handler.pkg.name); --convert chinese to pinyin, remove special chars etc.
- --- 从自定义配置中读取路径和命名空间
- local exportCodePath = codeGenConfig.HotfixCodeOutPutPath .. '/' .. codePkgName
- local namespaceName = codeGenConfig.HotfixNameSpace
- --- 初始化自定义组件名前缀
- local classNamePrefix = codeGenConfig.ClassNamePrefix
- --- 初始化自定义成员变量名前缀
- local memberVarNamePrefix = codeGenConfig.MemerVarNamePrefix
-
- --- 从FGUI编辑器中读取配置
- ---@type CS.FairyEditor.GlobalPublishSettings.CodeGenerationConfig
- local settings = handler.project:GetSettings("Publish").codeGeneration
- local getMemberByName = settings.getMemberByName
- --- 所有将要导出的类(当前包的所有设置为导出的组件,以及当前包所有被引用的组件)
- ---@type CS.FairyEditor.PublishHandler.ClassInfo[]
- local classes = handler:CollectClasses(codeGenConfig.CodeStrip, codeGenConfig.CodeStrip, nil)
- handler:SetupCodeFolder(exportCodePath, "cs") --check if target folder exists, and delete old files
- local classCnt = classes.Count
- local writer = CodeWriter.new()
- for i = 0, classCnt - 1 do
- local classInfo = classes[i]
- local members = classInfo.members
- writer:reset()
- writer:writeln('using FairyGUI;')
- writer:writeln('using Cysharp.Threading.Tasks;')
- writer:writeln()
- writer:writeln('namespace %s', namespaceName)
- writer:startBlock()
-
- --- 组装自定义组件前缀
- local className = classNamePrefix .. classInfo.className
- -- 1
- writer:writeln([[public class %sAwakeSystem : AwakeSystem<%s, GObject>
- {
- public override void Awake(%s self, GObject go)
- {
- self.Awake(go);
- }
- }
- ]], className, className, className)
-
- writer:writeln([[public class %sDestroySystem : DestroySystem<%s>
- {
- public override void Destroy(%s self)
- {
- self.Destroy();
- }
- }
- ]], className, className, className)
- writer:writeln([[public sealed class %s : FUI
- {
- public const string UIPackageName = "%s";
- public const string UIResName = "%s";
-
- /// <summary>
- /// {uiResName}的组件类型(GComponent、GButton、GProcessBar等),它们都是GObject的子类。
- /// </summary>
- public %s self;
- ]], className, codePkgName, classInfo.resName, classInfo.superClassName)
- local memberCnt = members.Count
- -- 是否为自定义类型组件标记数组
- local customComponentFlagsArray = {}
- -- 是否为跨包组件标记数组
- local crossPackageFlagsArray = {}
- for j = 0, memberCnt - 1
- do
- local memberInfo = members[j]
- customComponentFlagsArray[j] = false
- crossPackageFlagsArray[j] = false
- -- 判断是不是我们自定义类型组件
- local typeName = memberInfo.type
- for k = 0, classCnt - 1
- do
- if typeName == classes[k].className
- then
- typeName = classNamePrefix .. classes[k].className
- customComponentFlagsArray[j] = true
- break
- end
- end
- -- 判断是不是跨包类型组件
- if memberInfo.res ~= nil then
- --- 组装自定义组件前缀
- typeName = classNamePrefix .. memberInfo.res.name
- crossPackageFlagsArray[j] = true
- end
-
- --- 组装自定义成员前缀
- writer:writeln('\tpublic %s %s;', typeName, memberVarNamePrefix .. memberInfo.varName)
- end
- writer:writeln('\tpublic const string URL = "ui://%s%s";', handler.pkg.id, classInfo.resId)
- writer:writeln()
- writer:writeln([[
- private static GObject CreateGObject()
- {
- return UIPackage.CreateObject(UIPackageName, UIResName);
- }
-
- private static void CreateGObjectAsync(UIPackage.CreateObjectCallback result)
- {
- UIPackage.CreateObjectAsync(UIPackageName, UIResName, result);
- }
- ]])
- writer:writeln([[
- public static %s CreateInstance(Entity parent)
- {
- return parent.AddChild<%s, GObject>(CreateGObject());
- }
- ]], className, className)
- writer:writeln([[
- public static UniTask<%s> CreateInstanceAsync(Entity parent)
- {
- UniTaskCompletionSource<%s> tcs = new UniTaskCompletionSource<%s>();
-
- CreateGObjectAsync((go) =>
- {
- tcs.TrySetResult(parent.AddChild<%s, GObject>(go));
- });
-
- return tcs.Task;
- }
- ]], className, className, className, className)
- writer:writeln([[
- /// <summary>
- /// 仅用于go已经实例化情况下的创建(例如另一个组件引用了此组件)
- /// </summary>
- /// <param name="domain"></param>
- /// <param name="go"></param>
- /// <returns></returns>
- public static %s Create(Entity parent, GObject go)
- {
- return parent.AddChild<%s, GObject>(go);
- }
- ]], className, className)
- writer:writeln([[
- /// <summary>
- /// 通过此方法获取的FUI,在Dispose时不会释放GObject,需要自行管理(一般在配合FGUI的Pool机制时使用)。
- /// </summary>
- public static %s GetFormPool(Entity domain, GObject go)
- {
- var fui = go.Get<%s>();
-
- if(fui == null)
- {
- fui = Create(domain, go);
- }
-
- fui.isFromFGUIPool = true;
-
- return fui;
- }
- ]], className, className)
- writer:writeln([[
- public void Awake(GObject go)
- {
- if(go == null)
- {
- return;
- }
-
- GObject = go;
-
- if (string.IsNullOrWhiteSpace(Name))
- {
- Name = Id.ToString();
- }
-
- self = (%s)go;
-
- self.Add(this);
-
- var com = go.asCom;
-
- if(com != null)
- {
- ]], classInfo.superClassName)
- for j = 0, memberCnt - 1
- do
- local memberInfo = members[j]
- --- 组装自定义成员前缀
- local memberVarName = memberVarNamePrefix .. memberInfo.varName
- if memberInfo.group == 0
- then
- if getMemberByName
- then
- if customComponentFlagsArray[j]
- then
- --- 组装自定义组件前缀
- writer:writeln('\t\t\t%s = %s.Create(this, com.GetChild("%s"));', memberVarName, classNamePrefix .. memberInfo.type, memberInfo.name)
- elseif crossPackageFlagsArray[j]
- then
- --- 组装自定义组件前缀
- writer:writeln('\t\t\t%s = %s.Create(this, com.GetChild("%s"));', memberVarName, classNamePrefix .. memberInfo.res.name, memberInfo.name)
- else
- writer:writeln('\t\t\t%s = (%s)com.GetChild("%s");', memberVarName, memberInfo.type, memberInfo.name)
- end
- else
- if customComponentFlagsArray[j]
- then
- --- 组装自定义组件前缀
- writer:writeln('\t\t\t%s = %s.Create(this, com.GetChildAt(%s));', memberVarName, classNamePrefix .. memberInfo.type, memberInfo.index)
- elseif crossPackageFlagsArray[j]
- then
- --- 组装自定义组件前缀
- writer:writeln('\t\t\t%s = %s.Create(this, com.GetChildAt(%s));', memberVarName, classNamePrefix .. memberInfo.res.name, memberInfo.index)
- else
- writer:writeln('\t\t\t%s = (%s)com.GetChildAt(%s);', memberVarName, memberInfo.type, memberInfo.index)
- end
- end
- elseif memberInfo.group == 1
- then
- if getMemberByName
- then
- writer:writeln('\t\t\t%s = com.GetController("%s");', memberVarName, memberInfo.name)
- else
- writer:writeln('\t\t\t%s = com.GetControllerAt(%s);', memberVarName, memberInfo.index)
- end
- else
- if getMemberByName
- then
- writer:writeln('\t\t\t%s = com.GetTransition("%s");', memberVarName, memberInfo.name)
- else
- writer:writeln('\t\t\t%s = com.GetTransitionAt(%s);', memberVarName, memberInfo.index)
- end
- end
- end
- writer:writeln('\t\t}')
- writer:writeln('\t}')
- writer:writeln([[
- public override void Destroy()
- {
- base.Destroy();
-
- self.Remove();
- self = null;
- ]])
- for j = 0, memberCnt - 1 do
- local memberInfo = members[j]
-
- --- 组装自定义成员前缀
- local memberVarName = memberVarNamePrefix .. memberInfo.varName
- if memberInfo.group == 0 then
- if customComponentFlagsArray[j] or crossPackageFlagsArray[j] then
- writer:writeln('\t\t%s.Dispose();', memberVarName)
- end
- writer:writeln('\t\t%s = null;', memberVarName)
- elseif memberInfo.group == 1 then
- writer:writeln('\t\t%s = null;', memberVarName)
- else
- writer:writeln('\t\t%s = null;', memberVarName)
- end
- end
- writer:writeln('\t}')
- writer:writeln('}')
- writer:endBlock()
- writer:save(exportCodePath .. '/' .. className .. '.cs')
- end
- -- 写入fuipackage
- writer:reset()
- writer:writeln('namespace %s', namespaceName)
- writer:startBlock()
- writer:writeln('public static partial class FUIPackage')
- writer:startBlock()
- writer:writeln('public const string %s = "%s";', codePkgName, codePkgName)
- for i = 0, classCnt - 1 do
- local classInfo = classes[i]
- writer:writeln('public const string %s_%s = "ui://%s/%s";', codePkgName, classInfo.resName, codePkgName, classInfo.resName)
- end
- writer:endBlock() --class
- writer:endBlock() --namespace
- local binderPackageName = 'Package' .. codePkgName
- writer:save(exportCodePath .. '/' .. binderPackageName .. '.cs')
- end
- return HotfixCodeGenHandler
|