lua 熱更新原理 一

2021-09-13 18:25:32 字數 1703 閱讀 1894

**

熱更一般是針對模組的線上替換。我們動態載入要熱更的模組試試。例如,我們在迴圈間隔載入某模組,這樣就能有時間去更改模組了。測試的**如下:

for i = 1, 5 do

local m = require('other')

print('other.a is ', m.a)

sleep(5)

end我們迴圈載入了other這個模組他僅僅返回乙個local table ,在sleep(lua沒有直接提供sleep,我們可以利用os模組自己實現)期間我們改變other模組a的值為101,不出意外,m.a還是100。這是為什麼呢?

這是由於require快取機制決定的,請參考lua require機制

要想打破require快取機制,我們必須刪除快取,package.loaded[module_name] = nil就可以做到。

我們將package.loaded['other'] = nil加在第四行後,再改變a的值,不出意外,a的值被改變了。

還有乙個問題就是,之前的舊資料可能被其他變數引用,所以舊資料仍然有可能存在,例如下面的**:

local g = {}

for i = 1, 5 do

local m = require('other')

if (i == 1) then g = m end

print('other.a is ', m.a)

sleep(5)

package.loaded['other'] = nil

end由於g第一次引用的是舊資料,最後列印g.a時還是100,而不是修改之後的值。我們畫個示意圖就能很好的說明問題:

左邊是lua全域性表package.loaded,require模組就會填入其中。再次require時我們發現他已經指向另乙個表了,而g仍然指向之前的表資料。

怎麼才能讓g指向新的表資料,直接讓g指向他不行嗎?不太可行,因為在實際的專案中不太確定有哪些變數引用到了舊的資料,就算知道,那也是侵入式的修改了。另一種方法就是package.loaded仍引用舊的資料表,只不過與新的資料表交換資料。還是畫個示意圖:

有了上面的描述,相信**實現很簡單:

function reload_module(module_name)

local old_module = package.loaded[module_name] or {}

package.loaded[module_name] = nil

require (module_name)

local new_module = package.loaded[module_name]

for k, v in pairs(new_module) do

old_module[k] = v

endpackage.loaded[module_name] = old_module

return old_module

end以上有個問題就是模組返回的最好是表資料,這樣才能替換已經引用到的舊資料,例如g。

還有,如果要熱更的模組中有全域性變數,熱更模組時修改了全域性變數,那麼在_g['other']指向的值也會被覆蓋,這沒什麼問題,本來全域性變數就應該被覆蓋才對。但是在熱更之前如果有變數指向這個全域性變數就糟糕了,這個變數也應該被修改才對。所以類似上面的交換新舊package.loaded['other']資料,全域性資料也應該交換才對。可惜的是,沒有辦法知道全域性變數來自哪個模組,所以無法做到替換該模組的全域性變數。不知道大佬們有沒有辦法。

Lua熱更新原理及示例

網上有不少lua熱更新的文章,都只說了理論,被沒有給出實際可操作的 下面是我寫的幾個例子。lua的require modelname 把乙個lua檔案載入存放到package.loaded modelname 當我們載入乙個模組的時候,會先判斷是否在package.loaded中已存在,若存在則返回...

lua 熱更新模組

最近準備在手機專案客戶端中使用lua,以前一直在伺服器使用luabind.另外,tolua 也體驗過,luaplus也在早年用過.以下是本人對這些繫結庫的個人感覺 luabind 利用boost機制把繫結做到極致,比較適合主c 弱lua的指令碼框架.作者已經停止更新,在windows linux編譯...

使用LUA 熱更新模組

最近準備在手機專案客戶端中使用lua,以前一直在伺服器使用luabind.另外,tolua 也體驗過,luaplus也在早年用過.以下是本人對這些繫結庫的個人感覺 luabind 利用boost機制把繫結做到極致,比較適合主c 弱lua的指令碼框架.作者已經停止更新,在windows linux編譯...