1

I have used this code in my AS3 document class to remove all objects from the stage:

var _stage:DisplayObjectContainer = stage as DisplayObjectContainer;
while (_stage.numChildren > 0) {
    _stage.removeChildAt(0);
}

and this appears to be working very well with one exception. After I run this, a button can be pressed to re-load everything onto the stage. In this construction function, some conditionals are added to create event listeners for the stage if they don't already exist:

if(!stage.hasEventListener(KeyboardEvent.KEY_DOWN));
    stage.addEventListener(KeyboardEvent.KEY_DOWN, handle_key);
if(!stage.hasEventListener(MouseEvent.MOUSE_MOVE));
    stage.addEventListener(MouseEvent.MOUSE_MOVE, manage_cursor);   

EDIT: stage definitely is null, I put if(stage){} around this section of code, and the error cropped up at the next point in the code that stage is used

I receive an error however, on the reconstruct, TypeError: Error #1009: Cannot access a property or method of a null object reference. in reference to "stage".

Further research indicates that it might be possible that removing all DisplayObjects from the stage removes the ability to access the stage itself until a DisplayObject is added in. however, this doesn't make any sense to me whatsoever and I am not entirely sure how to proceed.

Any help would be greatly appreciated.

BumbleShrimp
  • 2,150
  • 23
  • 42
  • Could you perhaps post some more code? It sounds peculiar. If stage is null, how are you adding another DisplayObject to it? – Jonatan Hedborg Jan 09 '12 at 19:56
  • If you are calling "stage" from within a MovieClip, the reference will ONLY be non-null when the MovieClip is on the display list. Are you sure that's not what is happening? The Stage always exists once Flash is loaded, but individual MovieClip instances can gain/lose reference to it when they are added/removed from the display list. – meddlingwithfire Jan 09 '12 at 19:56
  • Well this is the document class's reference to `stage` , not a movieclip class's, so I am not sure how its possible for it to lose access... – BumbleShrimp Jan 09 '12 at 19:58
  • @JonatanHedborg I'm not adding another DisplayObject to it, I can't access it at all, which is why I was confused in the first place. I can't think of any more specific code that would be involved in this. The file is 500 lines of poorly commented and poorly structured code, so putting the whole thing probably wouldn't be useful to anyone. – BumbleShrimp Jan 09 '12 at 20:13
  • Unless it's referring to the "KeyboardEvent.KEY_DOWN" as the null object reference, which might make even less sense. – BumbleShrimp Jan 09 '12 at 20:16

1 Answers1

2

If you are calling "stage" from within a MovieClip, the reference will ONLY be non-null when the MovieClip is on the display list. The Stage always exists once Flash is loaded, but individual MovieClip instances can gain/lose reference to it when they are added/removed from the display list.

This even applies to your document root instance. As soon as any DisplayObject is removed from the display list, its' stage reference is set to null.

Here's an example using the root document that illustrates the concept:

package
{
    import flash.display.Sprite;
    import flash.events.Event;

    [SWF(width="800", height="600", frameRate="60"]
    public class Main extends Sprite
    {
        public function Main()
        {
            addEventListener(Event.ENTER_FRAME, onEnterFrame, false, 0, true);
        }

        private function onEnterFrame(event:Event):void
        {
            if (stage != null)
            {
                trace("stage: "+stage);
                stage.removeChild(this);
                trace("stage: "+stage);

               removeEventListener(Event.ENTER_FRAME, onEnterFrame);
            }
        }
    }
}

This code will output:

stage: [object Stage]
stage: null

Note the loss of the stage reference after removing the object from the display list.

In your example, you are looping over every child of the stage, and removing each of them. That will definitely cause your stage reference to be lost because of the same concept as shown above.

meddlingwithfire
  • 1,437
  • 8
  • 12
  • i have been trying putting something like `if(_stage.getChildAt(0) != this)` inside the while loop and around the `removeChildAt`, however when I do that, flash just crashes – BumbleShrimp Jan 09 '12 at 22:05
  • if I change `while numChildren > 0` to `while numchildren > 1` and do `removeChildAt(1)` instead of `removeChildAt(0)`, it effectively fixes my problem. I was guessing that the stage will be the first child on the display list, as it turns out I was right. Is this a stable method of handling the situation though? Is this safe to do? – BumbleShrimp Jan 09 '12 at 22:13
  • 1
    While it is probably safe to assume that your root document class is always the first child of the stage, I'd break a for loop out instead of a while. Then your code will explicitely show what it is trying to accomplish: `for(int i=stage.numChildren-1; i>=0; i--) { if (stage.getChildAt(i) != this) { stage.removeChildAt(i); } }` – meddlingwithfire Jan 10 '12 at 13:17
  • Thank you, for some reason this works in a for loop but not a while loop. Thanks again! – BumbleShrimp Jan 10 '12 at 16:20