2010-04-20 87 views
4

我對Lua相當陌生,我一直在努力實現Lua腳本編寫邏輯,我將它放在一個遊戲引擎中。到目前爲止,我沒有遇到任何麻煩讓Lua通過引擎運行,我可以從Lua的C和C函數調用Lua函數。我將如何去與Lua共享C++類中的變量?

現在引擎工作的方式,每個Object類都包含一組變量,引擎可以快速迭代以繪製或處理物理過程。雖然遊戲對象都需要訪問和操作這些變量,以便遊戲引擎本身能夠看到任何變化,但他們可以自由創建自己的變量,Lua對此非常靈活,所以我不擔心任何問題。無論如何,目前遊戲引擎方面的東西都坐在C陸地上,我真的希望他們呆在那裏,因爲性能方面的原因。所以在一個理想的世界裏,當產生一個新的遊戲對象時,我需要能夠讓Lua讀/寫這個標準變量集作爲Lua對象基類的一部分,然後它的遊戲邏輯可以繼續狂奔着。到目前爲止,我保留了兩個獨立的對象表 - Lua生成一個新的遊戲對象,它將自身添加到一個數字索引的全局對象表中,然後繼續調用C++函數,該函數創建一個新的GameObject類,並在類中註冊Lua索引(一個int)。到目前爲止,C++函數現在可以看到Lua對象,並輕鬆地使用dostring在Lua land中執行操作或調用函數。

我現在需要做的是將C++變量作爲GameObject類的一部分,並將它們暴露給Lua,這就是Google讓我失敗的原因。我遇到了一個非常好的方法here,它詳細介紹了使用標籤的過程,但是我已經讀過這種方法已被棄用,以支持metatables。

完成此操作的理想方法是什麼?學習如何使用libBind或一些等價的方法傳遞類定義是否值得學習,或者是否有一種簡單的方法,我可以將全局lua對象註冊到每個變量(一次,在產卵時)?從Lua 5.1.4開始,什麼是「當前」最好的方法呢?

回答

4

一種方法是使用

  • 一個lightuserdata指向C++可變
  • C函數使用lightuserdata
  • 訪問C++變量保持lightuserdata作爲C的函數的的upvalue所以一個函數滿足所有變量
  • 使用函數的參數數量來獲取和設置變量之間進行選擇

例如:

int game_state_var_accessor (lua_State *L) 
{ 
    int *p = lua_topointer(L, lua_upvalueindex(1)); 
    if (lua_gettop(L) == 0) 
    { // stack empty, so get 
     lua_pushinteger(L, *p); 
     return 1; 
    } 
    else 
    { // arg provided, so set 
     *p = lua_tointeger(L,1); 
     return 0; 
    } 
} 

當你犯了一個新的遊戲狀態就可以使用創建每個變量的訪問器:

lua_pushlightuserdata(L, (int *)p); // where p points to your variable 
lua_pushcclosure(L, game_state_var_accessor, 1); 

現在的訪問是在棧上,並可以綁定到一個全局名稱或Lua類中方法的名稱。如果你的Lua類表是在棧上的索引t這將是:

lua_setfield(L, t, "name_of_accessor"); 
+0

問:你投的指針,P,與(int *),但在文檔中lua_pushlightuserdata接受(無效*)。除了代碼可讀性以外,是否有任何好處以這種方式投射?我想我會需要爲不同類型的變量創建單獨的包裝函數,它似乎有點奇怪。 – 2010-04-24 06:05:23

+0

演員只在那裏突出顯示與返回類型game_state_var_accessor的對應關係;換句話說,爲了可讀性。如果您正在爲其他類型的包裝器進行製作,則可以將其重命名爲game_state_int_accessor以保持完整。 – 2010-04-24 13:40:24

+0

這個解決方案工作得很好。非常感謝!是的,我結束了使用不同的粘合劑功能,因爲每個需要一個不同的處理函數。 我還在這裏學習,但Lua的通信API是*純粹的天才*,我很喜歡它。^_^ – 2010-04-29 18:24:16