探索關於Lua自動繫結系統問題

來源:互聯網
上載者:User

關於Lua自動繫結系統問是本文要介紹的內容,因為遊戲內容增長的速度遠遠超過了以前,所以程式員已經不能夠完全控制所有程式碼為了。他們需要其他遊戲開發人員的協助。指令碼語言在遊戲裡已經被用了幾十年,但是現在的遊戲機更能抓住它們的優點來打打提高玩家的體驗。

本精粹著重說明Lua語言的綁定實現。這門技術能夠讓程式員將它們的C++類暴露給Lua,但不需要瞭解這個系統。這裡介紹的工具不僅能用在C++語言裡,對其他語言也有效。這種設計的核心思想是易用性、效率、記憶體佔用和多線程的設計目標來驅動的。

1、介紹

在本精粹裡介紹的綁定玉虛在Lua指令碼裡建立、訪問和使用C++對象。舉例來說,在一個singleton的類WORLD裡儲存了一個ENTITY類型的實力列表,下面的指令碼就能夠用來設定玩家的生命值。

 
  1. local entity = WORLD:GetEntity("player")  
  2. entity:SetHealth(50) 

在這個例子裡用到的綁定是由如下的聲明定義的。

 
  1. //in.h and class definition  
  2. SCRIPTABLE_DefineClass(WORLD)  
  3. //in.cpp  
  4. SCRIPTABLE_Class(WORLD)  
  5. {  
  6. SCRIPTABLE_ResultMethod1(GetEntity,ENTITY,std::string)  

綁定一個類就這麼簡單。不需要做其他任何步驟,允許程式員把C++類和自己的函數暴露給Lua,就這麼簡單。

2、特性

這個形同的設計目標如下:

低記憶體消耗;

高效率綁定;

支援C++的繼承;

使用方便;

在指令碼與指令碼之間保證線程使用的安全。

3、函數的綁定

Lua需要一個特別借口來綁定函數。被綁定的函數必須是下面代碼裡定義的類型。Lua的綁定是基於堆棧的,lua_State包含了所有傳到那個函數裡去的參數。這些參數必須通過使用堆棧索引號 lua_to*來收集。在這個例子裡,這個函數接受到的第一個參數是字串,第二個參數是數字,傳回值也是數字。關於C函數的綁定,你可以在Lua手冊[Ierusalimschy06]裡找到更多的相關資訊。C函數的綁定是Lua綁定到C/C++的唯一一個方法,也是這個系統的基礎。

 
  1. int bingding_method(lua_State* state)  
  2. {  
  3. const char* some_string;  
  4. double some_number,another_number;  
  5. some_string = lua_tostring(state,1);  
  6. some_number = lua_tonumber(state,2);  
  7. //在這裡可以設定傳回值,或者做點你需要做的事情  
  8. //另外一個數字  
  9. lua_pushnumber(state,another_number);  
  10. return 1;//假如說我們返回1  

4、在Lua裡的物件導向

Lua是使用廣泛的一種程式設計語言,功能也很強大。本精粹介紹了如何把Lua變成一個物件導向的語言。為了協助大家用好這個功能,Lua的作者們定義了一系列的工具來給大家提供文法協助(syntactic sugar)。下面列出我們在本系統裡使用的一個。在這段代碼裡,the_object是一個初始的變數,這段代碼類比了this_call的函數返回。

 
  1. the_object:Test(5)==the_object["Test"]( the_object,5) 

物件導向的方法可以是用這種文法來實現。對象被當做關係數組,用函數名來進行索引,返回的就是你需要調用的函數。Lua裡有一個機制,允許通過使用元表(metatable)來讓任何類型的變數對一個數組進行互動(這事Lua5.1的特性。Lua5.0中只有表和使用者資料對象才有元表)。元表是Lua裡的表,這個表被分配給一個對象,這個對象包含一些特殊的欄位:_index, _newindex等([Ierusalimschy06])。在那些特殊欄位裡設定的函數會根據情況來被調用。當一個對象被訪問時,採取的如果是數組形式的訪問方式,_index就被調用了。下面的代碼說明了如何講一個元表設定到一個對象上。

 
  1. metatable = {}  
  2. metatable._ _index = function(table,key) return key end  
  3. setmetatable(object, metatable)  
  4. test_return = object["Test"] --在元表裡面調用_index函數 

Lua的內建函式類型有數字(double 或者float)、string、table、nil、function(Lua或C)、thread和(輕)使用者資料。我們採用最後一個類型在Lua裡儲存對象。輕使用者資料和使用者資料稍微有點不一樣。第二種完全是Lua對象,可以擁有一個元表。

5、在Lua裡綁定C++對象

綁定需要幾個機制:在Lua重新描述C++對象、綁定函數的儲存,最後是每個C++對象綁定資料的註冊。在本精粹裡,我們先把整體的技術介紹給大家,稍後我們會講解一些特別的例子。

綁定資料結構

在已經存在的現實中,綁定是直接儲存在Lua裡面的,而相關的綁定資料就幫存在每個指令碼裡。但是如果系統必須支援的指令碼數量很大,那麼綁定資料就回不必要的被重複儲存。為了避免這樣的情況發生,我們決定把綁定資料儲存在C++中一個叫SCRIPTABLE_BINDING_DATA的類裡。每個綁定的類都會被分配到一個索引值。

SCRIPTABLE_BINDING_DATA裡包含一個記錄雷鳴和類的索引號的映射,它被儲存在CLassIndexTable裡。然後每個類都有個映射,記錄每個函數名和對應的綁定函數。MethodTable是這種映射的重組,可以根據ClassIndex Table裡的值進行索引。因為delete操作符是沒有名字的,所以它的綁定被存放在單獨的數組裡,這個數組叫做Delete Table。最後,Parent Table儲存了每個類的弗雷的索引。如果某個類是沒有父類的,那麼Parent Table的入口就被設定了 -1

在本書附帶光碟片中,你可以找到一系列的副主函數,這些輔助函數能夠讓你訪問這些映射。你可以在 scriptable_bingding_data.h檔案裡找到它們。

 
  1. class SCRIPTABLE_BINDING_DATA  
  2. {  
  3. typedef int(* BINDING_FUNCTION) (lua_State *);  
  4. std::map<std:string,int> 
  5. ClassIndexTable;  
  6. std::vector<std::map<std::string,BINDING_FUNCTION>*> 
  7. MethodTable;  
  8. std::vector<BINDING_FUNTION> 
  9. DeleteTable;  
  10. std::vector<int>;  
  11. ParentTable;  
  12. }; 

指向這個綁定資料的指標和之歌類的索引被存放在lua_State裡。這個資料的空間是由luaconf.h裡的LUAI_EXTRASPACE常量分配的。

小結:探索關於Lua自動繫結系統問題的內容介紹完了,希望通過本文的學習能對你有所協助!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.