Si tu veux faire des vrais threads avec une vraie pile, le plus simple est de recopier la pile du thread dans une grosse pile temporaire, puis de recopier juste qu'il faut quand on veut passer au thread suivant ^^
Pour la deuxième idée, c'est simplement qu'au lieu d'avoir une quête dans un thread spécial qui appellerait une fonction d'attente style wait(), on fait en sorte que la quête retourne tout de suite en disant ce qu'elle attend : ensuite on mémorise 1) la condition qu'elle attend (en l'occurrence, que le pont soit détruit), et 2) ce qu'il faudra faire quand cette condition sera remplie (en l'occurrence, passer à la fonction CodePontDetruit()). Ca nous donne une liste de paires (condition,fonction= qu'on peut appeler "listeners". Ensuite signal(bidule) se contente de regarder quelle conditions de "listeners" correspondent à "bidule", et exécuter les fonctions correspondantes. Et quand chacune de ces fonctions se termine, on ajoute sa valeur de retour à "listeners".
Exemple :
1. listeners = []
2. on initialise la quête du pont en appelant AttendrePontDétruit() et en rajoutant sa valeur de retour à listeners
3. listeners = [(map[mypont.pos].is_destroyed,CodePontDétruit)]
4. le joueur joue, gnagnagna : arrive un moment où ParlerAuPerso() est appelée
5. du coup signal(map[mypont.pos].is_destroyed) recherche map[mypont.pos].is_destroyed dans listeners, le trouve, et trouve que la fonction correspondante est CodePontDétruit(); et on efface cet élément de listeners (qui devient donc vide)
6. CodePontDétruit() est exécutée, et comme elle renvoie NULL, listeners est inchangé
7. listeners = []
Evidemment tu peux faire en sorte que ça soit bien plus général que des quêtes, par exemple :
listeners = [(keys[KEY_LEFT].pressed,BougerPerso), (keys[KEY_ENTER].pressed,Parler), (objects[UNTEL].discussion,ParlerAvecUntel), (map[mypont.pos].is_destroyed,CodePontDétruit)]