美文网首页
Unity tolua#/ulua/lua基础类

Unity tolua#/ulua/lua基础类

作者: unlockc | 来源:发表于2021-02-21 10:49 被阅读0次

问题引出

  • 有些Lua项目,为了解决循环强引用无法释放类(table),需要程序员手动回收内存Delete类,这是在开历史倒退车。
  • 出现循环强引用时,只需要使用Weak Table(http://www.lua.org/manual/5.1/manual.html#2.10.2)来规避。这样就可以无障碍地使用此文章下面提到的基础类,无需手动回收内存Delete类,面向对象开发lua

目录结构

Base/BaseClass.lua
Base/Example/Parent.lua
Base/Example/Child.lua
Base/Example/Grandson.lua

类的详细代码

BaseClass.lua

--Lua5.1 __gc方法(Lua5.2开始才支持直接设置__gc)
function setmt__gc(t, mt)
  local prox = newproxy(true)
  getmetatable(prox).__gc = function() mt.__gc(t) end
  t[prox] = true
  return setmetatable(t, mt)
end

--输出日志--
function log(...)
    print(...)
end

--错误日志--
function logError(...) 
    print(...)
end

--警告日志--
function logWarn(...) 
    print(...)
end

local _class = {}
function class(base)
    
        local class_type = {}
        
        local vtbl = {} -- construct virtual table
        _class[class_type] = vtbl
        setmetatable(class_type, {__newindex=
            function(t, k, v)
                vtbl[k] = v
                --rawset(t, k, v) -- add by Dream^2
            end,
            __index = function (t, k)
                return vtbl[k]
            end})
            
        class_type.ctor = false
        class_type.base = base
        
        --class_type.new = function (...) --Comment by liboxiang
        function class_type:new (...)  -- Add by liboxiang 
                local obj = {}


                --Lua5.1 __gc方法
                setmt__gc(obj, {__gc=function(target) 
                    logWarn("__gc函数执行")
                    do
                        local decreate -- a function use for recursion to base class
                        
                        decreate = function(c)
                            if c.dtor then
                                c.dtor(target) 
                            end

                            if c.base then
                                decreate(c.base)
                            end
                        end
                        
                        decreate(class_type)
                    end

                end})

                --為了可以在 class:ctor()函數里 ,可以冒號調用self:func(),放到這裡來
               -- setmetatable(obj, {__index=vtbl})
                getmetatable(obj).__index = vtbl

                do
                    local create -- a function use for recursion to base class
                    
                    create = function(c, ...)
                        if c.base then
                            create(c.base, ...)
                        end
                        if c.ctor then
                            c.ctor(obj, ...) 
                        end

                    end
                    
                    create(class_type, ...)
                end

                return obj
        end
        

            
        if base then
                setmetatable(vtbl, {__index = 
                    function(t, k)
                        --print("--" .. tostring(t) .. " k:" .. tostring(k))
                        local ret=_class[base][k] --为了追溯父类的成员
                        vtbl[k]=ret
                        return ret
                    end})
        end
        
        return class_type
end

Parent.lua


Parent = class()
function Parent:ctor( ... )
    logWarn("Parent:ctor( ... )")
end

function Parent:dtor( )
    logWarn("Parent:dtor()")
end

Child.lua


require "Base/Example/Parent"
Child = class(Parent)

function Child:ctor( ... )
    logWarn("Child:ctor( ... )")
end

function Child:print()
    logWarn("Child:print()")
end

function Child:dtor( )
    logWarn("Child:dtor()")
end

Grandson.lua


require "Base/Example/Child"
Grandson = class(Child)

function Grandson:ctor( name )
    logWarn("Grandson:ctor(name=" .. name .. ")")
end

function Grandson:print()
    logWarn("Grandson:print()")
    Grandson.base.print(self)
end

function Grandson:dtor( )
    logWarn("Grandson:dtor()")
end

使用例子

    logError("BaseClass 例子开始")
    require "Base/BaseClass"
    require "Base/Example/Grandson"
    local grandson = Grandson:new("Tom")
    grandson:print()
    grandson = nil
    collectgarbage("collect") -- 强制垃圾回收
    logError("BaseClass 例子结束")

--输出日志如下:
--BaseClass 例子开始
--Parent:ctor( ... )
--Child:ctor( ... )
--Grandson:ctor(name=Tom)
--Grandson:print()
--Child:print()
--__gc函数执行
--Grandson:dtor()
--Child:dtor()
--Parent:dtor()
--BaseClass 例子结束

Unity例子工程链接

链接:https://pan.baidu.com/s/1Sv32_q_cvk7HU79Bvd-h5w
提取码:c6q8
例子场景为:Assets\LuaFramework\Scenes\main.unity

联系邮箱

chasing2moro@qq.com

相关文章

网友评论

      本文标题:Unity tolua#/ulua/lua基础类

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