Equivalent de Lua coroutine.create en C ++ en utilisant lua_newthread

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:

  • extraire le luaFunc
  • puis appuyez sur la fonction coroutine.create
  • puis repoussez le luaFunc sur
  • et utilisez 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.