關於lua 5.3 服務端熱更新流程


 

腳本的熱更新的流程都大同小異, 第一步先保存舊代碼的塊的數據, 第二部加載新的代碼塊,第三步將舊代碼塊的局部和全局數據拷貝到新代碼塊的對應的

變量中。

在服務器熱更新中,主要考慮熱更的內容是什么, 一般更新分兩種,一種是邏輯的更新,一種是變量的值更新。

 

先談論第一種,在lua 5.3中,繼承了新的debug.upvaluejoin(f1, i, f2, j)函數,能將函數f1的第i個個upvalue引用f2的第j個upvalue, 

可以通過debug.getupvalue函數,獲取ENV 的upvalue來的索引位置,找到該位置后,可以通過debug.upvaluejoin函數來實現env的交換。

 

第二種就是要更新變量值,lua中的變量值更新,除了table外,其它變量類型都可以通過直接賦值來改變值的大小。由於table的回收,會導致其它引用

該table的變量都會收到影響,會導致錯誤的發生,所以, table的值更新,不能通過直接賦值, 可以通過移除table里面的所有元素的值,table的table除外,

然后將新table的所有元素的值遍歷賦值給舊的table,注意的是不能將table也賦值,如果新table里有新的子元素是table類型,必須要在舊table對應值里重新

創建一個新的table,遞歸將值拷貝。

以下是table的拷貝方法實現熱更的過程:

HotFixTable = {}

-- copy a old table's all key and value  to new table, but don't release old table
local function copyTable( oldTbl, newTbl)
    for k, v in pairs(newTbl) do
        if type(v) == "table" then
            if type(oldTbl[k]) ~= "table" then
                oldTbl[k] = {}
            end
            copyTable( oldTbl[k], v)
        else
            oldTbl[k] = v
        end
    end
    return oldTbl, newTbl    
end

--table no need release
local function clearTable(tbl)
    for k, v in pairs(tbl) do
        if type(v) ~= "table" then
            tbl[k] = nil
        else
            clearTable(v)
        end
    end

    return tbl
end

--use file to hotfix the source table
function HotFixTable.hotFixByFileName(fileName, sourceTbl)
    local deskTbl
    local function newIndexFunc(tbl, name, value)--t:table, name:key, f:function
        deskTbl = value
    end

    local dummy_env = setmetatable({}, { __newindex = newIndexFunc })
    local f, err = loadfile(fileName, "bt", dummy_env)
    if f then
        local ok, err = pcall(f)
        assert(ok, err)
        if ok then
            clearTable(sourceTbl)
            copyTable(sourceTbl, deskTbl)
        end
    end
end

--use lua string to hotfix the table
function HotFixTable.hotFixByData(hitfixContent, sourceTbl)
    local deskTbl
    local function newIndexFunc(tbl, name, value)--t:table, name:key, f:function
        deskTbl = value
    end

    local dummy_env = setmetatable({}, { __newindex = newIndexFunc })
    local f, err = load(hitfixContent, "=patch", "bt", dummy_env)
    if f then
        local ok, err = pcall(f)
        assert(ok, err)
        if ok then
            clearTable(sourceTbl)
            copyTable(sourceTbl, deskTbl)
        end
    end
end

調用方法如下:

HotFixTable.hotFixByFileName("新table的保存所在文件", 舊table)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM