J’ai un système de rappel, qui peut append des fonctions Lua à un gestionnaire C ++, par exemple, je peux le faire
myCObject:AddCallback(luaFunc)
j’ai aussi le même, pour les coroutines
myCObject:AddCallback(coroutine.create(luaFunc))
Je peux alors utiliser
lua_State * pThread = lua_tothread(L, -1); lua_resume(pThread, 0,0);
en C ++
Pour démarrer / reprendre la fonction lua.
Maintenant, je ne veux pas obliger les rédacteurs de script à écrire coroutine.create (luaFunc) – et je veux juste “convertir” automatiquement une fonction en bloc en coroutine. Lorsque AddCallback est appelé, j’ai le luaFunc sur la stack – et comment puis-je procéder? (avec coroutine.create j’ai déjà un thread sur la stack)
EDIT: Je cherche une solution qui utilise l’API C, par exemple, lua_newthread
L’idée est assez simple. Tout d’abord, vous créez un nouveau fil.
lua_State *pThread = lua_newthread(L);
Cette fonction pousse également ce fil sur L
La prochaine étape consiste à obtenir votre fonction de fil sur pThread
. Étant donné que vous avez une fonction Lua sur la stack à ce stade, votre prochaine étape consiste à transférer cette fonction sur la stack pThread
.
Il existe une fonction spécifique pour transférer des valeurs entre les threads: lua_xmove
. Cependant, il ne transfère que les éléments supérieurs de la stack. Vous devez donc copier la fonction Lua de là où elle se trouve sur la stack de L
vers le haut de la stack de L
Ensuite, lua_xmove
dans la nouvelle stack.
lua_pushvalue(L, #); //Where # is the index in the stack where the function is. //Remember that lua_newthread pushed a value on the stack, so compensate for that. lua_xmove(L, pThread, 1); //Moves the function to the top of the new stack.
Rappelez-vous que lua_xmove
déplace la valeur, ce qui la supprime de L
Donc, lua_pushvalue
pousse la valeur et lua_xmove
. Donc, le haut de la stack est encore le lua_State
représenté par pThread
.
Après cela, appuyez sur tous les parameters que vous devez envoyer à la fonction (qui est apparemment zéro) et reprenez-le.
lua_resume(pThread, 0);
Le code total:
lua_State *pThread = lua_newthread(L); lua_pushvalue(L, #); //Where # is the index in the stack where the function is. //Remember that lua_newthread pushed a value on the stack, so compensate for that. lua_xmove(L, pThread, 1); //Moves the function to the top of the new stack. lua_resume(pThread, 0);
Un thread Lua (qu’il soit créé dans Lua ou dans l’API C) est une valeur Lua, tout comme une table, des données utilisateur, une chaîne de caractères, etc. Il est donc sujet à un garbage collection. Il sera collecté lorsque Lua détectera qu’il n’y a plus de références à la valeur.
Rappelez-vous: lua_newthread
pousse le thread sur la stack d’origine. Il vous appartient de le copier dans le registre, dans l’environnement global ou à tout autre endroit où vous souhaitez que ce fil réside en permanence. lua_State
simplement un pointeur sur le lua_State
qu’il a généré ne garantira pas que le thread rest en vie.
Je n’ai pas fait beaucoup de choses depuis longtemps, donc je suis un peu rouillé. Mais je pense que ce que vous voulez faire est:
luaFunc
coroutine.create
luaFunc
sur lua_pcall
pour obtenir votre thread sur la stack. D’après vos commentaires, vous souhaitez utiliser lua_newthread
. Je n’ai aucune expérience avec cela, mais j’ai trouvé cette réponse qui contient un exemple de programme qui l’utilise.