|
@@ -1,311 +0,0 @@
|
|
|
----@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
|