Masapi - overall progression
Par Cédric Tabin le mercredi 11.06.2008, 21:23 - ActionScript - Lien permanent
Voici un billet expliquant plus en détail comment masapi gère la progression globale des fichiers qui ont été mis en file d'attente.
Comment faire pour récupérer le nombre total de bytes des fichiers lorsque le chargement n'a pas commencé ? Masapi gère la chose très simplement : tous les fichiers ont le même poids (bytesTotal) jusqu'à ce que cette valeur soit connue. Dès que la propriété bytesTotal d'un fichier est récupérée, masapi va automatiquement l'utiliser (et laisser tomber le poids par défaut).
Coté code, la propriété qui est utilisée se nomme virtualBytesTotal de l'interface ILoadableFile. Par défaut, la classe LoadableFileFactory mettra une valeur de 200ko à cette valeur. La plupart du temps, celle-ci est suffisante car les fichiers sont assez légers.
Toutefois, cela peut poser problème lorsque les fichiers à charger sont gros (dépassent les 200Ko). Si un loader séquentiel (fichiers chargés 1 par 1) est utilisé, tout d'un coup la barre de progression va reculer ! Dans le cas contraire, avec des fichiers très légers, la barre de progression avancera très lentement et arrivera d'un coup à la fin.
Voila un exemple d'une très mauvaise utilisation de la propriété virtualBytesTotal. La barre du haut, tous les fichiers font 10Mo par défaut et pour celle du bas, 2Ko. L'image chargée fait 2.5Mo.
J'ai créé ci-dessous un autre exemple où 1 fichier de 2.5Mo est chargé et ensuite 8 fichiers de 1Ko. La barre du haut montre le comportement avec les valeurs par défaut et celle du bas avec des valeurs personnalisées :
Dans le deuxième cas, l'avancée des pourcentages reflète mieux la réalité qu'avec les valeurs par défaut, quoique celles-ci fonctionnent très bien.
Du coté du code, cela reste assez simple. Voici le code de base utilisé :
var cpLoader:CompositeMassLoader = new CompositeMassLoader(); cpLoader.massLoader.parallelFiles = 1; var rootPath:String = "./"; var file1:ILoadableFile = cpLoader.addFile(rootPath+"picture.jpg"); //2.5Mo var file2:ILoadableFile = cpLoader.addFile(rootPath+"file1.txt", LoadableFileType.TEXT); //1Ko var file3:ILoadableFile = cpLoader.addFile(rootPath+"file2.txt", LoadableFileType.TEXT); var file4:ILoadableFile = cpLoader.addFile(rootPath+"file3.txt", LoadableFileType.TEXT); var file5:ILoadableFile = cpLoader.addFile(rootPath+"file4.txt", LoadableFileType.TEXT); var file6:ILoadableFile = cpLoader.addFile(rootPath+"file5.txt", LoadableFileType.TEXT); var file7:ILoadableFile = cpLoader.addFile(rootPath+"file6.txt", LoadableFileType.TEXT); var file8:ILoadableFile = cpLoader.addFile(rootPath+"file7.txt", LoadableFileType.TEXT); var file9:ILoadableFile = cpLoader.addFile(rootPath+"file8.txt", LoadableFileType.TEXT); cpLoader.start();
Pourquoi avec ce morceau de code, le comportement n'est pas le même que dans le premier exemple avec la barre qui recule ? Tout simplement car Masapi reçoit très rapidement la bonne valeur bytesTotal du fichier et n'utilise plus la propriété virtualBytesTotal. Toutefois, la barre de progression continue d'avancer lentement car Masapi pense qu'il y a encore 8 fichiers de 200Ko à charger.
Pour adapter cela, il y a la solution simple mais fastidieuse suivante : pour chacun des fichiers créés, adapter manuellement la propriété virtualBytesTotal.
var file:ILoadableFile = cpLoader.addFile(rootPath+"file8.txt", LoadableFileType.TEXT); file.virtualBytesTotal = 2000; //2Ko
L'autre méthode consiste à dire à la classe LoadableFileFactory de mettre directement la valeur désirée, et d'adapter cette valeur pour le fichier qui est beaucoup plus lourd.
var cpLoader:CompositeMassLoader = new CompositeMassLoader(); cpLoader.loadableFileFactory.defaultVirtualBytesTotal = 2000; cpLoader.massLoader.parallelFiles = 1; var rootPath:String = "./"; var file1:ILoadableFile = cpLoader.addFile(rootPath+"picture.jpg"); //2.5Mo file1.virtualBytesTotal = 2.5 * 1024 * 1000; //2.5Mo par défaut var file2:ILoadableFile = cpLoader.addFile(rootPath+"file1.txt", LoadableFileType.TEXT); //2Ko par défaut var file3:ILoadableFile = cpLoader.addFile(rootPath+"file2.txt", LoadableFileType.TEXT); var file4:ILoadableFile = cpLoader.addFile(rootPath+"file3.txt", LoadableFileType.TEXT); var file5:ILoadableFile = cpLoader.addFile(rootPath+"file4.txt", LoadableFileType.TEXT); var file6:ILoadableFile = cpLoader.addFile(rootPath+"file5.txt", LoadableFileType.TEXT); var file7:ILoadableFile = cpLoader.addFile(rootPath+"file6.txt", LoadableFileType.TEXT); var file8:ILoadableFile = cpLoader.addFile(rootPath+"file7.txt", LoadableFileType.TEXT); var file9:ILoadableFile = cpLoader.addFile(rootPath+"file8.txt", LoadableFileType.TEXT); cpLoader.start();
Et l'avancement du pourcentage sera beaucoup mieux géré ! Il faut juste bien retenir que la propriété virtualBytesTotal est utilisée seulement si la valeur bytesTotal d'un fichier chargé n'est pas connue.
La bonne pratique pour gérer ce genre de chose est de spécifier une taille légèrement supérieure à la taille réélle du fichier. Par exemple, pour une liste de fichiers dont le poids est compris entre 10 et 30Ko, la valeur de virtualBytesTotal devrait être à 35Ko. Il faut éviter d'avoir une valeur inférieur à la taille d'un fichier sous peine de voir sa barre de progression reculer. Dans le doute, une valeur élevée est de mise.
Enfin pour ceux qui utiliser l'inter-dépendance des fichiers, il n'y a aucune ligne de code à toucher pour ajuster cela : il suffit de rajouter l'attribut virtualBytesTotal dans le xml de configuration :
<?xml version="1.0" encoding="utf-8" ?> <application> <files> <file name="astorm" url="/blog/public/Sources/Masapi/Dependency/astorm.swf" type="swf" virtualBytesTotal="200000" /> <file name="font" url="/blog/public/Sources/Masapi/Dependency/font.swf" type="swf" virtualBytesTotal="500000" /> <file name="background" url="/blog/public/Sources/Masapi/Dependency/storm.jpg" type="swf" virtualBytesTotal="1000000" /> <file name="text" url="/blog/public/Sources/Masapi/Dependency/text.txt" type="text" virtualBytesTotal="30000" /> </files> <dependencies> <dependency name="astorm"> <file name="font" /> <file name="background" /> <file name="text" /> </dependency> </dependencies> </application>
Commentaires
Bonjour,
Merci pour l'explication, mais comment faire quand on ne connait pas par avance la taille des fichiers à charger ?
Bonne continuation.
Salut,
Dans ce cas, mets une taille assez grosse. C'est surtout pour éviter que la barre ne recule. De toute façon, dès que la taille réelle est connue, la taille virtuelle n'est plus utilisée
@++
Salut Cédric, J'utilise Masapi maintenant depuis une semaine, c'est très agréable a utiliser je t'en remercie.
J'ai un petit problème tout de même. En local avec testeur de bande passante en T1, Mon "onMassloadProgress" Commence à 0% mais sur un serveur distant... il ne commence jamais avant 60%.
Aurai tu une idée de l'erreur?
Salut,
C'est probablement du au fait que tu as trop de choses à charger avant la première frame (typiquement si tu as des objets que tu as exporté pour AS). Je te conseilles de faire un SWF qui ne contienne que ce qui est relatif au massive loading pour éviter ce genre de problème
@++
C'est le cas, j'ai un fichier index.swf de 17 ko qui charge mes différents SWF, images, xml, c'est bien pour ça qui me parait flou.
mmmh bizarre... Normalement y a pas de raison. Pose ta question sur le googlegroup que je puisse voir le code Merci !