Accueil > Code > Récupérer un Loader depuis un callback de type IOErrorEvent…

Récupérer un Loader depuis un callback de type IOErrorEvent…

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: ,
  1. okenneko
    13/03/2008 à 00:21 | #1

    Bonjour Tynril !

    Essaie comme ça

    ldr.contentLoaderInfo.addEventListener(Event.INIT, onInit(ldr));

    private function onInit(loader):Function
    {
    return function(e:Event)
    {
    delete loader;
    }
    }

    ca devrait marcher.

  2. 25/03/2008 à 10:23 | #2

    Utilise-tu les content de ce pool simultanement ou se remplacent-il les uns les autres? Parce que sinon, je suppose que tu dois être confronté au bug du changement de parent du content, dont parle Thibault sur ByteArray: http://www.bytearray.org/?p=127

    ++ ^_^

  3. 02/04/2008 à 15:19 | #3

    okenneko > Jolie feinte. Je vais tenter le coup.

    LAlex > En fait, pour parer à la casse, j’utilise les loaders comme DisplayObject également. En gros, je reparente mon objet Loader mais jamais son contenu.

    Du coup, le problème se pose pas. C’est plus lourd à traiter (enfin, j’imagine qu’un Loader est plus lourd qu’un simple Sprite par exemple, même si au niveau de la display list ça doit pas changer grand chose), mais vu que j’utilise les loaders pour constituer une scène précalculée que je place ensuite dans un backbuffer (à grand coup de draw()), ça ne coince pas.

    Enfin, pas pour le moment. Saleté de bugs planqués, quand même. :p

  1. 27/03/2014 à 00:02 | #1
  2. 14/08/2014 à 17:14 | #2