Archive

Archives pour 25/02/2008

25/02/2008 3 commentaires

Tout le monde aura déjà écrit un code de ce genre :

var ldr : Loader = new Loader();
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
ldr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
ldr.load(new URLRequest("http://www.bidon.com/trucmuche.jpg"));

Ca marche bien. Mais il se trouve que dans mon projet, on a tendance à avoir besoin de beaucoup, beaucoup de loaders. Je me suis donc dit « Allons, Tyn, utilise donc un pool ! » Ce qui marche également bien. On a un gain de plus de 1000% en utilisant un pool de Loader plutôt que d’en créer de nouveaux à chaque fois.

Mais qui dit pool dit nettoyage d’objet, et rendu dudit objet au pool après son utilisation. Hors, dans ce cas précis, j’ai un gros soucis: je ne peux pas récupérer mon objet Loader dans mon callback onIOError! C’est quand même très, très con. Ca signifie que je perds un élément de mon pool à chaque URL foireuse, ce qui est un leak inacceptable.

Voici donc un contournement foireux pour récupérer son objet Loader depuis un callback où LoaderInfo.loader n’est pas encore renseigné:

package net.tynambule.exp {
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLRequest;
	import flash.utils.Dictionary;
	public class IOErrorCallbackWithLoader extends Sprite
	{
		private var _loaders : Dictionary = new Dictionary(true);
		public function IOErrorCallbackWithLoader()
		{
			var ldr : Loader = new Loader();
			ldr.contentLoaderInfo.addEventListener(Event.INIT, onInit);
			ldr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
			// Feinte ici :
			_loaders[ldr.contentLoaderInfo] = ldr;
			ldr.load(new URLRequest("existe-po.png"));
		}
		private function onInit(e : Event) : void
		{
			trace("Trop bien, le fichier existait!");
			// Ne pas oublier d'effacer ma référence, histoire que mon Loader puisse
			// être garbage collecté.
			delete _loaders[e.target];
		}
		private function onIOError(ioe : IOErrorEvent) : void
		{
			trace("Le fichier existait pas, mais j'ai toujours mon loader!");
			trace("Le voici :" + _loaders[ioe.target]);
			// Ne pas oublier d'effacer ma référence, histoire que mon Loader puisse
			// être garbage collecté.
			delete _loaders[ioe.target];
		}
	} }

Et hop. C’est quand même bien crade. Si un gentil développeur de chez Adobe passe par ici (sait-on jamais), c’est quand même con que le Loader ne soit pas accessible depuis l’objet LoaderInfo en cas d’erreur de chargement alors qu’il est disponible avant le chargement. Allez, salut.

Categories: Code Tags: ,