Optimizing tweens - actionscript-3

What is the best way to clean up after tweens in AS3 no matter what library you are using (or the built-in tween classes). Is there a best-practice or is it specific to each tween library?

If with "clean up" you mean to clean up the memory used for animations in flash, try
System.gc();
to fire the garbage collection. It will sweep everything out what is not used or lost its reference.
Recycling is also a good idea, even though it highly depends on your coding style and actual project.
For more information on the garbage collection, see the reference.

Related

AS3 Tween Freezes

I started using AS3's Tween function but noticed some strange behavior every once in awhile. Basically, it freezes before it finishes the tween.
This website seems to offer the solution:
http://www.rgbeffects.com/blog/actionscript/tween-freeze-frustrations-avoid-actionscript-tweens-stalling-out/
My program requires that the rotation tween works precisely every time. I like to use the functions adobe put in place but this makes me nervous since it has such a big issue.
Should I be using AS3's tween or some external tween like greensock.com's TweenLite?
Which would be more reliable?
Most likely your tween instance is being prematurely garbage-collected, because you don't store a reference to it somewhere. This is a common mistake which you can easily Google for.
Solution: store a reference to Tween instance while it is performing animation to save it from GC.
Follow the link for detailed explanation: AS3 Garbage Collection, the reason your tweens are ending early.
Official article on adobe.com also mention this problem (see note at the bottom of article):
Note: Consider variable scope when using the Tween class. If a tween is created in a function, it is important that the variable's scope exists beyond the function itself. If a tween is stored to a variable of local scope, ActionScript garbage collection removes the tween as the function completes, which will likely be before the tween has even begun.
And here are some links on garbage collecting if you would like to learn more on GC logics.

Does AS3 have a class destructor?

My question is as simple as the title, yet googling it didn't give me a simple yes/no answer.
Does AS3 have a class destructor?
In short: no, it doesn't. Flash Player virtual machine uses garbage collector concept. You don't have direct control over memory used by objects (except for rare cases like BitmapData.dispose() and ByteArray.clear()), but you are to do some work to make garbage collecting possible. And there is no way you can have something triggered automatically when an object dies.
Follow the links to learn more about GC logics.

Garbage collection - manually wiping EVERYTHING!

I have been building a game for a while (nearly done) - But the game needs a replay button and its a big task.
I know the GC is dreadful in flash, but I wanted to know if there is a way to wipe EVERYTHING as if the flash app has just begun. Clearing memory, game data - I haven't to worry about game loading as its not really heavy on data.
Everything pretty much lives in a DataModel - but I fear if I just clear the all variables, I'll have pockets of orphaned memory.
Any forwarding idea would be great.
cheers guys.
I would do this:
make a class that encapsulates your entire game, called GameContainer or whatever.
Do a search on all your source code, and make sure that in every call to addEventListener, you are passing true for the "use weak references" argument.
In your document class (or frame script), make a single instance of GameContainer and add it to the stage, and do nothing else.
Now when you want to entirely clear your game from memory, remove GameContainer from the stage and null the reference. Memory will not immediately be released, but everything in your game will now be eligible for release. If Flash thinks it needs more memory it will trigger a GC, and the large orphaned GameContainer will be nuked. (Step 2 above will keep your event listeners from counting as references to your objects, and make sure that all self-contained objects are eligible for disposal.
Not sure what you mean about Flash's GC being dreadful though. I can't recall having heard of any bugs in it. It won't nuke your objects unless you are careful with your references, but that's true of all garbage collection.
Not short of refreshing the page. There might be some hack you could do by loading a separate swf and then unloading it, but that would be just as error prone as doing it the proper way.
My advice would be to just buckle down and write your reset function then get something to monitor memory and make sure it works by reiniting/resetting a bunch of times.
The problem with Flash's garbage collector is that as far as I know you cannot FORCE it to "collect". I had this issue with a program in which I would load in various external SWF's, and occasionally Flash would simply not load them. What you may need to do is make a function to set every major variable in your code to null at the end of a game, if you want a true reset.
There is still no guarantee, but unfortunately I'm fairly certain there is no shortcut to force a memory release.
(For me this meant also making sure my event handlers were cleared properly, and my loaders would "unload()" after passing their content off, in the case of my external SWF loader.)

AS3: Faster to use EventListeners or ArrayLoops?

I am writing a game in AS3 and have, as an example, around 40 objects on screen. Let's say they are clouds. I'm wondering which of the two paths would be less a strain on system resources:
a) Put an eventListener on each object and have it update itself, or
b) Loop through the array and manually update each object
Or is the performance difference negligable? Does either solution scale better than the others?
I would expect the performance to be fairly negligable either way. Once you get a lot of objects you might see a difference (with the loop being the winner). From my experience Adobe put a lot of work into optimizing the actionscript event listener path.
This is a tricky one, purists would say to to go with the array looping method, as with this method it would be possible to cut out the 'view' out of the MVC and still have the system working (which is a good test of any system). However, if you are working with the events you can cut some corners with event bubbling and strict typing.
For example if we assume you make a custom event called CloudEvent that has a property called cloud that contains a reference to the dispatching CloudSprite, then as long as the event bubbles by default, you don't need to add an event listener to each one, just to the DisplayObjectContainer which holds them (which I am imaginatively calling CloudContainer). This way the event bubbles up and you only have to add one listener, and don't have to worry about managing listeners on child items.
public function CloudContainer()
{
super();
addEventListener(CloudEvent.CHANGE, cloudChangeHandler);
}
private function cloudChangeHandler(evt:CloudEvent):void
{
var cloud:CloudSprite = evt.cloud;
cloud.update();
}
Hope this helps
I am under the impression that event listeners require more resources so it is better to use an array when performance is required. It would also scale better for that reason. If you are using Flash 10 then use a Vector, I believe it offers better performance than an array (and type saftey).
Use EventListeners! Just make sure you manage them properly ie. remove them when you done, use weak references.
You wont really find much performance from doing things like this. Usually better performance comes from the bigger ticked items, like not using filters, lowering the frame-rate etc. So punishing your code clarity and OO for the sake of a half a millisecond is not worth it in my book.
There are a few really great guides out there that will teach you all about optimizing in AS3. The best one I have found is Grant Skinner's; AS3 Resource Management. And I just found a quicker seven step version. I would definitely recommend everyone doing AS3 should read the Grant Skinner slides though.
Of course don't just take my word (or anyone else answering your question), you can do you own tests and actually see whats up using a profiler. See Lee Brimlow's latest video tutorial for how to do this. It is worth the watch! Check it out here: GotoAndLearn - ActionScript 3 Performance Testing.

FLVPlayback component memory issues

My website is entirely flash based, it moves around a 3D model which was given to me as chunks of video that I've converted to FLV files. I'm using the FLVPlayback component to control the video inside of my program. While running memory checks using System.totalMemory I've noticed that whenever a video is loaded, it will eat up a chunk of memory and even when I remove all the event listeners from it(they are all weakly referenced), remove the component from its parent, stop the video and null the component instance, it still will not give that memory back.
This has been bothering me since I started working on this project because of the huge amount of video a user can potentially instantiate and load. Currently every video is loaded into a new FLVPlayback instance whenever it is required, but I have read that perhaps the best way to go about this problem is to simply have a global FLVPlayback instance and just reload the new video into the old instance, that way there would only be one FLVPlayback component in the application's memory.
Has anyone else run into this problem as well? Have you found a better solution than using a global instance that you just re-use for every new video?
I've never really liked the components, they're a bit dodgy. This particular problem seems to be common, and the somewhat annoying solution is, as you're suggesting, to only have one FLVPlayback and reuse that.
Here's a blog post about it
You can't help the memory problems much until Flash adds destructors and explicit object deletion, unfortunately. See this thread:
Unloading a ByteArray in Actionscript 3
There's a limit to how much memory Flash applets can use; the GC seems to fire upon reaching that limit. I've seen my memory-easy applets use as much as ~200MB, just because they run for hours on end and the GC doesn't want to kick in.
Oh, and I don't think using a single instance is an elegant solution, either. Currently I just write a dispose() function for my custom classes, waiting for some day when it can be turned into a proper destructor.
From what I gather after a lot of testing is that flash dynamically loads in libraries and components as needed but never garbage collects that data. For instance, if I have a website or an Air app that uses the FLVPlayback component, the actual component and libraries associated with it aren't loaded until a new FLVPlayback() instance is created. It will then load in the library and component into memory but you will never get that space back until the program / website is closed. That specific instance with the video inside of it will get garbage collected and release some memory as long as you remove listeners from it, take it off the stage, and set it to null.
Also, if you are doing individual videos, the VideoPlayer is much lighter weight, and cleans up nicer.
Thanks for the responses, the links to the other blog questions were helpful as well, I had read all of Grant Skinner's info on garbage collection too, but searching through those links and going back and re-reading what he had originally said about GC helped refresh the old noggin. In addition to nulling and re-instantiating that single FLVPlayback component, I also realized that I wasn't correctly unloading and destroying my Loader instances either, so I got them cleaned up and now the program is running much more efficiently. I would say the memory usage has improved by around 90% for the site.
#aib I will admit the single instance solution isn't elegant, but because flash just won't let go of those FLV files, I'm kind of stuck with it.
#grapefrukt I detest the flash components, they typically cause more grief than time saved, however in this case I had a lot of cue points and navigation stuff going on with the video files and the FLVPlayback component was the best solution I found. Of course I'm still fairly new to the ActionScript world so perhaps I over-looked something.
Unfortuantely, thats just the way flash handles it. Not particularly smart, but it works for most people.