2011年2月22日 星期二

LUA整合(LUA+LUABind+Decoda)

  最近開始做Script的整合,因為本身是WOW的愛好者,所以就直接選擇了LUA。
  剛接觸時,因為除錯及AutoBind的問題困擾了我很久,所以花了一些時間上網找相關資源,於是開啟了LUA+LUABind+Decoda的整合之路。

  先說明一下LUABind的簡單使用法,請參考以下的Sample Code:
//Test.cppclass CMyObject
{
public:
  const bool HitPlayer(void)
  {
    //Hit Player
    return true;
  }
};


class CMyWorld
{
private:
protected:
  map m_mapObjectContainer;
public:
  const bool CreateObject(const string& strName)
  {
   map::iterator it = m_mapObjectContainer.find(strName);
   if(it == m_mapObjectContainer.end())
   {
     CMyObject* pObject = new CMyObject;
     m_mapObjectContainer[strName] = pObject;
     return true;
   }
   return false;
   }
  CMyObject& GetObject(const string& strObjectName)
  {
   map::iterator it = m_mapObjectContainer.find(strObjectName);
   return (*(*it).second);
  }
};
type Loki::SingletonHolder SingletonMyWorld;
main()
{
  SingletonMyWorld::Instance().CreateObject("Player");
  lua_State* pMyLuaState = lua_open();
  if(pMyLuaState)
  {
    luabind::open(pMyLuaState);
    // Export our class and member function with LUABind    luabind::module(pMyLuaState)[
     luabind::class("CMyWorld")
     .def("GetObject", &CMyWorld::GetObject)];
    luabind::module(pMyLuaState)[
     luabind::class_("CMyObject")
     .def("HitPlayer", &CMyObject::HitPlayer)];
    // Assign SingletonMyWorld to a global in LUABind
    luabind::globals(pMyLuaState)["SingletonMyWorld"] =
     SingletonMyWorld::Instance();
    string strData;
    ifstream infile("../MyTest.lua");
    if(infile)
    {
      char TempBuffer[1024];
      while(!infile.eof())
      {
        infile.getline(TempBuffer, 1024);
        strData += TempBuffer;
        strData += '\n';
      }
      infile.close();
    }
    luaL_dostring(pMyLuaState, strData.c_str());
    //Call Lua Function by LUABind    luabind::call_function(pMyLuaState, "ObjectAttack", "Player");
    lua_close(pMyLuaState);
    pMyLuaState = NULL;
  }
}

//MyTest.lua
function ObjectAttack(ObjectName)  local TestValue = 10
  Object = SingletonMyWorld:GetObject(ObjectName)
  Object:HitPlayer()
end
  由以上範例程式可以看出,利用LuaBind可以輕易將物件、成員函式及
Singleton物件跟Lua Bind在一起。
  接下來是Decoda的使用,請看下圖:
1.進入畫面:
2.設定執行專案:3.選好按下ok鍵:
4.進行除錯(選擇單步執行模式):5.單步執行第一次出現的結果:6. 將要觀察的變數加入Watch視窗:
7.依序執行後,可以看到Watch視窗變數值的變化:8.Decoda目前並無法顯示自訂型別的資料結構,一大缺點:結論:


  1. LUABind可以讓我們輕易整合C++的物件函式庫,上手度適中,並可以在LUA最新版本的函式上執行無誤。(其實它包含更多跟Design Pattern相關的功能,很複雜…)
  2. Decoda是一個可以Runtime進行除錯的工具,不過目前沒有支援自訂物件型別,可惜了點,
    但支援Call Stack、Watch Variables…等,跟那只能Check Lua語法的工具比起來,還算不錯

6 則留言:

  1. 我目前也是使用 Lua + Luabind 的組合。只要習慣了 Lua 的語法後,就會對它愛不釋手!

    回覆刪除
  2. 首先謝謝半路大大的留言。
    既然有半路背書,相信這應該是一條正確的路,XD。

    回覆刪除
  3. 前輩... 別叫我大大,承受不起阿。 XD

    Lua 的 auto-bind 函式庫我只用過 Luabind 而已。另外聽說 SWIG 也滿不錯用,但我使用 Luabind 沒遇到什麼問題,所以就一直用下去了。

    回覆刪除
  4. xd,在經營部落格及手機程式設計方面你的確是我的前輩,所以這樣叫是沒問題的XD,謝謝你提供的的資訊(SWIG)。

    回覆刪除
  5. 夢癡,可以跟你交個朋友嗎?我的部落格:akira32 編程之家
    最近我都在研究Windows Phone 7的遊戲程式。

    回覆刪除
  6. ok呀!剛剛有去你的部落格留言了,希望未來能有更多交流的機會。

    回覆刪除