View Single Post
Old 09-08-2006, 07:52 PM   #219
senocular
If you can read this, I'm
 
senocular's Avatar
Location San Francisco, CA (USA)

Posts 17,266
Access to stage and root

In Flash it is often useful to reference the main timeline, or the root, of a movie. In ActionScript 3, the root instance of the SWF loaded into a player represents the first instance of the stage (flash.display.Stage). The stage object in Flash is the primary container in which all other display objects, including root, exist.

A Flash application only has one stage. However, there can be multiple root instances in an application if external content is loaded into the player using the Loader class (flash.display.Loader).

All DisplayObject (flash.display.DisplayObject) instances have stage and root properties. These properties, however, are null unless the display object is attached to the stage or a display list that is attached to the stage. The stage property, when accessible, will always reference the stage object. The root property references different objects depending on the display object:
  • For the stage, root always references the stage
  • For the main timeline of the SWF and all display objects within it, root references the main timeline
  • If an object is added directly to the stage from any timeline, the root property for it and its children references the stage
  • For display objects in loaded SWF files, root references the main timeline of that SWF file
  • For loaded bitmap images, root references the Bitmap instance of the image loaded
  • Loader objects used to load external SWFs and images follow the rules of all other display objects within the SWF it is being used

Keep in mind that only display objects have access to stage and root and only when attached to the stage or a display list on the stage. This is contrary to ActionScript 1 and 2 in two respects:
  1. All "display objects" (movie clips) in AS1 and AS2 were attached to the "stage" or an active timeline upon creation. This is no longer true with AS3; in fact, the only display object which is inherently attached to the stage upon instantiation is the document class (or, in Flash 9, objects existing on the timeline in the IDE before publish).
  2. All ActionScript in AS1 and AS2 are defined in timelines, even classes. AS a result, essentially all scopes gained access to _root through the timelines (MovieClip instances) in which they were defined. Since classes in AS3 are not defined in timelines, they no longer have access to root (or stage) unless they themselves are DisplayObject instances already attached to the stage

This greatly limits your access to stage and root within your scripts. For example, non-display object classes in AS3 can only access stage or root if explicitly given a reference. Ex:
ActionScript Code:
package {
   
    import flash.display.Stage;

    public class CustomObject {
   
        private var stage:Stage;
   
        public function CustomObject(stageRef:Stage) {
       
            // stage access through
            // constructor argument
            stage = stageRef;
        }
    }
}

Also, your display object classes will not inherently have stage or root access in their constructor unless they are used for the document/application class of your movie.
ActionScript Code:
package {
   
    import flash.display.Sprite;
    import flash.events.Event;

    public class CustomDisplayObject extends Sprite {
   
        public function CustomObject() {
       
            // stage not acessible until
            // added to stage or display
            // list on the stage
            trace(stage); // null
        }
    }
}

This can make it difficult if you need to access the stage for things like adding event listeners. You would need to either pass a reference of the stage (or root) to your custom display objects as with the CustomObject class or not attempt to access stage or root until the object has been added to a display list allowing it to be accessible. And for this you can manually call a setup or init function after the instance has stage accessible or detect it automatically using the StageDetection class (com.senocular.events.StageDetection). Note: As of Flash Player 9.0.28.0 - which was released with Flash CS3 - you have 2 new, native ADDED_TO_STAGE and REMOVED_FROM_STAGE events for detection access to the stage.

Another approach to stage or root access would be to create a static property of a known class that would be accessible from any class. This class can be instantiated in the document class or it can be a DisplayObject subclass and you can have your document classes extend it as opposed to Sprite or MovieClip. For example, if you have your document classes always extend this TopLevel class, any class would be able to access stage or root (assuming they want root to be the document class extending this) using TopLevel.stage and TopLevel.root.
ActionScript Code:
package {
   
    import flash.display.DisplayObject;
    import flash.display.MovieClip;
    import flash.display.Stage;
   
    public class TopLevel extends MovieClip {
       
        public static var stage:Stage;
        public static var root:DisplayObject;
           
        public function TopLevel() {
            TopLevel.stage = this.stage;
            TopLevel.root = this;
        }
    }
}

Example document class using TopLevel
ActionScript Code:
package {
       
    public class MyDocumentClass extends TopLevel {
           
        public function MyDocumentClass() {
            // code
        }
    }
}

Example non-DisplayObject class used in MyDocumentClass application accessing stage:
ActionScript Code:
package {
       
    public class RandomClass {
           
        public function RandomClass() {
            trace(TopLevel.stage); // [object Stage]
        }
    }
}

Of course, ideally, you wouldn't need reliance on a class like TopLevel, especially if you are developing classes that might be shared with other developers. If someone is not in a position to have their document class extend TopLevel or simply don't have access to the class, any other class referencing it would fail. Passing around a reference of the stage (or root) or using the added (or added to stage) event(s) would be a safer way to go.

__________________
senocular is offline   Reply With Quote

Sponsored Links (Guests Only) - Register | Need Help?