In Flex, what's the best way to remove a swf that was authored in Flash CS3? - apache-flex

So, I have an application where I'll be loading any number of swfs into a SWFLoader and removing them at runtime. The issue is - they are all timeline based movies authored in Flash CS3. I have very little control over what is in the movie other than the authors are not able to program any interactivity (i.e. no event listeners) but I want to make sure I am using the best technique to stop and trash these things so they don't hang around in memory too long. Here is the process I use right now to get rid of them:
Try stopping the content using MovieClip(content).stop();
Remove any listeners that I know about (ENTER_FRAME, etc...)
Set the source of the SWFLoader to null.
cross fingers, pray, make sacrifice (human if need be)
So that seems to work but is some better (or more comprehensive) method that you guys use to accomplish this same task? In all honesty - I'm not entirely sure these things aren't just kept in memory but I don't hear them so I don't know that they are there...

That's pretty much right. Loader (what SWFLoader uses under the hood), removes it's loaded clip from the stage with .unload(), but depending on what the clip has referenced the clip still runs and events still fire.
Flash Player 10 added .unloadAndStop(), but that is mostly just doing the same thing you are.
You could also try giving an explicit SecurityDomain (and probably ApplicationDomain so any contained classes are separate as well) in the optional LoaderContext parameter to Loader.load(), to try to prevent it adding event listeners outside (if you don't trust the clip not to), and avoid forming any references to anything from the clip so it can be garbage collected — but apparently it might still not unload in some cases.

Related

Understanding Flash SWC's imported into Flex Builder 3 and key framed animation

I am trying to understand what is going on in a SWC that I am importing from Flash CS4 into Flex Builder 3. Specifically I am using a SWC supplied by a Designer as the animation for a custom preloader (a subclassed DownloadProgressBar).
The issue I am trying to understand is, once the FlexEvent.INIT_COMPLETE is fired, I cleanup by removing the swc by running this :
removeChild(myPreloader);
myPreloader = null;
though even after I have removed this (which is successful, as I have checked by comparing this.numChildren before and after the call) the key framed animation still continues to run (not visibly). This has been detected by the Designer placing a trace in the time line of the animation (in Flash).
Can anyone tell me why is it, that even after I have removed the animation from the subclassed DownloadProgressBar, it still keeps running ?
Also, is it standard practice when importing SWCs to manage the cleanup of resources from the Flash side of things (much like releasing memory in obj-c). I find it counter intuitive that removing the child from the Flex side does not stop the animation.
Any clues to this would be greatly appreciated.
Basically, your SWC file is nothing more than a ZIP containing a SWF. So what you're doing is removing a MovieClip from the stage, but it is NOT stopping or unloading it. You might want to try
myPreloader.stop();
to stop the animation and
myPreloaderLoader.unload();
after you removed the item from the stage to free up memory.
Beware, though: the Flash Player garbage collection does not always work correctly. If there is any kind of ActionScript running within myPreloader, chances are it will continue to run, and it will be ignored during garbage collection. It is usually best to include a clear() or destroy() method for all AS classes and call it upon Event.REMOVED_FROM_STAGE.
This would have to be done by your designer colleague, but in my experience it is the cleanest procedure.

Video or VideoDisplay in Flex: when does it make sense to use one or the other

Flex appears to have 2 video classes: Video and VideoDisplay. My question is when does it make sense to use one or the other?
What I can tell from initial glancing is that VideoDisplay responds to mouse events because it inherits from IntaractiveObject, but I'm not sure if it's a real difference, because Video seems to have a workaround for this in that you can add your own event listeners.
There's probably more to it, but this is the only difference I can see now. So my question for those who used these objects extensively, can you share your experience when you use one over the other.
You'll nearly always want to use VideoDisplay. Video isn't a UIComponent, it can't handle its own loading from URL, won't dispatch any Flex events, and you can't bind to any of the properties such as playHeadTime. Video is a very basic DisplayObject that's capable of displaying video data, and doesn't do much else. It's more of a building-block, that you'd only use if you wanted to do something funky, or are building a Flash (non-flex) app.

Get Fscommand in Flex3

I have one swf file in that i used fscommand to get final output when submit button clicked in that swf ,
i am loading that swf in SWFloader in flex3 .i need to get fscommand value as Alert, how to get that value first and display as alert.
Thanks in advance
fscommand cannot be used for communication between loaded and containing SWFs.
From livedocs
fscommand: Lets the SWF file communicate with either Flash Player or the program hosting Flash Player, such as a web browser. You can also use the fscommand() function to pass messages to Director or to Visual Basic, Visual C++, and other programs that can host ActiveX controls.
You can call a method in the loaded swf OR access its properties directly OR use events OR use local connection to pass data between parent and loaded SWFs.
TECHNICALLY this is feasible, but a bad idea. You'd need to register a callback which would call the child swf (generally done from the child swf). But, you will risk a good deal of headache, and you'll have to rely a lot more on the browser than other options. It would also be slower than an AS only solution.
You're much better off (in this order):
Using a shared Singleton. This allows for complete separation of the two
swf's without requiring any major coordination between the two. The only
real potential problem can be caused if you want the child swf to have its
own ApplicationDomain, but even with that, there are work-arounds
Using events. This can work if you have the child swf dispatch a bubbling,
non-cancel-able event and have the event.target recorded by the
parent swf. You may have to adjust to avoid
SecuritySandboxViolations, however.
Using LocalConnections. The two detriments to LocalConnections are:
You will need to continually re-generate unique connection names to
avoid the error thrown by connecting two LocalConnections to the same
channel.
LocalConnections do have bandwidth limitations which can call
slowdowns if there is a high volume of traffic or if the messages are
too large.
Using direct manipulations like loader.content.foo.bar.baz;
I don't like this solution because it is much harder to maintain. It is
also much worse from a design perspective: you want to use
encapsulation as much as possible in this situation -- this technique
actively works against that.

What happens when a Flex App can't run at the specified framerate?

In our application (a game), in some cases it can't run fast enough. Obviously we'd like to speed it up, but in the mean-time when this happens it causes many problems (or if it's not causing them, the two are related).
The one which is least related to our own functionality is that the built in Alert.show() method stops working. Typically the full-screen transparent box appears but not the actual popup. I believe this is down to Flex giving all available cycles to other tasks... but it's proving difficult to investigate analytically so I am happy to hear another explanation.
To clarify, core parts of Flex are simply not working in this situation. I've stepped through the code for instance where a new element is added to the screen, everything happens and the addChild() method is called on the main display canvas... but then the element does not appear. If we then disable our update loop, the element suddenly appears.
So whether Flex is supposed to run the exact same code or not, somehow it IS blocking is some strange way. As I said, even the Flex Alert.show() method doesn't work.
All Flash content is executed frame-by-frame - Flash executes one frame's worth of code, then updates the screen, and then waits until the next frame update.
When Flash can't keep up with the specified framerate, all that happens is that instead of waiting between frame updates, Flash does them as fast as it can with no waiting in between. So the only visible difference is that frame updates occur less frequently. There are never cases where code is skipped, events are dropped, or screen redraws are skipped for performance reasons (unless you've found new bugs).
So the most likely culprit is that either you have a problem with code that's very time-dependent (such as code that expects two timers to trigger on the same frame), or some other problem that's being misdiagnosed. (For example, maybe there's a bug causing a slowdown, rather than a slowdown causing your bug.)
I'm not too sure if Flex has some additional performance handling of it's own. But for pure actionscript the only thing that would happen is the framerate would slow to a crawl, everything will happen normally just slower. If you stack very large amounts of transparent or masked objects you might get some weird behavior, but that should be more noticable.
And I guess telling you that making a game in Flex isn't that much of a good idea (just because of the performance overhead the framework has) is a bit late ;)
I like to make games in FLEX 3 (actionscript3), its actually pretty handy solution when compared to Flash CS3: good debugging environment without hassle.
Of course it depends on the game style which one is better, if you need lot of graphics you may like Flash more, but Flex allows you to use external images, components, etc. Notice I am not talking about Flex XML project here.
Answer to your performance issue: You can use e.g. old MacOSX machine to see what happens in a very slow machine, a few solutions are:
- move objects more than x++ y++ pixels when machine is old
- reduce objects
you can detect with a timer how slow machine is..

How to use "native" custom mouse cursors from within Flash apps?

The most common way of changing a cursor in Flash apps seems to be based on simply hiding the native OS cursor and displaying a graphic (drawn by the Flash Player) inside the Flash rectangle where the (hidden) cursor would be. This is what mx.managers.CursorManager does, for example. The reason why I find this approach unacceptable is that Flash Player isn't nearly fast enough at updating the cursor graphic, leading to some very visible lag in the cursor movement, which I find to be a pretty fundamental usability problem and annoyance, making the whole app seem slower than it really is.
On the other hand, I've noticed that the CSS cursor property implementation in browsers works like it should -- i.e. there's no visible lag in the cursor movement when using it to implement a custom mouse cursor.
So my question is: is there any way to use the CSS cursor property (or any other method that doesn't involve lagging, slow cursor movement) to change the cursor on top of a Flash rectangle?
I've already tried to change the cursor style property for a Flash element (or a Div wrapper around the Flash element) via JavaScript, but didn't seem to get it to work. Has anyone successfully done something like this?
Native cursors are available in Flash Player 10.2 beta. So you should give it a try! See: http://www.bytearray.org/?p=2373
I don't believe there is any way for Flash to use custom system cursors. In my 6 years of being a Flash Developer I've never heard of such functionality or a hack.
I understand your complaints, I too have been frustrated with how laggy the display-update can be. Thinking about the solution to use CSS to set a cursor-style in the browser though is an interesting approach... It smells, but off the top you may be able to implement control over the CSS cursor attribute from Actionscript using ExternalInterface. That way you could presumably communicate back to the HTML container calling some Javascript to modify the HTML page CSS at runtime. Not 100% sure that will work, but it may be worth a try if you are desperate. Otherwise it's probably advisable to stick with CursorManager.
The CursorManager is it, but I haven't had any problems with being laggy.
If you haven't already seen it, check out Colin Moock's CustomMousePointer classes. He has a bunch of AS3 examples and sample code from his Essential AS3 book posted at http://www.moock.org/eas3/examples/. Scroll down to, or search for, the Custom Mouse Pointer link. It's under the Chapter 22 heading.
The code in these examples, incidentally, was originally intended for use by Flash developers, so you may be able to optimize some of them for Flex by using objects that aren't available in Flash's implementation of AS3.
I believe Flash Player 10 will natively let you select the ibar, drag hand, finger or normal cursors, but if you're in Flash 9 this isn't possible and I don't believe a CSS hack will work either.
My advice is - use the MOUSE_MOVE event to position a graphic and set the frame rate as high as possible (e.g. 50 frames per second).
You could in fact accomplish this by writing an ExternalInterface that calls javascript to update the Mousecursor. jQuery functionality would work well here and it is something im doing in my new portfolio site for buttons and various areas of the flash app.
The new portfolio is not up yet, but should be within the next week or two for those are curious it will be at http://chrismcintoshdesigns.com

Resources