Как передать список объектов из C ++ в Lua? - PullRequest
12 голосов
/ 08 мая 2009

Я ведущий разработчик для Bitfighter , и я добавляю ботов по сценарию пользователя, используя Lua. Я работаю с C ++ и Lua, используя Lunar, чтобы склеить их вместе.

Я пытаюсь сделать что-то, что, на мой взгляд, должно быть довольно простым: у меня есть объект C ++ в Lua (бот в коде ниже), и я вызываю метод, который (findItems) заставляет C ++ искать в область вокруг робота и вернуть список объектов, которые он находит (TestItems и другие, не показанные здесь). Мой вопрос состоит в том, как просто собрать и вернуть список найденных элементов в C ++, а затем перебрать их в Lua?

По сути, я хочу заполнить <<<< Создать список элементов, вернуть его в блок lua ​​>>>> ниже и внести любые исправления, которые могут понадобиться в самом коде Lua, включены ниже этого.

Я пытался сделать код простым, но полным. Надеюсь, здесь не так уж много! Спасибо!

Заголовочный файл C ++

class TestItem : public LuaObject
{

public:
   TestItem();     // C++ constructor

   ///// Lua Interface

   TestItem(lua_State *L) { } ;             //  Lua constructor

   static const char className[];
   static Lunar<TestItem>::RegType methods[];

   S32 getClassID(lua_State *L) { return returnInt(L, TestItemType); }
};


class LuaRobot : public Robot
{
   LuaRobot();     // C++ constructor

   ///// Lua Interface

   LuaRobot(lua_State *L) { } ;             //  Lua constructor

   static const char className[];
   static Lunar<LuaRobot>::RegType methods[];

   S32 findItems(lua_State *L);
}

C ++ .cpp файл

const char LuaRobot::className[] = "Robot";      // Class name in Lua
// Define the methods we will expose to Lua
Lunar<LuaRobot>::RegType LuaRobot::methods[] =
{
   method(LuaRobot, findItems),
   {0,0}    // End method list
};


S32 LuaRobot::findItems(lua_State *L)
{
   range = getIntFromStack(L, 1);    // Pop range from the stack
   thisRobot->findObjects(fillVector, range);  // Put items in fillVector

   <<<< Create list of items, return it to lua >>>>

   for(int i=0; i < fillVector.size(); i++)
      do something(fillVector[i]);    // Do... what, exactly?

   return something;
}


/////
const char TestItem::className[] = "TestItem";      // Class name in Lua

// Define the methods we will expose to Lua
Lunar<TestItem>::RegType TestItem::methods[] =
{
   // Standard gameItem methods
   method(TestItem, getClassID),
   {0,0}    // End method list
};

Код Lua

bot = LuaRobot( Robot ) -- This is a reference to our bot

range = 10
items = bot:findItems( range )

for i, v in ipairs( items ) do
    print( "Item Type: " .. v:getClassID() )
end

Ответы [ 2 ]

9 голосов
/ 08 мая 2009

Итак, вам нужно заполнить вектор и передать его Луа. Ниже приведен пример кода. Приложения - это std :: list .

typedef std::list<std::string> Applications;

Я создаю таблицу и заполняю ее данными в моем списке.

int ReturnArray(lua_State* L) {
    lua_createtable(L, applications.size(), 0);
    int newTable = lua_gettop(L);
    int index = 1;
    Applications::const_iterator iter = applications.begin();
    while(iter != applications.end()) {
        lua_pushstring(L, (*iter).c_str());
        lua_rawseti(L, newTable, index);
        ++iter;
        ++index;
    }
    return 1;
}

Это оставляет меня с массивом в стеке. Если бы он был возвращен Луа, я мог бы написать следующее:

for k,v in ipairs( ReturnArray() ) do
    print(v)
end

Конечно, до сих пор, я получаю массив Lua из строк . Чтобы получить массив объектов Lua , мы просто немного подправим ваш метод:

S32 LuaRobot::findItems(lua_State *L)
{
    range = getIntFromStack(L, 1);    // Pop range from the stack
    thisRobot->findObjects(fillVector, range);  // Put items in fillVector

    // <<<< Create list of items, return it to lua >>>>

    lua_createtable(L, fillVector.size(), 0);
    int newTable = lua_gettop(L);
    for(int i=0; i < fillVector.size(); i++) {
        TestItem* item = fillVector[i];
        item->push(L);  // put an object, not a string, in Lua array
        lua_rawseti(L, newTable, i + 1);
    }
    return 1;
}
1 голос
/ 12 мая 2009

Это работает отлично. Чтобы уточнить другим, кто читает это, метод

item->push(L)

есть

void push(lua_State *L) {  Lunar<TestItem>::push(L, this); }

Инкапсулируя это в методе, можно сделать findItems независимым от того, что он находит.

Спасибо за помощь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...