Deleting everything from the stage AS3 - actionscript-3

So, I am wanting to clear my whole stage. I already searched through the internet, and unfortunately nothing has worked for my situation.
Basically, what I am doing is a somewhat complex maze generator and before I create a new one, I want to get rid of everything I created prior to that. So far, I hear that the best way to remove movieclips from the stage is buy using:
while(numChildren > 0)
removeChildAt(0);
However this only works for the current movieclip I call it in, which doesn't include the maze I generated. I just want to get rid of absolutely everything.
Any ideas on how to do this?

You're thinking along the right lines, you can use numChildren and removeChildAt however you need to call them in the scope of the stage:
while(stage.numChildren > 0)
{
stage.removeChildAt(0);
}

To just remove it from the stage:
stage.removeChildren();
Just removing clips from stage isn't always equal of removing them from memory
removeChildren, removeChild or removeChildAt does not actually remove an Sprite or any other DisplayObject from memory, it only removes it from the displaylist. That means if you create 1000 sprites and add them to the stage (displaylist), and then use removeChildren they could still exist in memory (forever). Then you have a memory leak.
To remove it from memory, all objects with a relation to the displayObject should be set to null. This includes event listeners and relations from / to non-displaylist related objects.
If you want to be sure all related stuff should be gone, just null it and check these things:
Remove it from the displaylist using removeChild or removeChildAt or removeChildren. (note this can be done from the stage)
Remove all eventListeners that are attached to the clip, or use weak event listeners.
If you used a reference in an Array, Vector, Dictionary or any other object, remove it from the object, set it to null or splice it using Array.splice()
setTimeout/setInterval should be cleared
Set the object = null
You can profile the memory with Mr Doob stats or performance stats from the Temple Library. You should see a drop (garbage collection) after a while when removing all clips. After removing multiple times the memory indicator should not be higher.

Related

How does AS3's addChild works?

I'm aware that addChild (1) adds the object into a display container object, and (2) shows the object in the DisplayObjectContainer. What I want to know is what happens when an object is added into a DisplayObjectContainer?
To summarize my question is (are),
Is there any magic happens when addChild invoked? i.e. Something is happening in, for example, DisplayObjectContainer.
Let's say, I have MovieClip A and B. B has A as part of it. I called addChild (A) in B. In MainTimeline and Stage, I don't call addChild (B). Visually, since B hasn't been added, A won't be there too. However, does A is exist (e.g. the memory allocated), even though it's not on the Stage?
I have searched here and there in SO, but humongous amount of the questions asked related to mine are technical. I greatly appreciate any answer or pointer regarding my questions
Here is simplified explanation of what happens.
When you create MovieClip A (or any object) using the new keyword (or if using FlashPro an item that exists on the timeline where the playhead is), that object is in memory. So whether or not MovieClip A is on the display list, it is taking up memory in your application.
When you use addChild, here are some of those things that happen (not necessarily in order):
If the object being added already has parentage, it is removed from that parent (though scale and position are kept, and will now be relative to the new parent).
Events are dispatched on the new parent (and the old parent if applicable). Event.ADDED and Event.ADDED_TO_STAGE + Event.REMOVED / REMOVED_FROM_STAGE on the old parent.
The parent(s) of the newly added object, will now take into account the new child/grandchild. Things like hit tests, and bounds, and mouse overs etc.
On the next frame tick (the stage's refresh rate), that item will be drawn
All that said, once a movieClip is on the display list, there is performance drain VS just having that object in memory - so if an object doesn't need to be seen, it's more efficient to have it off the display list until it needs to be seen.
If using FlashPro/Animate, you should also be aware that if through code you do anything that manipulates the parentage of a timeline display object (addChild/removeChild/setChildIndex etc), that timeline object will no longer be managed by the timeline. That means that if you have an empty keyframe to remove an item from the timeline, that item will actually stay on the screen until you either explicitly remove it (removeChild(item)) or it's parent goes away.

Removing movieclip in timeline - really gone?

I want a explosion to play when a object hits another object. I do this so that when hitTestObject is true, I run this function
function createExplosion():void {
var explosion:Explosion = new Explosion(enemy.x, enemy.y);
this.parent.addChild(explosion);
}
Explosion class only consists of setting the input to it's x and y values. Then in explosion movieclip I have a few frames of a animation. It ends in a keyframe (i.e., as an action in that frame) with the following code:
stop();
this.parent.removeChild(this);
My question is. Is it really gone now? I had to add stop() to not get error 1009. That makes me suspect some event timer is still running around?
Removing a display object from the display list, doesn't stop the animation or remove it from memory. It just removes it from the display list. Yes, you need to stop the animation and remove any event listeners that might be active for that object.
A display object is never truly gone until it is garbage collected. But that will not happen until no references to that object remain. So if you have a variable called explosion that references your display object, you need to set it to null after removing it from the display list :
explosion.stop(); // stop the animation
removeChild(explosion); // remove from display list
explosion = null; // remove variable reference
// explosion now qualifies for garbage collection.
Keep in mind that this doesn't immediately remove the object from memory, it just makes it fair game for the garbage collector. You can google "AS3 Garbage Collection" to get more information on that process.

ActionScript 3 Removing All RESIZE Event Listeners

I'm working on a Flash project which is separated into separate scenes.
In Scene 1 I have multiple MovieClips (which include event listeners for RESIZE (and others) inside them).
In Scene 2 I have a few common MovieClips and new ones (which also include event listeners for RESIZE (and others) inside them).
After clicking a button from Scene 1 to go to Scene 2, it's fine, except for if I resize the stage and then I get the following error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
I know it's related to the event listeners, but it would be unrealistic to remove them each individually as it's expected there will be many.
If I undertand your situation correctly, I think you will in the end need to remove each listener individually, or add the resize listener only once. Since you mentioned scenes, am I right to assume you are working on the timeline? I also am assuming the null object reference error comes from a scene that has been removed from the stage, making reference to a display object that is no more, a ref to the stage after the scene has been removed, or just calling a function (the resize handler) on an object that no longer exists.
Some way to deal with this are:
Add some checking in the listener handler functions
if (!this.stage) return
To avoid the errors, but will not help if the object the function is a method of has been removed.
To avoid needing remember to remove hundreds of listeners, create removeAllListeners and addCustomEventListener functions. Instead of the usual addEventListener, call you addCustomEventListener which in turn will call addEventListener. Have addCustomListener store the target, listener function and event string in a dictionary or array of objects. removeAllListeners can loop through the dictionary or array and remove all your listeners. It is a bit like setting up an event hub, but does not go quite that far.
Instead of adding the RESIZE event listener to each scene, add it only once. Then in the listener function call a function on whichever scene is the active scene or view.
This last one is the approach I have seen most often, and is the most bullet proof. It may be tricky to implement on the time line, I have always been a little hazy on timeline variable scope.
Yes, so far as I know there is no good automated way to do this, however it would be a good practice to create a registerAllListeners and a removeAllListeners methods that manually add and remove the appropriate listeners to your object.

Flash memory management and Actionscript

There was many discussions about this problem, but I want to pay attention on the situations that IMHO seems not so clear:
Yes the general rules are:
Remove chachedAsBitmap
Stop movieClip if playing
Remove events
Delete references
etc.
But let's look:
First Example:
I have nested sprite (ex: mainSprite), it contains other sprites with dynamic textFields in it (and are chached as bitmaps), just textFileds and MovieClips with event listeners on it (with weak reference).
When I need to remove this sprite I need first to remove all it's nested content via loops or just
removeChild(mainSprite);
mainSprite=null;
is just enough?
Second Example:
I have some sprite in which I'm loading bitmap and manipulating with bitmapData, later I'm just replacing content of this sprite with another bitmap, is allocated memory for older bitmap automatically erases and is overwritten or it still exists?
Third example:
I have some "graphics template" MovieClip (in library with Export for Actionscript property set on it) which I'm adding on the stage and filling with dynamic data (and adding event listeners), let's say that it's one scene of the app, on another scene I need same MovieClip with other dynamic data, but inbetween need to clear my stage (need something like transition animation which is also library MovieClip), what's the best way: to set this MovieClip visible property to false (while transition animation is plays) and then reuse it, or just remove it with removeChild and then add when add with addChild once more?
All I wrote is more about Air Mobile, cause in most cases for the desktop these situations aren't so problematic, but in case of mobile development they are.
You can visually monitor memory usage along with fps etc using this lib: http://code.google.com/p/flash-console/
hope that helps.
P.S. gc in flash is always a weird thing :)
First example: removing mainSprite from display list is enough if there are only weak listeners on its children.
Second example: I'd advice reusing the same object with visible = false. Recreating the same object is more resource expensive plus you get another instance of the same thing being in memory before it gets gc'ed.

ActionScript Clean Up

i want to deallocate a spriteClass from memory and remove it from the display list.
when the spriteClass is instantiated, it creates some of it's own sprites with new tweens and tween events and add them as children. i understand that the tween events must be removed in order for the spritClass to become available for garbage collection, and only afterwards should i remove and nullify the spriteClass, but should i also nullify and remove the spriteClass's sprite children and tweens as well, or does it not matter?
essentially i'd like to know if by writing
spriteClass.deallocate(); //removes it's tween event listeners;
removeChild(spriteClass);
spriteClass = null;
it automatically removes all of it's added children and new instantiations like tweens, sprites, rects, whatever, or am i responsible for removing them all along with event listeners from within my spriteClass.deallocate() function?
As far as I'm aware, any child sprites should not need to be nulled to trigger garbage collection as long as there aren't any references to them from elsewhere.
However, you would need to remove any listeners on the children assuming they are not weakly referenced (an optional argument to addEventListener).
Also for reference, you can check yourself if the garbage collector is doing its job with the Flash Builder Premium profiler (http://help.adobe.com/en_US/flashbuilder/using/WS6f97d7caa66ef6eb1e63e3d11b6c4d0d21-7e46.html)
P.S. You can use the Flash Builder IDE even if its a pure AS3 or Flash project.