Papa De Beau
Papa De Beau

Reputation: 3828

as3 declaring a GLOBAL variable - in TIMELINE / outside of CLASS

I am looking to declare a GLOBAL VAR in the main time line.

Then I need to access that GLOBAL VAR from another externally loaded SWF's.

QUESTIONS:

How do I create the global var in the main timeline?

How do I access that var in externally loaded swf files?

Upvotes: 0

Views: 5824

Answers (2)

Amy Blankenship
Amy Blankenship

Reputation: 6961

First, you shouldn't use any global/static state. In your situation this is even more true, because Singletons are a royal pain in the butt across different applicationDomains.

Instead, you should use something called Dependency Injection. Think of your little swfs as starving orphans. When they have loaded, they don't run up to your main swf and pick its pockets. Instead, the main swf magnanimously presses money into their little hands.

So, how do we make this happen? One way is that we could compile a reference to their Document class(es) into the main swf, and then we could set a variable that the Class exposes. However, this can get pretty heavy and isn't really necessary.

Instead, you can write something called an Interface, which defines the "idea" of an orphan.

It might look something like this:

public interface IOrphan {
   function get alms():Number;
   function set alms(value:Number):void;
}

Note that you have to use getters and setters with Interfaces, because you can't use them to define vanilla variables. However, that's going to work out great for our actual Orphan:

public class Oliver implements IOrphan {
    private var _alms:Number;
    private var _totalAlms:Number;
    public var tf:TextField;//put this on stage and allow Flash to populate automatically
    public function get alms():Number {
       return _alms;
    }
    public function set alms (value:Number):void {
      _alms = value;
      _totalAlms += _alms;
      updateAlmsMessage();
    }
    private function updateAlmsMessage():void {
       tf.text = 'That was a donation of ' + _alms + '.\n'
                 'I now have ' _totalAlms + '.\n'
                 'Please, sir, can I have some more?';
    }
}

Now, all you need to do is populate that variable on load. There are several ways you can do this, such as watching the stage for IOlivers to be loaded, or you could be more direct about it:

private function loadSwf(url:String):void {
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
            var request:URLRequest = new URLRequest(url);
            loader.load(request);
            addChild(loader);
}

private function completeHandler(e:Event):void {
   ((e.target as LoaderInfo).content as IOrphan).alms = .25;
}

Upvotes: 2

Chris Riebschlager
Chris Riebschlager

Reputation: 1333

If these are variables that you only want to set once and will never change, you can just create a class that holds static constants.

package
{
    public class Env
    {
        public static const WHATEVER:String = "Whatever!";

        public function Env()
        {}
    }
}

Then you could access them later in your program like so:

trace(Env.WHATEVER);

However, if you want global variables that can change, I like to handle this by using a singleton class.

package 
{
import flash.events.EventDispatcher;

public class Control extends EventDispatcher
{
    //---------------------------------------
    // PRIVATE & PROTECTED INSTANCE VARIABLES
    //---------------------------------------

    private static var _instance:Control;

    //---------------------------------------
    // PUBLIC VARIABLES
    //---------------------------------------

    public var whatever:String = "Whatever";

    //---------------------------------------
    // PUBLIC METHODS
    //---------------------------------------

    public static function get instance():Control
    {   
        return initialize();
    }

    public static function initialize():Control
    {
        if (_instance == null)
        {
            _instance = new Control();
        }
        return _instance;
    }

    //---------------------------------------
    // CONSTRUCTOR
    //---------------------------------------

    public function Control()
    {
        super();
        if (_instance != null)
        {
            throw new Error("Error:Control already initialised.");
        }
        if (_instance == null)
        {
            _instance = this;
        }
    }

}
}

The difference here is that you need to grab the instance of your singleton before you can get to what's inside it. It'd look a little bit like this.

private var _control:Control = Control.instance;
// Reading a global variable
trace(_control.whatever);
// Change a global variable
_control.whatever = "Foobar!";

So whenever you change "whatever", that variable will change for all loaded SWFs. If you want to be really fancy about it, you could use getters/setters in your singleton rather than simple public variables.

Upvotes: 1

Related Questions