Hello there,
je vais vous parler un peu des Workers récemment implémentés au Flash Player 11.4.
Autant vous le dire tout de suite, vous ne pouvez pas passer à coté de cette nouvelle classe.
Chaque Workers utilise une instance de la machine virtuelle (MV) du player Flash (FP) qui s’exécute en background de votre application.
L’intérêt est donc de faire tourner du code en arrière plan pour alléger la MV principale, celle qui affiche votre application.
Il est bien sûr possible de communiquer entre les différents Workers de différentes manières :
- en envoyant des messages via MessageChannel.send()
- en partageant un ByteArray (BA) (depuis le FP 11.5) dont l’instance sera accessible par tous les Workers.
La méthode du BA est particulièrement puissante puisse qu’il suffit de modifier l’instance du BA
pour que les Workers aient accès aux nouvelles données dans un Event enterframe par exemple.
PROBLÈME : il est possible qu’un Worker cherche à lire ou modifier le BA alors qu’un autre Worker est en train de le lire ou de le modifier… on est en multitâche donc c’est logique.
//dans un Worker…
ba.position=0; ba.writeInt(12); ba.writeFloat(12.5); ba.writeInt(5);
donc le BA contient 12,12.5,5
sauf qu’apres ba.writeInt(12); un Worker a essayé de lire les données…
ba.position=0; n=ba.readInt(); f=ba.readFloat(); n=ba.readInt();
le pointeur ayant été remit à zéro, on se retrouve avec des données corrompues.
Ce cas de figure arrive en général quand le Worker qui modifie le BA mets énormément de temps à le mettre à jour.
Il est possible d’empêcher ce problème en utilisant la class Mutex,
c’est un peu l’équivalent d’un feu rouge, avant de modifier/lire le BA on lock l’instance du Mutex
quand on a fini on unlock le mutex.
Si on essaye de lire le BA alors que le mutex est locké, la VM se mets en pause et attend que le Mutex soit unlocké pour se relancer.
Il est donc impossible de éditer/lire le BA alors qu’un Worker est entrain de l’éditer/lire.
PROBLÈME: (raaahhhhhh tout ce passait si bien pourquoi ?!!!)
Si votre Background Worker mets du temps à mettre à jour votre BA (genre 40ms alors que votre budget par frame est de 33ms) le FPS de votre main Worker baisse.
Normal, vous essayez de lire le BA dans votre Main Worker, Mutex mets en pause la VM le temps que le Mutex soit unlocked.
Donc dans ce cas de figure le main Worker se retrouve avec autant de FPS que le Worker en background (celui qui mets du temps à éditer le BA).
Mutex c’est génial mais c’est donc à utiliser pour des cas très particulier.
NB: Notez qu’il existe aussi la méthode tryLock() qui bloque le Mutex sur le current Worker s’il n’est pas déjà bloqué et renvoi true, ou juste false si le Mutex est bloqué sur un Worker.
Contrairement à lock, tryLock ne bloque pas la MV, le code continuera à s’exécuter normalement.
Et maintenant la pratique avec 3 tests:
(FP11.5 requis, les démos ne fonctionne pas sous chrome? about:plugins vous devez avoir plusieurs plugins flash activé, désactivez celui situé dans les répertoires de chrome )
sourcecode du worker Mutex (echapez mutex.lock/unlock pour ne pas utiliser Mutex)
//dans l'update de chaque particules var l:int=300;//oh le bourrin ! while(l--){ velocity.x=Math.cos(_angle*Math.PI/180)*speed; velocity.y=Math.sin(_angle*Math.PI/180)*speed; }
-un test qui n’utilise pas de Worker,
au bout d’un certain temps ça rame comme prévu…
-un test qui utilise des Workers (un pour la vue et l’autre pour la physique) et shared BA
le Worker qui gère la physique perd du FPS mais pas le main Worker donc cool !
Par contre l’accès au BA n’est pas contrôlé par Mutex donc risque de données corrompues.
-un test qui utilise des Workers, shared BA et Mutex
le Worker qui gère la physique perd du FPS et entraine dans sa chute le FPS du main Worker :/