Jump to content
Search Community

didn't get complete event, shouldn't i have got fail event?

eigenface test
Moderator Tag

Recommended Posts

So this is what appears to be happening, and it doesn't seem ideal, but I've been wrong before: in swfA, I'm using a SWFLoader to load swfB. SwfB uses dataLoader1 to load some data, using requireWithRoot. If the data loads, the SWFLoader fires a complete event. If the data fails to load, the SWFLoader fires an error event and a child fail event, but not a regular fail event (also, not a complete event.) I'm thinking the SWFLoader should fire a regular fail event if any child fails (if it's not going to fire a complete event.) It was my understanding that a loader always completes or fails. Actually, maybe it is better than you only get a child fail, and not a regular fail also - easier to tell those 2 cases apart that way. Does the behavior I'm describing make sense?

 

As a separate issue, it appears to be the case that requireWithRoot only works for subloaders instantiated when their root finishes loading. I tried instantiating dataLoader2 in the complete event handler for dataLoader1, also using requireWithRoot (dataLoader2 has to wait for dataLoader1 to finish in order to know what to load next.) But then the SWFLoader fires a complete event after dataLoader1 completes, and only after that does dataLoader2 complete. Seems to me, it would make more sense if the SWFLoader didn't fire its complete event until both DataLoaders completed.

Link to comment
Share on other sites

So this is what appears to be happening, and it doesn't seem ideal, but I've been wrong before: in swfA, I'm using a SWFLoader to load swfB. SwfB uses dataLoader1 to load some data, using requireWithRoot. If the data loads, the SWFLoader fires a complete event. If the data fails to load, the SWFLoader fires an error event and a child fail event, but not a regular fail event (also, not a complete event.) I'm thinking the SWFLoader should fire a regular fail event if any child fails (if it's not going to fire a complete event.) It was my understanding that a loader always completes or fails. Actually, maybe it is better than you only get a child fail, and not a regular fail also - easier to tell those 2 cases apart that way. Does the behavior I'm describing make sense?

 

Good catch - this should be fixed in the latest version of LoaderMax. Please give it a shot and let me know if it works well for you. Sorry about the confusion/hassle.

 

As a separate issue, it appears to be the case that requireWithRoot only works for subloaders instantiated when their root finishes loading. I tried instantiating dataLoader2 in the complete event handler for dataLoader1, also using requireWithRoot (dataLoader2 has to wait for dataLoader1 to finish in order to know what to load next.) But then the SWFLoader fires a complete event after dataLoader1 completes, and only after that does dataLoader2 complete. Seems to me, it would make more sense if the SWFLoader didn't fire its complete event until both DataLoaders completed.

 

SWFLoader waits for the subloading swf's INIT event and checks for any loaders that have requireWithRoot set at that point. If it finds any, it incorporates them accordingly but there's really no way for it to know if/when you're going to create more loaders with requireWithRoot later. I wouldn't want to set some timeout (like wait for 2 seconds and see if there are any) because that will slow things down (imagine loading 20 swfs sequentially - that would add 40 seconds to their load time unnecessarily). The scenario you described, though, should work - if DataLoader1 has requireWithRoot and inside of its onComplete, you create DataLoader2 which also has the same requireWithRoot, it should get added in there before the COMPLETE event gets dispatched. I just tested that theory on my end and it seemed to work perfectly, but if you're running into trouble, please feel free to post a sample FLA that demonstrates the issue (it's SUPER helpful for troubleshooting).

Link to comment
Share on other sites

I'm going to ignore the second issue and concentrate on the first one for now. I updated all my greensock classes, and now I'm getting even weirder behavior. The setup is the same: in swfA, I'm using a SWFLoader to load swfB. SwfB uses a DataLoader to load some data, using requireWithRoot. I've entered an incorrect filename so the DataLoader fails. There are no other DataLoaders.

 

Here is the sequence:

 

SWFLoader gets a bunch of progress events.

swfB main class constructor is called.

SWFLoader gets an error event.

DataLoader gets an error event. (Shouldn't this go before the error event to SWFLoader? The default is listen for the target and bubbling phases, not capture; the child gets the event before the parent.)

SWFLoader gets a child fail event.

DataLoader gets a fail event. (Shouldn't this go before the child fail event to SWFLoader?)

SWFLoader gets another progress event. (Is this supposed to happen?)

SWFLoader gets a fail event.

SWFLoader gets another error event. (Is this supposed to happen?)

SWFLoader gets another fail event. (Is this supposed to happen?)

Link to comment
Share on other sites

With regard to the second issue, what I'm really trying to do is determine if I can use LoaderMax for the following use-case: in swfA, I'm using a SWFLoader to load swfB. SwfB may need to load any kind of resource at any point in the future, not necessarily right away. I want swfA to hear about it if any of those resource loads fail. (Ideally, swfA could also track the progress of the resource loads, but this is not essential.) Is LoaderMax intended for this use-case or not?

Link to comment
Share on other sites

I updated all my greensock classes, and now I'm getting even weirder behavior.

It actually isn't a bubbling issue - it just has to do with the priority in the addEventListener() calls. You see, LoaderMax automatically adds listeners for various stuff like FAIL events so that it can propagate them and manage/advance its queue. So those listeners were added BEFORE anything else. Since the default priority is 0, any listeners you add after that point will receive the events after the listeners that were already added internally. The solution was for me to simply reduce the priority to -1. I just posted an update with that change.

 

As for the FAIL events that were received AFTER the COMPLETE event on the LoaderMax, that is expected. Imagine the event bubbling up - when the last loader in the queue fails, the FAIL event starts bubbling up. When the LoaderMax receives that FAIL event, it says "okay, now that the last loader is done (failed), I'm done with my queue so dispatch a COMPLETE event." That's when you receive the COMPLETE event obviously. Then the FAIL event continues to bubble up and your listeners get notified. If I reversed that order, that would be problematic because in your listener function, if you checked the LoaderMax's status it wouldn't accurately reflect what it should. In other words, it would still indicate that it's LOADING when it has actually completed. So I can see why you'd think it's odd that the FAIL events were received after the COMPLETE event but hopefully the explanation makes it clear as to why it does make sense to work that way.

 

With regard to the second issue, what I'm really trying to do is determine if I can use LoaderMax for the following use-case: in swfA, I'm using a SWFLoader to load swfB. SwfB may need to load any kind of resource at any point in the future, not necessarily right away. I want swfA to hear about it if any of those resource loads fail. (Ideally, swfA could also track the progress of the resource loads, but this is not essential.) Is LoaderMax intended for this use-case or not?

Actually, yes, LoaderMax should be able to handle this just fine. If you want to monitor the loaders inside the sub-loaded swf (including loaders that aren't requiredWithRoot and ones who are created later after the swf loads), I'd recommend creating a LoaderMax instance inside that swf and make sure you insert/append the loaders to that LoaderMax. Then, when the SWFLoader dispatches its INIT event, you can grab that LoaderMax instance and attach your listeners. You don't need to ever load() that LoaderMax - it can simply be a monitoring tool through which important events bubble. So, for example, on the first frame of the child swf (or in the document class's constructor), you'd have code like this:

 

var rootQueue:LoaderMax = new LoaderMax({name:"game1Root"});
rootQueue.append( new DataLoader("bogus.txt", {name:"DataLoader", requireWithRoot:this.root}) ).load();
rootQueue.append( new ImageLoader("assets/1.jpg", {name:"image1", container:this}) );
...and add stuff to rootQueue whenever you want...

 

Then, in your parent swf, you could have code like this:

 

var loader:SWFLoader = new SWFLoader("child.swf", {container:this, onInit:swfInitHandler}) );
loader.load();

function swfInitHandler(event:LoaderEvent):void {
var rootQueue:LoaderMax = event.target.rawContent.rootQueue; //or LoaderMax.getLoader("game1Root");
if (rootQueue != null) {
	rootQueue.addEventListener(LoaderEvent.CHILD_PROGRESS, childEventHandler, false, 0, true);
	rootQueue.addEventListener(LoaderEvent.CHILD_COMPLETE, childEventHandler, false, 0, true);
	rootQueue.addEventListener(LoaderEvent.CHILD_FAIL, childEventHandler, false, 0, true);
	rootQueue.addEventListener(LoaderEvent.ERROR, errorHandler, false, 0, true);
	...add whatever other listeners you want...
}
}

function childEventHandler(event:LoaderEvent):void {
trace("--child event: "+event.type+" on "+event.target+", progress: "+event.target.progress);
}

function errorHandler(event:LoaderEvent):void {
//handle errors here
}

 

There are, of course, other ways to handle this but hopefully this demonstrates a relatively easy way that LoaderMax can be used to accomplish your objective of tracking important events for all your loaders in the subloaded swf(s).

 

Does that help?

Link to comment
Share on other sites

"As for the FAIL events that were received AFTER the COMPLETE event on the LoaderMax, that is expected."

 

I didn't get a COMPLETE event before, and I'm still not getting one now (nor did I instantiate LoaderMax, at least not explicitly.) I updated my greensock classes again (just before posting this), and I'm getting a somewhat different, but still strange sequence of events:

 

SWFLoader gets a bunch of progress events.

swfB main class constructor is called. (Not an event, just letting you know.)

DataLoader gets an error event. (Now this is in the right place, but not if I set priority <= -1.)

SWFLoader gets an error event.

DataLoader gets a fail event.

SWFLoader DOES NOT get a child fail event. (It's supposed to, right?)

SWFLoader DOES NOT get another progress event. (I guess this is good.)

SWFLoader gets a fail event.

SWFLoader gets another error event. (Is this supposed to happen?)

SWFLoader gets another fail event. (Is this supposed to happen?)

 

The priority = -1 fix seems to have corrected the order of the error events (but now I'm not getting a child fail event from the SWFLoader at all), but it seems like a brittle fix. If I decide I want to change the priority of my DataLoader error event listener to -1, then the order is wrong again. You have to know internal implementation details in order to avoid breaking the system.

 

Also, I'm getting two events at the end, an error event and a fail event to SWFLoader, that apparently should not be there.

 

Thanks for the sample code, I'll try it out once I get the basic stuff working.

Link to comment
Share on other sites

Sorry for the delayed reply. Now the sequence is:

 

SWFLoader gets a bunch of progress events.

swfB main class constructor is called.

DataLoader gets an error event.

SWFLoader gets an error event.

DataLoader gets a fail event.

SWFLoader gets a child fail event.

SWFLoader gets a fail event.

 

Perfect - this is how I expected it to work. Thanks for fixing this.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...