Domanda

Sto avendo qualche difficoltà a capire come utilizzare coroutines correttamente con luabind.C'è una funzione basato su modelli:

template<class Ret> 
Ret resume_function(object const& obj, ...)

Dove (Ret) dovrebbe contenere i valori passati al yield da Lua.

Il mio attuale punti di confusione, sono:

  • Cosa succede se la funzione restituisce invece di chiamare yield?Non resume_function restituire il valore restituito dalla funzione?
  • Come fare per utilizzare questa funzione se non si sa in anticipo quale (o quanti) i parametri sono trasferiti a yield?Per esempio, se ci sono molteplici possibilità di cedere le funzioni che la funzione chiamata.
  • Qual è il tipo di Ret se sono di più i valori sono passato a yield?

Io sono del tutto erroneo come tutto questo funziona?Mi immagino qualcosa di simile a questo.Il Lua lato:

local img = loadImage("foo.png")

loadImage sarebbe una funzione C++ che richiede il caricamento dell'immagine in un altro thread e poi chiama lua_yield, e qualche tempo dopo luabind::resume_function viene chiamato con img come parametro.

Devo passare "foo.png" per yield come parametro?Per una funzione diversa prima di chiamare yield, e quindi non passano mai di valori da yield?Qual è il modo giusto per la struttura di questo?Ovviamente sto fraintendimento qualcosa qui.

È stato utile?

Soluzione

Dove (Ret) deve contenere i valori passati alla resa da Lua.

Luabind supporta solo i valori di ritorno, in modo che solo restituisce il primo valore passato coroutine.yield.

Cosa succede se la funzione restituisce piuttosto che chiamare la resa?Non resume_function restituire il valore restituito dalla funzione?

Sì, si ottiene il valore di ritorno.

Come fare per utilizzare questa funzione se non si sa in anticipo quale (o quanti) i parametri sono trasferiti alla resa?Per esempio, se ci sono molteplici possibilità di cedere le funzioni che la funzione chiamata.

Che a voi;sono le funzioni.È necessario sviluppare convenzioni su ciò che il cedimento funzione(s) riceve come parametri, e che la funzione di riprendere la coroutine fornisce.

Qual è il tipo di Ret se più valori vengono passati alla resa?

Quello che si desidera essere.È il parametro di modello.Il numero di parametri a una funzione non ha alcun effetto sul ritorno dei valori che la funzione fornisce.

Ricordate:Funzioni Lua prendere qualsiasi numero di parametri e può restituire nulla.Tutti Luabind può fare è passare lungo i parametri di dare e di convertire il valore restituito dalle funzioni Lua in quello che ci si aspetta che il valore di ritorno di essere.Luabind farà tipo di controllo sul valore di ritorno di corso.Ma è la vostra responsabilità di assicurarsi che le funzioni di rendimento/ritorno restituirà qualcosa che è trasformabile per il tipo di utente fornisce per Ret.

loadImage sarebbe una funzione C++ che richiede il caricamento dell'immagine in un altro thread e quindi chiama lua_yield, e qualche tempo dopo luabind::resume_function viene chiamato con img come parametro.

Se si utilizza Luabind non chiamare mai lua_yield direttamente.Il modo corretto per cedere in Luabind è quello di aggiungere un attributo di una funzione di registrazione che sarà resa ogni volta che viene restituito dalla funzione.La sintassi è la seguente:

module(L)
[
    def("do_thing_that_takes_time", &do_thing_that_takes_time, yield)
];

Che è una funzione C++ che rese necessario sempre la resa.Questa è una limitazione di Luabind, come con regolare Lua, è possibile scegliere se cedere o meno come si vede in forma.

Non dimenticate, inoltre, che Lua coroutines non sono la stessa cosa come reale thread.Non sono di prelazione;essi solo eseguire quando lo si dica esplicitamente per coroutine.resume o l'equivalente di riprendere la chiamata.

Inoltre, si dovrebbe mai eseguire la stessa Lua istanza da più di C/C++ thread;Lua non è thread-safe, all'interno della stessa istanza (che più o meno significa che la stessa lua_State oggetto).

Quello che sembri voler fare è di avere Lua chiamare qualche funzione in C++ che di per sé genera un thread per fare un po di processo, quindi il codice Lua attendere che il thread è completa e quindi riceve la sua risposta.

Per fare questo, è necessario dare il Lua script di un oggetto che rappresenta il C++ thread.Così il vostro loadImage la funzione non dovrebbe essere utilizzando coroutine logica;dovrebbe restituire un oggetto che rappresenta il C++ thread.Lua script può chiedere l'oggetto se non è stata completata, e se si dispone, è in grado di interrogare i dati da esso.

Il luogo in cui coroutines può entrare in gioco qui è se non si desidera che il Lua script di aspettare fino a quando questo è finito.Che è, si chiama il Lua script ogni tanto, ma se il C++ thread non è fatto, allora si dovrebbe solo tornare.In questo caso, si può fare qualcosa di simile a questo:

function loadImageAsCoroutine(imageFilename)
    local cppThread = cpp.loadImage(imageFilename);

    local function threadFunc(cppThread)
        if(cppThread:isFinished()) then
            local data = cppThread:GetImage();
            return data;
        else
            coroutine.yield();
        end
    end

    local thread = coroutine.create(threadFunc);

    local errors, data = assert(coroutine.resume(thread, cppThread));

    if(coroutine.status(thread) == "dead") then
        return data;
    else
        return thread;
    end
end

Questa funzione restituisce una coroutine o i dati dell'immagine stessa.I chiamanti di questa funzione deve controllare il tipo;se il tipo è "filo", quindi il C++ thread non è ancora finito.In caso contrario, è l'immagine di dati.

I chiamanti di questa funzione è in grado di pompare la coroutine quanto si vuole con un equivalente di coroutine.resume (se è luabind::resume_function o qualsiasi altra cosa).Ogni volta, controllare il valore di ritorno.Sarà nil se il C++ thread non ha ancora finito, e non nil altrimenti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top