Lua熱更系統


1.介紹

   使用腳本開發游戲業務邏輯其中一個好處就是代碼可線上熱更,不停機修復bug。而熱更代碼的寫法與需要被熱更的文件的代碼又有着密切的關系,本文介紹一種熱更方法。

 

2.熱更原理

  Lua提供一個叫require的函數,實現文件的加載,require的作用可查看雲風大大的參考手冊說明  http://cloudwu.github.io/lua53doc/manual.html#pdf-require
要熱更一個已經被加載(require)過的模塊,要做兩件事件.

1. 將package.loaded[filename] = nil, 將模塊置空.

2. 重新調用require,require(filename).

如果要熱更的模塊里面所用到的都是全局變量,那么只需要這樣寫:

global_var = global_var

ok,新的模塊內容就會重新被加載進內存了,而且全局變量也成功保留了熱更前的值。

然而每個文件里面只定義全局變量,會破壞模塊的可讀性,試想一下,定義了一個類,但它並沒有成員變量,用到的變量全是全局變量,這是一種怎樣的感受。
所以我們要換一種寫法,模塊既可以有自己的變量,又可以被熱更。

 

3. 實現

  形如一個類既有成員變量,又有成員函數,要實現熱更一個模塊同時又保留其原有變量,我們可以把模塊的變量定義和函數定義分開,分別寫在兩個文件。
目錄如下:

  data目錄: modA.lua; modB.lua; modC.lua

       logic目錄: modA.lua; modB.lua; modC.lua

把模塊的變量定義放在data文件夾,把模塊函數的實現放在logic目錄。

下面是實現:

 

1 -- data.modA
2 local mod = {}
3 -- 這里定義模塊變量
4 mod.players = {}
5 mod.total_online = 0
6 
7 -- 最后記得return這個表
8 return mod

 

 1 -- logic.lua
 2 local mod = require("data.modA")
 3 
 4 -- 定義函數
 5 function mod.login()
 6        -- xxxxxx
 7 end
 8 
 9 function mod.load_data()
10       -- xxxxxxx
11 end

這里只是一個例子,logic.modA想要執行 `require("data.modA")` 成功,還要修改package.path,這個是Lua虛擬機啟動時自己去定義了,這里不做討論。
這里把模塊的變量和函數的定義分離了,我們只熱更function目錄下的文件,data目錄下的則不管。
熱更文件的實現如下:

 

 1 -- require_ex.lua
 2 function require_ex(filename)
 3     local old_content
 4     if package.loaded[filename] then
 5         -- 把舊的模塊保存起來
 6         old = package.loaded[filename]
 7         -- 然后package.loaded[filename]賦空
 8         package.loaded[filename] = nil
 9     end
10          
11      -- xpcall下執行require
12     local ok,err = pcall(require, filename)
13     if not ok then
14         --熱更失敗,將舊值賦回去
15         print("hotfix fail, err msg ",err)
16         package.loaded[filename] = old_content
17         return false
18     end
19 
20     return true
21 end

 

切記: 重新require模塊的時候,必須在pcall下執行,萬一模塊有語法錯誤,require掛掉的話,package.loaded[filename]就會一直為nil。當有其他文件需要執行 require(filename)的時候,則會報錯,后面的邏輯無法執行。


免責聲明!

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



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