美文网首页
【FGUI】自动生成UI控件代码,lua写的插件

【FGUI】自动生成UI控件代码,lua写的插件

作者: 木心Sepith | 来源:发表于2022-04-28 17:22 被阅读0次

    在FGUI中可以自己去写lua的插件,来实现各种功能,最近写了一个自动生成UI控件的插件,需要的自取

    总共分为4个文件,全部放在FGUI的工程目录下的plugins文件夹里
    CodeGenEntry.lua
    CodeGenConfig.lua
    HotfixCodeGenHandler.lua
    package.json

    package.json

    {
      "name": "CodeGenerate",
      "displayName": "代码生成插件",
      "description": "",
      "version": "0.0.1",
      "author": {
        "name": "meta404"
      },
      "icon": "icon.png",
      "main": "CodeGenEntry.lua"
    }
    

    CodeGenEntry.lua

    local CodeGenEntry = {}
    
    ---@type HotfixCodeGenHandler
    CodeGenEntry.HotfixCodeGenHandler = require(PluginPath .. '/HotfixCodeGenHandler')
    ---@type CodeGenConfig
    CodeGenEntry.CodeGenConfig = require(PluginPath .. "/CodeGenConfig")
    
    --- 点击发布工程时的回调
    ---@param handler CS.FairyEditor.PublishHandler 发布处理者
    function onPublish(handler)
        --- 不勾选生成代码时,将为其生成热更层代码
        if not handler.genCode then
            CodeGenEntry.HotfixCodeGenHandler.Do(handler, CodeGenEntry.CodeGenConfig)
        else
            --- 勾选生成代码时,将为其生成非热更层代码
            CodeGenEntry.ModelCodeGenHandler.Do(handler, CodeGenEntry.CodeGenConfig)
        end
    end
    
    return CodeGenEntry
    

    CodeGenConfig.lua

    ---@class CodeGenConfig 代码生成配置
    local GenerateHotfixCodeConfig = {
        --- 热更代码配置
        --- 热更层命名空间
        HotfixNameSpace = "HotfixUI",
        --- 热更层代码输出目录
        --HotfixCodeOutPutPath = "../Unity/Assets/ModelView/Demo/FGUI/AutoGeneratedCode/",
        HotfixCodeOutPutPath = "E:/Project/Red/SVN/RedWar/Projects/RedWar/HotUpdateScripts/Game/UI/AutoGeneratedCode/",
    
        --- 代码裁剪,即是否为默认名称对象生成获取代码,如果为true,代表不会生成,否则会生成,注意如果开启可能会导致需要导出的类也没有导出的情况
        CodeStrip = false,
        
        --- 组件名前缀
        ClassNamePrefix = "FUI_",
        --- 成员名前缀
        MemerVarNamePrefix = "m_"
    }
    
    return GenerateHotfixCodeConfig
    

    HotfixCodeGenHandler.lua

    ---@class HotfixCodeGenHandler 热更层代码生成器
    local HotfixCodeGenHandler = {}
    
    --- 执行生成热更层代码
    ---@param handler CS.FairyEditor.PublishHandler
    ---@param codeGenConfig CodeGenConfig
    function HotfixCodeGenHandler.Do(handler, codeGenConfig)
        
        fprint("开始生成Hotfix代码")
    
        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
    
        fprint("找到" .. classes.Count .. "个classes的数量")
    
        local classCnt = classes.Count
        local writer = CodeWriter.new()
    
        local mainPanelIndex = 0
        for i = 0, classCnt - 1 do
            local className = classes[i].className
            fprint("class name: " .. className)
            if(string.find(className, 'Panel') ~= nil) then
                mainPanelIndex = i
                break;
            end
        end
    
        --for i = 0, classCnt - 1 do
        for i = mainPanelIndex, mainPanelIndex do
            local classInfo = classes[i]
            local members = classInfo.members
            writer:reset()
    
            writer:writeln('/** ============================================================================== **/')
            writer:writeln('/** ============================Auto Generate Class=============================== **/')
            writer:writeln('/** ============================================================================== **/')
    
            writer:writeln()
            writer:writeln('using FairyGUI;')
            writer:writeln('using FUIFW;')
            writer:writeln()
            writer:writeln('namespace %s', namespaceName)
            writer:startBlock()
    
            --- 组装自定义组件前缀
            local className = classNamePrefix .. classInfo.className
    
            writer:writeln([[public partial class %s : FUIBase
        {   
                ]], codePkgName, codePkgName, classInfo.resName, classInfo.superClassName)
    
    
            local memberCnt = members.Count
            fprint("找到了" .. memberCnt .. " 个成员变量")
    
            -- 是否为自定义类型组件标记数组
            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()
            writer:writeln([[
        public void Init(GObject go)
            {
                if(go == null)
                {
                    return;
                }
                
                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 = new %s(com.GetChildAt(%s));', memberVarName, classNamePrefix .. memberInfo.type, memberInfo.name)
                        elseif crossPackageFlagsArray[j]
                        then
                            --- 组装自定义组件前缀
                            writer:writeln('\t\t\t%s = new %s(com.GetChildAt(%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 = new %s(com.GetChildAt(%s));', memberVarName, classNamePrefix .. memberInfo.type, memberInfo.index)
                        elseif crossPackageFlagsArray[j]
                        then
                            --- 组装自定义组件前缀
                            writer:writeln('\t\t\t%s = new %s(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()
    
    
    
    
    
    
            local classCntSub = classes.Count
            fprint('找到了' .. classCntSub - 1 .. '个子对象')
            for m = 0, classCntSub - 1 do
                if(m ~= mainPanelIndex) then
    
                local classInfoSub = classes[m]
                local membersSub = classInfoSub.members
                local classNameSub = classNamePrefix .. classInfoSub.className
    
                writer:writeln([[
        public class %s
            {   
                        ]], classNameSub)
    
                local memberCntSub = membersSub.Count
                -- 是否为自定义类型组件标记数组
                local customComponentFlagsArraySub = {}
                -- 是否为跨包组件标记数组
                local crossPackageFlagsArraySub = {}
        
                for n = 0, memberCntSub - 1
                do
                    local memberInfoSub = membersSub[n]
                    customComponentFlagsArraySub[n] = false
                    crossPackageFlagsArraySub[n] = false
        
                    -- 判断是不是我们自定义类型组件
                    local typeNameSub = memberInfoSub.type
                    for k = 0, classCntSub - 1
                    do
                        if typeNameSub == classes[m].className
                        then
                            typeNameSub = classNamePrefix .. classes[m].className
                            customComponentFlagsArraySub[n] = true
                            break
                        end
                    end
        
                    -- 判断是不是跨包类型组件
                    if memberInfoSub.res ~= nil then
                        --- 组装自定义组件前缀
                        typeNameSub = classNamePrefix .. memberInfoSub.res.name
                        crossPackageFlagsArraySub[n] = true
                    end
                    
                    --- 组装自定义成员前缀
                    writer:writeln('\t\tpublic %s %s;', typeNameSub, memberVarNamePrefix .. memberInfoSub.varName)
                end
    
    
    
                writer:writeln()
                writer:writeln([[
            public %s(GObject go)
                {
                    if(go == null)
                    {
                        return;
                    }
                    
                    var com = go.asCom;
                        
                    if(com != null)
                    {   
                        ]], classNameSub)
        
                for j = 0, memberCntSub - 1
                do
                    local memberInfoSub = membersSub[j]
                    --- 组装自定义成员前缀
                    local memberVarNameSub = memberVarNamePrefix .. memberInfoSub.varName
                    if memberInfoSub.group == 0
                    then
                        if getMemberByNameSub
                        then
                            if customComponentFlagsArraySub[j]
                            then
                                --- 组装自定义组件前缀
                                writer:writeln('\t\t\t\t%s = new %s(com.GetChildAt(%s));', memberVarNameSub, classNamePrefix .. memberInfoSub.type, memberInfoSub.name)
                            elseif crossPackageFlagsArraySub[j]
                            then
                                --- 组装自定义组件前缀
                                writer:writeln('\t\t\t\t%s = new %s(com.GetChildAt(%s));', memberVarNameSub, classNamePrefix .. memberInfoSub.res.name, memberInfoSub.name)
                            else
                                writer:writeln('\t\t\t\t%s = (%s)com.GetChild("%s");', memberVarNameSub, memberInfoSub.type, memberInfoSub.name)
                            end
        
                        else
                            if customComponentFlagsArraySub[j]
                            then
                                --- 组装自定义组件前缀
                                writer:writeln('\t\t\t\t%s = new %s(com.GetChildAt(%s));', memberVarNameSub, classNamePrefix .. memberInfoSub.type, memberInfoSub.index)
                            elseif crossPackageFlagsArraySub[j]
                            then
                                --- 组装自定义组件前缀
                                writer:writeln('\t\t\t\t%s = new %s(com.GetChildAt(%s));', memberVarNameSub, classNamePrefix .. memberInfoSub.res.name, memberInfoSub.index)
                            else
                                writer:writeln('\t\t\t\t%s = (%s)com.GetChildAt(%s);', memberVarNameSub, memberInfoSub.type, memberInfoSub.index)
                            end
                        end
                    elseif memberInfoSub.group == 1
                    then
                        if getMemberByNameSub
                        then
                            writer:writeln('\t\t\t\t%s = com.GetController("%s");', memberVarNameSub, memberInfoSub.name)
                        else
                            writer:writeln('\t\t\t\t%s = com.GetControllerAt(%s);', memberVarNameSub, memberInfoSub.index)
                        end
                    else
                        if getMemberByNameSub
                        then
                            writer:writeln('\t\t\t\t%s = com.GetTransition("%s");', memberVarNameSub, memberInfoSub.name)
                        else
                            writer:writeln('\t\t\t\t%s = com.GetTransitionAt(%s);', memberVarNameSub, memberInfoSub.index)
                        end
                    end
                end
                writer:writeln('\t\t\t}')
        
                writer:writeln('\t\t}')
    
                writer:writeln('\t}')
                writer:writeln()
    
            end
            end
    
            writer:writeln('}')
            writer:endBlock()
    
            path = exportCodePath .. '/' .. codePkgName .. '.cs'
            writer:save(path)
            fprint("生成代码完毕:" .. path)
        end
    
    end
    
    return HotfixCodeGenHandler
    

    最后看下生成的效果

    /** This is an automatically generated class by FairyGUI. Please do not modify it. **/
    
    /** ============================================================================== **/
    /** ============================Auto Generate Class=============================== **/
    /** ============================================================================== **/
    
    using FairyGUI;
    using FUIFW;
    
    namespace HotfixUI
    {
        public partial class UI_ThisIsExample : FUIBase
        {   
                
            public GList m_list_Labels;
            public GGraph m_graph_Mask;
            public GTextField m_text_Exa;
            public FUI_Clone m_clone_Test;
            public FUI_Label1 m_label_t;
    
            public void Init(GObject go)
            {
                if(go == null)
                {
                    return;
                }
                
                var com = go.asCom;
                    
                if(com != null)
                {   
                    
                    m_list_Labels = (GList)com.GetChildAt(0);
                    m_graph_Mask = (GGraph)com.GetChildAt(1);
                    m_text_Exa = (GTextField)com.GetChildAt(2);
                    m_clone_Test = new FUI_Clone(com.GetChildAt(3));
                    m_label_t = new FUI_Label1(com.GetChildAt(4));
                }
            }
    
            public class FUI_Label1
            {   
                        
                public GTextField m_title;
    
                public FUI_Label1(GObject go)
                {
                    if(go == null)
                    {
                        return;
                    }
                    
                    var com = go.asCom;
                        
                    if(com != null)
                    {   
                        
                        m_title = (GTextField)com.GetChildAt(0);
                    }
                }
            }
    
            public class FUI_Button1
            {   
                        
                public Controller m_button;
                public GGraph m_n0;
                public GGraph m_n1;
                public GGraph m_n2;
    
                public FUI_Button1(GObject go)
                {
                    if(go == null)
                    {
                        return;
                    }
                    
                    var com = go.asCom;
                        
                    if(com != null)
                    {   
                        
                        m_button = com.GetControllerAt(0);
                        m_n0 = (GGraph)com.GetChildAt(0);
                        m_n1 = (GGraph)com.GetChildAt(1);
                        m_n2 = (GGraph)com.GetChildAt(2);
                    }
                }
            }
    
            public class FUI_Clone
            {   
                        
                public GTextField m_text_Content;
    
                public FUI_Clone(GObject go)
                {
                    if(go == null)
                    {
                        return;
                    }
                    
                    var com = go.asCom;
                        
                    if(com != null)
                    {   
                        
                        m_text_Content = (GTextField)com.GetChildAt(0);
                    }
                }
            }
    
        }
    }
    

    相关文章

      网友评论

          本文标题:【FGUI】自动生成UI控件代码,lua写的插件

          本文链接:https://www.haomeiwen.com/subject/mludyrtx.html