AS3 - Detect external SWF has stopped not using totalFrames

Trying to find a way to detect when an externally loaded SWF has stopped. Using “totalFrames” like the example below doesn’t work for what I’m trying to accomplish.

I need something that simply listens and detects when the clip has stopped. Editing the external SWF is not an option. Thanks in advance for any insight.

function onfrm( evnt: Event ): void
{
                if (newMC.currentFrame == newMC.totalFrames )
               {
                    newMC.removeEventListener( Event.ENTER_FRAME, onfrm);
                    trace("End of banner");
                }
}

Your problem isn’t very well-specified. Generally, when a MovieClip doesn’t ever reach its totalFrames, then it’s doing something more complicated than running through an animation once. But you haven’t told us what else is going on in that MovieClip, so it’s hard to help.

If for some reason the movie stops on a frame before its last frame, you could just check whether or not the clip has advanced frames in the most recent frame. Something like:

var prevFrameNum:Number = -1
function onfrm(e:*): void {
    var currFrameNum = newMC.currentFrame
    if(prevFrameNum == currFrameNum) trace('end of banner')
    prevFrameNum = currFrameNum
}

The external clip has a loop function on frame 80, long before the end of its timeline at frame 115. Once the number of loops it reached, it stops on frame 80. Before reaching that number, the banner continues along the timeline and then loops back to the beginning.

But… The SWF being loaded into newMC will change. Sometimes it will have a loop/function, sometimes it will just have a simple stop() at the end and won’t loop. My thinking was by detecting when the clip has stopped rather than its total frames, it would cover both scenarios.

Either way, if currentFrame is the same during two consecutive enter frame events, then you’ve hit your stop condition, which is what my code above checks.

Thanks so much for your help. Super smart solution. It’s working great.

1 Like

Not totally sure how to phrase the question but I need to extend the capabilities of the function to also work when the external SWFs contains animation that isn’t timeline-based but rather function-based.

Let’s say the external SWF loaded into the movie clip (newMC) has a single frame timeline that contains tween functions for all animation. Without knowing how many there are, or if they even exist, is it possible to detect when all Tweens/animation is complete?

Congrats! You’ve just run into the Halting Problem, one of the fundamental bases of theoretical computer science!

Luckily, your case has some moderately detectable aspects. For one, you could recursively look at the display list (children) of the loaded clip to see if any of their visible properties are still actively changing. Similarly, you could write the whole thing to a bitmap every once and a while to check activity. This approach suffers from the limitation that you can’t tell the difference between a finished animation and one that’s taking a long pause.

You could use bytecode reflection and static analysis to replace all provable references to Tween instances with a class your code controls directly. The extreme edge case of that would be guessing access to all Flash APIs with your own trampoline functions, so you’d have access to essentially the entire state of the other running program. This approach requires moderate skill in program analysis.

You could also look into whether or not Tween completion events bubble up at all… I sort of have the impression they don’t, but @senocular knows. He would also remember better than I whether or not hasEventListener exists in AS. I forget if that function is in JS or AS or some other language. If there are no more listeners, then the only thing you might worry about then would be setTimeout-type asynchronous things happening.

You won’t easily be able to tell if a programmatic animation is looping or not though. That’s pretty core to the nature of the halting problem.

In general, loading untrusted or unknown code has these problems.

There isn’t much you can do to reliably check this from the parent SWF alone. krilnon offered some great suggestions, but there can be cases where they would return false positives of completion. What you really want is to have that loaded SWF setup to indicate when its animations are done in a way that can be easily read by the parent SWF, such as dispatching a custom sharedEvents event when its animations are complete (bubbling shouldn’t apply since the non-display object tween instances themselves are the objects dispatching animation complete events). That child SWF having set up the animations can more easily determine when those animations are complete. Then its just a matter of informing other parties (parent SWF).