Le Blog de SamsamTS

AS3 - Timer pas précis

Tiens ça fais longtemps que je n'ai pas posté de billet.

Je me suis récemment mis à testouiller l'ActionScript 3 (avec FlashDevelop) pour voir de quoi il en retourne. Pas mal de choses ont changées, la gestion des évènements, des éléments graphique, etc... Je n'aborderai pas ces changements ici, je pense que d'autres personnes sauront vous les expliquer bien mieux que moi.

Venons-en au sujet qui m'intéresse ici, les Timer. Plus généralement tout ce qui est lié à la gestion du temps dans flash.

Avec la venue de l'AS3, j'espérais vraiment que la précision se soit améliorée. C'est vrai quoi, j'entends partout "l'AS3 c'est plus mieux", "plus rapide, plus performant", etc...
Alors forcément, dès que j'ai découvert l'existence d'une classe Timer je me suis précipité dessus. Finalement j'ai vite découvert qu'elle n'est pas précise du tout. Par exemple, si l'on fait un timer se déclenchant toutes les 1000ms on pourrait penser que lorsque l'évènement a été déclenché 60 fois, une minute se soit passé, ce qui n'est absolument pas le cas, et la différence est de plus en plus conséquente au fil tu temps.

Bon, la classe Timer n'est pas précise ? Pas grave, j'ai qu'à faire la mienne.
Comme je ne fais jamais rien comme les autres, les propriétés, méthodes et évènements ne sont pas du tout ceux de la classe fournie par Adobe. En fait je me suis largement inspiré de la classe Timer en C#. Mais l'important n'est pas là.
Je voulais cette classe aussi précise que possible, malheureusement rien dans flash ne permet d'exécuter une fonction après Xms avec précision. Mais j'allais pas me laisser me décourager pour autant.

L'idée est simple, on utilise un setTimeout pour envoyer un évènement. S'il y a du retard, ce qui ne peut être évité, le prochain setTimeout sera plus court afin de compenser le retard pris. Par exemple, l'évènement doit être déclenché toutes les 100ms, la première fois il est déclenché au bout de 112ms, soit un retard de 12ms, alors on définit le prochain setTimeout pour qu'il se déclenche au bout de 88ms, rattrapant le retard.
Bien sur ce n'est pas suffisant, puisqu'on ne peut pas définir d'intervalle négatif. Dans ce cas on déclenche l'évènement plusieurs fois de suite (boucle while) jusqu'à ce qu'il soit à nouveau possible de définir un setTimeout.

Vous pouvez télécharger la classe ainsi qu'un exemple d'application montrant les performances de cette classe ici (5ko).

Vos commentaires

Le mercredi 27 décembre 2006 à 10:56 , commentaire par thecaptain :: #

 

Salut,

Intéressant comme concept :) Je me demande pourquoi Adobe n'y passe pas un peu de temps car je trouve cela tout de même important pour qu'on s'y arrete... m'enfin sinon 2-3 remarques quant à ta classe (ouais j'adore faire mon chieur :mrgreen: ) :
- pour les ms, utilise uint
- commence les getters/setters avec un minuscule (conventions Java, la tu as pris celle de .Net)
- je sais pas si le test du isFinite dans le constructeur est pertinent...

@++ :)

 

Le mercredi 27 décembre 2006 à 11:16 , commentaire par SamsamTS :: #

 

Merci pour ces remarques thecaptain, je t'autorise à faire ton chieur :mrgreen:

- pour les ms, vu que la fonction getTimer utilise elle-même int, ne vaut-il pas mieux d'utiliser également int ? Ca évite de faire un cast implicite. C'est vrai que je me suis posé la question.
- pour les getter/setter j'ai pris l'habitude de mettre une majuscule et comme je ne fais pas de java, en plus java != ActionScript. Cela dis si tout le monde utilise la convention Java en AS je ferai peut-être bien de la suivre aussi.
- pour le test du isFinite je ne sais pas, la classe Timer d'Adobe le fait donc je me suis dis je fais pareil. Enfin sauf que leur constructeur prend un Number en paramètre.

 

Le mercredi 3 janvier 2007 à 14:30 , commentaire par ekameleon :: #

 

Hello :)

Java != actionscript mais .NEt aussi  :D en ECMAScript il est préférable de mettre une majuscule au début des noms de classe et c'est tout :) Ici c'est pas une question de notation Java mais de notation ECMAScript avant tout ;)
Sinon tu risques d'avoir des problèmes en utilisant des méthodes et des classes basées ECMAScript tu ne penses pas ?

En tout cas sinon la classe Timer utilise derrière un genre de setInterval et comme l'actionscript n'est pas synchrone et se base toujours sur la fréquence de l'animation, il est en effet très difficile d'avoir un Timer exacte ! Mais je me demande dans quelles circonstances (à part une horloge et encore pour ma part je préfère me baser sur la classe Date) on peut avoir besoin d'un temps exacte dans une animation Flash ?

EKA+ :)

 

Le lundi 8 janvier 2007 à 16:09 , commentaire par blaz :: #

 

salut,

pour info, on peux avoir besoin d'un timer exact, je travaille en ce moment sur des stats de log en live avec flex j'ai donc besoin de recuperer des données depuis un serveur toutes les x minutes pour faire un jolie graphe ... :?

c'est ce qu'on appelle un post qui sert pas à grand chose :oops:

 

Le mercredi 17 janvier 2007 à 17:20 , commentaire par Attraktive :: #

 

salut :)

oui l'utilisation d'un timer exact est nécessaire aussi dans le cadre d'appli de gestion du son, notamment pour boucler les sons, ou les quelques minisecondes de décalages sont déroutants... :(

Merci sam pour ta classe, m'en vais regarder ca de plus prêt ;)

 

Le jeudi 27 septembre 2007 à 01:30 , commentaire par PanicSystem :: #

 

Merci beaucoup pour ta classe ! Elle m'a permis de me sortir d'un sacré pétrin !! Je devais enregistrer les actions d'un utilisateur en même temps que j'enregistrais son commentaire audio. Si mon action était gourmande => Décalage...et maintenant c'est parfait !!!

 

Le jeudi 27 septembre 2007 à 14:13 , commentaire par SamsamTS :: #

 

Ravi que cela ai pu te servir ;)

 

Le samedi 17 novembre 2007 à 09:35 , commentaire par alixes :: email :: #

 

Salut,

Peut-on utiliser ta classe dans flash, même si l'on n'utilise pas Flashdevelop ?
J'ai essayé mais le compilateur ne comprend pas l'instruction

Code :

import org.flashdevelop.utils.FlashConnect3;


J'ai essayé sans l'utilisation de FlashConnect mais cela ne fonctionne pas :(

fichier test.fla :

Code :

import App;
var Appnew:App = new App();


Error #1009: Il est impossible d'accéder à la propriété ou à la méthode d'une référence d'objet nul.
at App$iinit()
at test_fla::MainTimeline/test_fla::frame1()

 

Le samedi 17 novembre 2007 à 12:43 , commentaire par SamsamTS :: #

 

Oui il est tout à fait possible d'utiliser cette classe dans flash.

Pour créer un timer rien de plus simple :

Code :

var timer = new Timer(1000);
timer.addEventListener(TimerEvent.ELAPSED, OnTimer);
timer.Start();


Ainsi la fonction OnTimer (que tu aura pris soin de créer) sera exécuté toute les secondes (1000ms = 1s)

 

Le lundi 27 avril 2009 à 19:42 , commentaire par rboyart :: email :: #

 

Merci pour ta library, c'est cool!, je suis en train de l'utiliser dans un projet et j'ai remarqué il met du temps à démarrer, peux-je force le timer à démarrer tout de suite?merci et bien cordialement

 

Le vendredi 3 juillet 2009 à 00:14 , commentaire par Manu :: #

 

Très jolie implémentation, j'aime bien le style C# en actionscript: ça donne un petit côté fleuri au code  :D

Mais surtout merci pour cette classe, je n'avais pas pensé à cette solution et ça m'a été super utile dans un projet où des images défilantes sont synchronisées sur du son, dont le pitch varie en plus, un cauchemar avec le Timer d'origine.

 

Le jeudi 17 septembre 2009 à 15:01 , commentaire par Caniche :: email :: #

 

Merci ! Tu viens de me sauver la vie  :D
Je me suis permis de chipotter un peu à la classe pour coller plus aux projets qui utilisaient déjà un timer.

Ca marche vraiment nickel !

 

Le samedi 18 décembre 2010 à 20:52 , commentaire par MatLab :: email :: #

 

Salut ! C'est moi ou le lien est mort ?
J'en ai vraiment trop besoin de cette astuce, j'essaye de faire un jeu musical et je galère comme un fou furieux ! :cogne:
Merci

 

Ajouter un commentaire