Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: Accessing the Stage in the stage mediator  (Read 7246 times)
dermdunc
Newbie
*
Posts: 2


View Profile Email
« on: March 28, 2010, 01:59:26 »

Hi All,

I'm fairly new to pureMVC so sorry in advance if this is an obvious question. What I'm trying to do is move movieclips around my stage. they're new locations are calculated based on where the mouse is clicked. This is my workflow is as follows

StartUpCommand is called and registers my stageMediator

I cast the viewComponent to a type of Stage

protected function get stage():Stage{
            return viewComponent as Stage;
        }



on StageMediator I add a movie clip to my stage as follows
stage.addChild(theScene);

I then have a loop for nesting multiple movieclips in this "theScene" movieclip
if (pointsArray != null)
         {
            for (i=0; i < pointsArray.length; i++){
               var studentEntityInstance:MovieClip = new StudentEntity();
               studentEntityInstance.name = "studentEntity" + i;
               studentEntityInstance.visible = true;
               studentEntityInstance.x = pointsArray.x;
               studentEntityInstance.y = pointsArray.y;
               studentEntityInstance.z = pointsArray.z;
               var attachedObj = theScene.addChild(studentEntityInstance);
            }


So this is my initial scene setup. i have an eventlistener on my stage listening for a mouseClick

A mouseclick then calls a command which calculates the new nested movieclips locations. This array is set in the proxy which sends a notification to the mediator letting it know the locations have changed. The mediator then updates the stage. This is where I'm having an issue - I'm not able to access the movieclips on my stage. I've tried the following

var currBalloon:MovieClip = MovieClip(viewComponent.getChildByName("studentEntity"+i))
var currBalloon:MovieClip = MovieClip(stage.getChildByName("studentEntity"+i))
var currBalloon:MovieClip = stage["studentEntity" + i];
var currBalloon:MovieClip = viewComponent["studentEntity" + i];

var theScene:MovieClip = MovieClip(viewComponent.getChildByName("theScene"))
var currBalloon:MovieClip = MovieClip(theScene.getChildByName("studentEntity"+i))

var theScene:MovieClip = MovieClip(stage.getChildByName("theScene"))
var currBalloon:MovieClip = MovieClip(theScene.getChildByName("studentEntity"+i))


But everything results in the following error
TypeError: Error #1009: Cannot access a property or method of a null object reference.

Anyone have any ideas where i'm going wrong? Any help really would be greatly appreciated as this is really starting to drive me insane.

Thanks,
Derm
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: March 29, 2010, 09:39:38 »

...I then have a loop for nesting multiple movieclips in this "theScene" movieclip...
Where is this loop?

The key here is that you want to wrap Mediators around these children as they are created, not try to go get them later.

Wherever the loop is now, I'd consider moving it to a command. That command would assemble 'theScene' movie clip and stuff all these children inside it. And as it does this, it would either:

1) Register a new mediator for each child (StudentEntityMediator)
or
2) Register a single mediator for 'theScene (SceneMediator).

We'll get back to a discussion of this decision this in a moment.

Once the scene object is created, stuffed with its children and either it or its children are mediated, THEN, the command would send a notification like 'ADD_TO_STAGE' to the StageMediator with the scene object as it's body, and the StageMediator would respond by doing the stage.addChild(note.getBody());

So back to the mediation of the scene and its children.

If you wrap a mediator around each child (StudentEntityMediator) you need to make sure that each mediator has a unique name. You can do this in a lot of ways, but here's one:

:
public static const NAME:String = "StudentEntityMediator";
public static var count:int=0;
public var id:int;
// Constructor
public function StudentEntityMediator( studentEntity:StudentEntity ) {
        super( NAME+String(++count), studentEntity);
        this.id=count;
}

You can now send position updates and other such notifications directly to a given StudentEntity. When you send a notification, do something like this:

:
var location:Point3D = getLocation(entityNumber);
sendNotification( ENTITY_POSITION_CHANGE, newLocation, entityNumber );

And in your StudentEntityMediator:
:
override public function handleNotification(note:INotification):void
{
    if ( int( note.getType() ) != this.id return // not directed to this entity
    switch( note.getName() )
    {
          case LocationProxy.ENTITY_POSITION_CHANGE:
          studentEntity.position = note.getBody() as Point3D;
          break;
    }
}

private function get studentEntity():StudentEntity
{
    return viewComponent as StudentEntity;
}

It depends on what you're really trying to do, but the above way is probably best because an individual entity can be updated directly.

The other option was to mediate the scene and you may still want to do that to build a channel to talk to the scene object for things like changing the background or whatever. But I wouldn't have it iterating through its children and updating their positions all at once if you could avoid it.

On a final note, you might want to have a look at the HelloFlash AS3 demo, which has lots of self-directed, independently-mediated sprites.

-=Cliff>
Logged
dermdunc
Newbie
*
Posts: 2


View Profile Email
« Reply #2 on: April 17, 2010, 12:58:35 »

Hi Cliff,

Sorry for the delay in responding - i'm doing this work in my spare time and have been away with work. Thanks a mil for your reply - it was extremely useful. It really helped clear up some of the confusion i was having.

So I now have
- A stage mediator
- A entity mediator (setup similarly to how you suggested)

My workflow now is looking something like this

- Setup my app
- Call a "create schema" command
    - This command generates the "bubbles" creating an individual entity mediator for each one
    - The command also creates an instance of theScene movie clip which is pretty much just a rectangle
    - As each "bubble" is created it is added to theScene instance
- TheScene instance is passed back to the stage mediator which adds it to the stage
- A mouseDown event which captures the mouse location and calls a command to calculate the bubbles new locations
- This fires off a mouseUpdate command which re-positions the bubbles

Now, the whole point of this app is to create a data schema which a user can navigate around. For the initial iteration this will be purely by mouse clicks. Now that I am embedding all my "bubbles" in theScene I need to add event handlers to the scene movieClip so my thinking was to create another mediator for theScene. Would this be bad practice. Basically what I will end up with is

- A stage mediator (which is pretty much just used to initialize the app)
- A theScene mediator for handling events on the main scene
- Various entity mediators for referencing the different bubbles
- Probably a menu mediator which will contain a user menu

My question would be - is it ok to have a stage mediator which is generally used just for initialization or would this be considered bad practice. Should I be setting up my stage in the designer and then just have the other mediators or does it not matter either way?

Thanks again for the help - it really is very much appreciated.

Thanks,
Dermot
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: April 18, 2010, 03:54:34 »

It'd be perfectly fine to set up the stage in your Flash IDE instead of building it and injecting the pieces of the hierarchy. However, in that case you still need a StageMediator, which has a reference to the stage at startup, so that it can reference the pre-existing components and wrap mediators around them.

This is the way it usually goes with Flex, where your MXML application file has generally defined most if not all of the view hierarchy at, so at startup the ApplicationMediator's job is to have a reference to the app and to wrap mediators around the appropriate children.

-=Cliff>
Logged
Pages: [1]
Print