I'm the lead dev for Bitfighter, and am adding user-scripted bots using Lua. I'm working with C++ and Lua using Lunar to glue them together.
I'm trying to do something that I think should be pretty simple: I have an C++ object in Lua (bot in the code below), and I call a method on it that (findItems) which causes C++ to search the area around the robot and return a list of objects it finds (TestItems and others not shown here). My question is simply how do I assemble and return the list of found items in C++, and then iterate over them in Lua?
Basically, I want to fill in the <<<< Create list of items, return it to lua >>>> block below, and make any corrections I may need in the Lua code itself, included below that.
I've tried to keep the code simple but complete. Hope there's not too much here! Thanks!
C++ Header file
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 file
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 Code
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
So you need to fill a vector and push that to Lua. Some example code follows. Applications is a std::list.
typedef std::list<std::string> Applications;
I create a table and fill it with the data in my list.
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;
}
This leaves me with an array in the stack. If it were returned to Lua, then I could write the following:
for k,v in ipairs( ReturnArray() ) do
print(v)
end
Of course so far, this just gets me a Lua array of strings. To get an array of Lua objects we just tweak your method a bit:
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With