2009-05-08 11 views
10

Soy el desarrollador principal de Bitfighter, y estoy agregando bots con scripts de usuario utilizando Lua. Estoy trabajando con C++ y Lua usando Lunar para unirlos.¿Cómo paso una lista de objetos de C++ a Lua?

Estoy tratando de hacer algo que creo que debería ser bastante simple: tengo un objeto C++ en Lua (bot en el código a continuación), y llamo a un método que (findItems) hace que C++ busque el área alrededor del robot y devolver una lista de los objetos que encuentra (TestItems y otros que no se muestran aquí). Mi pregunta es, ¿cómo puedo armar y devolver la lista de elementos encontrados en C++, y luego repetir sobre ellos en Lua?

Básicamente, quiero llenar el < < < < Crear una lista de artículos, devuélvalo a lua >>>> bloque de abajo, y hacer las correcciones que pueden necesitar en el propio código Lua, que se incluye a continuación .

He intentado mantener el código simple pero completo. Espero que no haya mucho aquí! ¡Gracias!

C++ Header presentar

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); 
} 

archivo 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 
}; 

Código 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 
+0

Está buscando la forma de obtener lunar para crear una tabla con índices que vayan de 1 a fillVector.size().En Lua, eso se haría creando una tabla y agregando los elementos. No sé lo suficiente sobre lunar para dar consejos específicos en ese marco. – RBerteig

+0

Sí, eso es absolutamente correcto, y ahí es donde estoy atascado. Puedo agregar varios elementos numéricos a una tabla, pero no sé cómo agregar varios elementos de datos de usuario. – Watusimoto

+0

bot = LuaRobot (Robot) - Esta es una referencia a nuestro bot --- POR FAVOR, cómo lo haces, ¿cómo consigues una referencia a tu robot creado en C++? Intenté crear un método getCurrent (luastate *) lunar :: push (esto) pero no funciona ... Te lo ruego .. – Icebone1000

Respuesta

7

por lo que necesita para llenar un vector yp ush eso a Lua. A continuación se muestra un ejemplo de código. Aplicaciones es un std :: list.

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

Creo una tabla y la lleno con los datos de mi lista.

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; 
} 

Esto me deja con una matriz en la pila. Si se vuelve a Lua, entonces yo podría escribir lo siguiente:

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

supuesto hasta ahora, esto sólo me consigue una matriz de Lua cuerdas. Para obtener una gran variedad de objetos Lua que acabamos de ajustar su método un poco:

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

Esto funciona perfectamente. Para aclarar a los demás que están leyendo esto, el método

item->push(L) 

es

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

Al encapsular esto en un método, es posible hacer que las findItems agnóstico a lo que se trata de encontrar.

¡Gracias por la ayuda!

+1

Wow - ¡es posible ser un usuario totalmente diferente en una computadora diferente con el mismo nombre de usuario! ¿Quien sabe? – Watusimoto

Cuestiones relacionadas