我是Bitfighter的首席开发者,并且正在使用Lua添加用户脚本机器人。我正在使用Lunar将C ++和Lua粘合在一起。
我正在尝试做一些我认为应该非常简单的事情:我在Lua中有一个C ++对象(下面代码中的bot),我在其上调用了一个方法(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 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
答案 0 :(得分:9)
所以你需要填充一个向量并将其推送到Lua。 下面是一些示例代码。 应用程序是 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;
}
这让我在堆栈中有一个数组。如果它被归还给Lua,那么我可以写下以下内容:
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 :(得分:1)
这完美无缺。为了向正在阅读本文的其他人澄清,方法
item->push(L)
是
void push(lua_State *L) { Lunar<TestItem>::push(L, this); }
通过将其封装在方法中,可以使findItems与其发现的内容无关。
感谢您的帮助!