2009-05-08 17 views
10

Sono lo sviluppatore principale per Bitfighter e sto aggiungendo bot con script utente utilizzando Lua. Sto lavorando con C++ e Lua usando Lunar per incollarli insieme.Come posso passare un elenco di oggetti da C++ a Lua?

Sto provando a fare qualcosa che penso dovrebbe essere piuttosto semplice: ho un oggetto C++ in Lua (bot nel codice qui sotto), e chiamo un metodo su di esso che (findItems) fa sì che C++ cerchi l'area attorno al robot e restituisce un elenco di oggetti trovati (TestItems e altri non mostrati qui). La mia domanda è semplicemente come posso assemblare e restituire l'elenco degli elementi trovati in C++ e poi scorrere su di loro in Lua?

Fondamentalmente, voglio riempire il < < < < Crea elenco di elementi, restituirlo al lua >>>> blocco di sotto, e apportare le correzioni che possono avere bisogno nel codice Lua per sé, riportato qui di seguito che .

Ho provato a mantenere il codice semplice ma completo. Spero non ci sia troppo qui! Grazie!

C++ intestazione del 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); 
} 

file cpp C++

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 Codice

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

Stai cercando il modo di ottenere lunare per creare una tabella con indici che vanno da 1 a fillVector.size().Nella semplice Lua, ciò sarebbe fatto creando una tabella e aggiungendo gli elementi. Non ne so abbastanza del lunare per dare consigli specifici in quel quadro. – RBerteig

+0

Sì, è assolutamente giusto, ed è lì che sono bloccato. Posso aggiungere più elementi numerici a una tabella, ma non so come aggiungere più elementi di dati utente. – Watusimoto

+0

bot = LuaRobot (Robot) - Questo è un riferimento al nostro bot --- PER FAVORE, come lo fai, come ottieni un riferimento al tuo robot creato in C++ ?? Ho provato a creare un metodo getCurrent (luastate *) lunar :: push (this) ma non funziona..Per favore .. – Icebone1000

risposta

7

Quindi, è necessario compilare un vettore e p quello a Lua. Segue un codice di esempio. Applicazioni è uno std :: lista.

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

Creo una tabella e la compilo con i dati nella mia 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; 
} 

Questo mi lascia con un array in pila. Se fosse tornato a Lua, allora potrei scrivere il seguente:

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

Naturalmente finora, questo solo mi viene un allineamento Lua di stringhe. Per ottenere un array di Lua oggetti abbiamo appena tweak il vostro metodo un po ':

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

Questo funziona perfettamente. Per chiarire agli altri che stanno leggendo questo, il metodo

item->push(L) 

è

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

Incapsulando questo in un metodo, è possibile rendere i findItems agnostica per quello che sta trovando.

Grazie per l'aiuto!

+1

Wow - è possibile essere un utente completamente diverso su un altro computer con lo stesso nome utente! Chi lo sapeva? – Watusimoto

Problemi correlati