Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

LoaderInfo and ProgressEvent.PROGRESS

Status
Not open for further replies.

maguskrool

Technical User
Dec 11, 2006
77
PT
Hi.

I'm working on a project where I have to preload several .swfs. I created a custom class (myLoader) that extends the Loader class and adds it a few string variables with data I need. To each instance's contentLoaderInfo I add event listeners for ProgressEvent.PROGRESS and assign the same event handler function.

The problem is, I need to access the myLoader instance from the event handler, but so far I haven't been able to, not until it finishes loading.

Any help in this matter is very appreciated.

 
Thanks for the reply, Kenneth, but that doesn't work either.

I'm not an expert on the AS3 event model, but the ProgressEvent.PROGRESS is not a bubbling event so I don't think I can listen to it from the Loader instance itself, for example.

I'm really stumped with this, don't know why the LoaderInfo object can't access the Loader immediately, since the Loader instance creates it in the first place. The url property returns "null" also.

Below is what I've tried and the error messages I received.

Any help in this matter is very appreciated.

Code:
//Event handler.
private function _progressHandler ($evt:ProgressEvent):void {
trace ($evt.target); 
trace ($evt.currentTarget); // both return [object LoaderInfo]

trace ($evt.target.loader);
trace ($evt.currentTarget.loader); //both return Error #2099: The loading object is not sufficiently loaded to provide this information.

trace ($evt.target.url);
trace ($evt.currentTarget.url); //both return null
}

 
Yep. You'll see the error messages are consistent with that and while adding the event listener to the Loader doesn't return an error message, it also doesn't return anything else.

 
Thanks for you interest in my problem, Kenneth. Here is a more complete example, a simplified version of my code.


Code:
//.fla file, 1st frame
import flash.display.Loader;
var sName:String = "loader_";
//Create a series of Loader instances. Here just one is created to simplify the example.
for (var k:int = 1; k < 2; k++) {
	this[sName] = new Loader();
	this[sName].contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, handle1, false, 0, true);
	this[sName].contentLoaderInfo.addEventListener(Event.COMPLETE, handle2, false, 0, true);
	this[sName].contentLoaderInfo.addEventListener(Event.INIT, handle2, false, 0, true);
	this[sName].contentLoaderInfo.addEventListener(Event.OPEN, handle2, false, 0, true);
	this[sName].load(new URLRequest("imagens/flower/"+k+".jpg"));
}
//Event Handlers.
function handle1 ($evt:ProgressEvent):void {
	trace ("type: "+$evt.type+ " | current target: "+$evt.currentTarget+" | target: "+$evt.target);
	trace ($evt.currentTarget.loader);
	trace ($evt.target.loader); //See comments below.
}
function handle2 ($evt:Event):void {
	trace ("type: "+$evt.type+ " | current target: "+$evt.currentTarget+" | target: "+$evt.target);
	trace ($evt.currentTarget.loader);
	trace ($evt.target.loader);
}

And here is the output I get:

Code:
type: open | current target: [object LoaderInfo] | target: [object LoaderInfo]
Error: Error #2099: The loading object is not sufficiently loaded to provide this information.
	at flash.display::LoaderInfo/get loader()
	at teste_04_fla::MainTimeline/handle2()
type: progress | current target: [object LoaderInfo] | target: [object LoaderInfo]
Error: Error #2099: The loading object is not sufficiently loaded to provide this information.
	at flash.display::LoaderInfo/get loader()
	at teste_04_fla::MainTimeline/handle1()
type: progress | current target: [object LoaderInfo] | target: [object LoaderInfo]
Error: Error #2099: The loading object is not sufficiently loaded to provide this information.
	at flash.display::LoaderInfo/get loader()
	at teste_04_fla::MainTimeline/handle1()
type: init | current target: [object LoaderInfo] | target: [object LoaderInfo]
[object Loader]
[object Loader]
type: complete | current target: [object LoaderInfo] | target: [object LoaderInfo]
[object Loader]
[object Loader]

So as you can see, the OPEN and PROGRESS events don't allow me to get the Loader instance from the event handler, they say it's not sufficiently loaded to retrieve that info. The INIT and COMPLETE work as they should, since their meaning, at least in this case, is not very different, I guess.

In handle1, since an error is returned with trace ($evt.currentTarget.loader), the function is halted. I have, however, tried using only the 2nd trace, (the $evt.target.loader) and it returns the same error.

Just to make sure the problem had nothing to do with declaring the loader instances dinamically, I tested and example without the for cycle, using a regular variable. Still the same result.

Hope this helps you helping me and any other that might have encountered similar problems. Thank you.

 
Sorry, I was thinking something else :)

From AS3 doc:
When a loading operation is not complete, some properties of the contentLoaderInfo property of a Loader object are not available. You can obtain some properties, such as bytesLoaded, bytesTotal, url, loaderURL, and applicationDomain. When the loaderInfo object dispatches the init event, you can access all properties of the loaderInfo object and the loaded image or SWF file.
In the other words, you cannot access "loader" property until INIT is fired.

For your purpose, I would create a Class, and do the loading in it, something like:

[tt]this[sName] = new MyLoader("imagens/flower/"+k+".jpg", "var1", "var2");[/tt]

Kenneth Kawamoto
 
Darn.

Thanks Kenneth, you've been a big help. What I find mind-boggling is that the .loader property is one of those you cannot access immediately, since it should be the 1st one available in the 1st place. I mean, it references the instance it belongs to, where can you go wrong? And why should you have to wait for INIT if the info is already there?

Perhaps there's a good reason for this, but I can't think of one.

And actually, yes, I created a custom class that extends Loader, I didn't use it in the example because the simpler case returned the same errors and thus, using a custom class might complicate the point I was trying to make.

 
No, what I mean is a custom class NOT extending Loader, but you create a Loader and monitor progress within that class. In this approach, you know what the loader is (since there's only one Loader in the class instance), and you can hold as much as variables in the instance. I show you a quick example if you want.

Kenneth Kawamoto
 
Ah, sorry, I misunderstood. Yes, an example would be perfect, thanks! I'm not sure how that would solve my problem.

Just to explain what I'm doing:

I have a website and I need to preload several files, including .swfs. I have an array holding all the files currently being loaded and each of them has a corresponding number of frames (property progressFrames) in the preloader bar animation.

I created a myLoader class that extends Loader and has a progressFrames property. This number is calculated on each progress event and then I need to acess the myLoader so I can assign it to progressFrames.

 
MyLoader.as
Code:
package {
	import flash.display.Loader;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;

	public class MyLoader {
		
		private var file:String;
		private var progressFrames:uint;
		
		public function MyLoader(argFile:String, argProgressFrames:uint):void {
			file = argFile;
			progressFrames = argProgressFrames;
			
			var ldr:Loader = new Loader();
			ldr.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoadProgress);
			ldr.load(new URLRequest(argFile));
		}
		
		private function onLoadProgress(e:ProgressEvent):void {
			trace("file:" + file, "progressFrames: " + progressFrames);
		}
		
	}
	
}
Then I will create MyLoader instance with the file name and the "progressFrames":

[tt]new MyLoader("image1.jpg", 69);[/tt]

Output:
[tt]file:image1.jpg progressFrames: 69
file:image1.jpg progressFrames: 69
file:image1.jpg progressFrames: 69[/tt]

Hope you get the general idea!

Kenneth Kawamoto
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top