XLua運転時の熱更新原理と実現


Lua熱更新原理と実現

  • 前言
  • 基本知識
  • 最も基本的な熱更新方式(使用不可)
  • __G
  • 完全熱更新方法
  • Xlua熱更新案
  • 前言


    2つのブログの主に感謝します.以下はブログのアドレスです.https://gameinstitute.qq.com/community/detail/120538 https://www.jianshu.com/p/7b8ae23ecd81

    基本的な知識


    私たちはrequireのLuaファイルをロードするときにLuaファイルをpackageにロードします.loaded[modelname]にあります.モジュールをロードするときはpackageから先にloadedで読み込み、ファイルが存在しない場合はLoadファイルをロードします.

    最も基本的なホット・アップデートの方法(使用不可)

  • 第1のロード方式はpackage.loaded[modelname]の値をnilに設定し、強制再ロード:
  • function reload_module(module_name)
       package.loaded[modulename] = nil
       require(modulename)
    end
    

    上記の操作では、モジュールを直接空に割り当て、再ロードします.このような過程でmodelを再ロードすることができますが、他の参照先は更新できません.そのため、ファイルを参照したすべてのモジュールを見つける必要があります.

    __G


    _Gは関数ではなく変数であり、グローバル環境全体を制御しています.モジュールを参照している他のモジュールを見つける必要があります.ここで構造を見つけることもできます.
    _G
    ├── string: 
    |    ├── sub: function: 006AEB70
    |    ├── upper: function: 006AEBB8
    |    ├── len: function: 006AE290
    |    ├── gfind: function: 006AE170
    |    ├── rep: function: 006AE3F8
    |    ├── find: function: 006ADFC0
    |    ├── match: function: 006AE368
    |    ├── char: function: 006ADEA0
    |    ├── dump: function: 006ADF30
    |    ├── gmatch: function: 006AE170
    |    ├── reverse: function: 006AE440
    |    ├── byte: function: 006ADE10
    |    ├── format: function: 006AE050
    |    ├── gsub: function: 006AE200
    |    └── lower: function: 006AE2D8
    ├── xpcall: function: 006AA630
    ├── package: 
    |    ├── preload: 
    |    |    └── { }
    |    ├── loadlib: function: 006AAD80
    |    ├── loaded: 
    |    |    └── { }
    |    ├── loaders: 
    |    |    ├── 1] function: 006AAEA0
    |    |    ├── 2] function: 006AAEE8
    |    |    ├── 4] function: 006AAF78
    |    |    └── 3] function: 006AAF30
    ...
    
  • _Gはluaが使用するすべてのグローバル関数とグローバル変数を保存し,初期はluaライブラリの関数と変数のみを含む.
  • luaプログラムで定義されたグローバル関数と変数が自動的に_に追加されます.Gでは,局所関数や変数はそうはしない.
  • しかし、ローカル関数をキー値ペアで保存することができます.Gでは、これで私たちは_Gと名前で元のローカル関数にアクセスしました
  • 完全な熱更新方法


    私たちのやり方は、新しいモジュールをロードして、新しいモジュールの中のものを古いモジュールに詰めることです.そうすれば、他の引用箇所が新しいモジュールに引用されます.
    function reload_module(module_name)
       local old_module = _G[module_name]	-- 
       package.loaded[module_name] = nil	-- 
       require (module_name)				-- 
       local new_module = _G[module_name]   -- 
       for k, v in pairs(new_module) do     -- 
           old_module[k] = v					-- 
       end
       package.loaded[module_name] = old_module	-- 。 
    end
    

    Xlua熱更新方式


    上記の手順では、Xlua実行時のホットアップデートは実行できません.XLua自身のメカニズムと関係があるかもしれませんが、直接メソッドを置き換えることはできません.まずメソッドを空に設定してから置き換える必要があります(このプロセスは曲折波が多いので説明しません).私たちの_Gはrequireを直接使用してモジュールを取得することもできます
    function reload_module(module_name)
       local old_module = require (module_name)	-- 
       package.loaded[module_name] = nil	-- 
       require (module_name)				-- 
       local new_module = require (module_name)   -- 
       for k, v in pairs(new_module) do     -- 
      		 old_module[k] = nil					-- 
           old_module[k] = v					-- 
       end
       package.loaded[module_name] = old_module	-- 。 
    end