Global Variables in AS3 · 16 August 2007, 10:50
Sometimes is just makes sense to create variables that are accessible from anywhere in your project. Prior to AS3 it was really easy… _root.myvar = 'mystring' or _globals.myvar = 'mystring. While these methods were easy, they are considered sloppy from an Object Oriented point of view. Since AS3 is all about OOP, I am not surprised Adobe nixed the AS2 _globals and _root in AS3.
So how do we create variables in AS3 that are globally accessible from anywhere a project? Well, its as easy as building a class with a static variable container. Let’s use an Object as our variable container as they are dynamic meaning we can add properties (our variables of any type) at runtime. Here is the class:
package com.greenethumb.utils
{
public
{
public static var vars:Object = [];
}
}
To use this global variable container, just import GlobalVarContainer into whatever class you would like to read/write/create your global variables. Here is a sample:
package
{
import flash.display.Sprite;
import com.greenethumb.utils.globalvars.GlobalVarContainer;
public
{
public
{
GlobalVarContainer.vars.groupingID = 1
GlobalVarContainer.vars.mediaID = 4
GlobalVarContainer.vars.facultyID = 5
GlobalVarContainer.vars.studentID = 2
}
}
}
Werd up… globally accessible vars in AS3
EDIT — 11/15/07:
If anyone is looking for a more robust global variable solution, i highly recommend looking at uza’s GlobalObject class. It uses a nice hash map and dictionary to track the variables and dispatches events when variable are modified…. it nice!
☆ Jonathan Greene
thanks, I’m confused by this problem.
this post is great help to me.
— syler · Nov 15, 02:38 AM · #
but how do you do access the global variable from inside the fla file.
— atishay · Dec 3, 05:31 AM · #
hey atishay,
the _globals object no longer exists in AS3. It is not a part of the Actionscript Virtual Machine 2 (Flash player 9’s AS3 runtime). You can use this static GlobalVarContainer class to replicate the functionality of the _globals object. If you need to reference the GlobalVarContainer in your FLA, you do it the same way as you would access it from a class in a package: import the GlobalVarContainer class and read and write properties to its vars property. Hope that clears things up.
— Jon · Dec 4, 12:57 AM · #
Thanks Jon, this was really helpful!
— Johan Nyberg · Dec 10, 08:58 AM · #
One question – where is the document class instanciated? Is there a way for other objects in the fla to access public properties of the document class?
Can’t seem to find your email on the site, so it you care to drop me a line I’d be really grateful. :-)
— Johan Nyberg · Dec 10, 09:15 AM · #
Hey Johan, the Document Class is instantiated when your SWF is initialized. The Flash Player will automatically call the constructor function of your Document Class when your SWF initializes. If you do not specify a Document Class for your project, the compiler will automatically create a MovieClip instance an assign it as your project’s document class.
It is possible to reference members of the your Document class from other elements in your FLA. For more details on that have a look at http://greenethumb.com/article/23/understanding-root-and-the-document-class-in-as3.
— Jon · Dec 11, 01:03 PM · #
hey, just a heads-up re AS3’s ‘static’ keyword. i’m not sure whether this is a bug or a deliberate design decision, but the ‘static’ness of a variable does not propagate up the document tree to the root.
let me give an example. suppose you have a document class MyDocumentClass that loads as two children movie_a.swf and movie_b.swf. suppose also you have class MultiLangManager, with a static function GetInstance() that fetches the static singleton instance, constructing a new one if necessary. like this:
(ps your blog commenting system’s ‘@’ code modifier is @broken@)
now, at some point movie_a.swf calls MultiLangManager.GetInstance(). MultiLangManager goes ahead and constructs the singleton. sometime later, movie_b.swf calls MultiLangManager.GetInstance(). you’d expect MultiLangManager to return the existing instance. it is static, after all, right? wrong. what you get is another singleton, that is also static, but only ‘locally’ static. you know this, because the console says “constructing singleton instance” not once, but twice.
thanks Adobe. you suck. when on earth this could be useful, i have absolutely no idea.
the way around this is, if you add to the MyDocumentClass constructer, the line
MultiLangManager.GetInstance()
it will construct a properly singleton properly static instance that is then visible by both movie_a.swf and movie_b.swf.
which means, of course, that MyDocumentClass has to know which static things both movie_a.swf and movie_b.swf are going to access. considering the fact that ‘static’ is supposed to be an elegant work-around to the problem of sharing data between instances without requiring some tight coupling in the middle, Adobe’s implementation is somewhat broken, to say the least, since it brings the coupling issue right back to the foreground.
— damian stewart · Jul 31, 07:42 AM · #
Meh, so much work for global variables.
Why the heck couldn’t they add a global var myvar=1;
to make things simple.
>_< I hate Adobe.
— ex · Aug 26, 06:43 AM · #
Anyone who needs a cross project (multi SWF file) please read carefully the comment above me by damian Stewartws. Only his fix makes it work cross-SWF.
— Barak Siman Ov · Sep 4, 08:00 PM · #
thanks for the tips guys. i have not run into this prob yet… could it be when you are loading in your child swfs they are not given access to the DocumentClass’s application domain? Not sure… just wondering…
and yeah, posting code in comments on this blog is pretty broken :)
— Jonathan Greene · Sep 4, 09:14 PM · #
Im confused… So how is this set up in th FLA?
I put the as code above with the GlobalVarContainer statements in an as file and import it yes? Then what in the fla?
— Jim Smitze · Sep 30, 11:00 PM · #
Good tip, thanks!
Let’s say I have 3 classes. Is it possible to have a public static boolean that can permeate through each class? I’m worried that by importing the var into another class and changing it’s value there it won’t reflect the change if used in another class. Or will it?
— Jonathan Dumaine · Oct 11, 11:28 PM · #
Is there a way I can send a _global value from AS2 to AS3? The main movie is created using AS2 then we migrate to AS3 and I made a mistake of using AS3 in the child movie that needed to be called into the main movie (AS2). Now I have a problem sending the _global variable from the main movie that the child movie (AS3).
— Thomas Brown · Oct 23, 10:13 AM · #
Thanks so much. I’ve been having problems with development ever since global vars were taken out.
— Nick · Nov 18, 06:48 PM · #
Ref message 25, can you explain more? I tried the code below but get “1046: Type was not found or was not a compile-time constant: GlobalVarContainer.
import com.greenethumb.utils.globalvars.GlobalVarContainer;
var gvc:GlobalVarContainer = new GlobalVarContainer;
gvc.vars.groupingID=1;
— John · Nov 19, 04:07 AM · #
As to the comments regarding static properties in the use case of Singletons. If you load movies using the same context, your Singletons (and static properties) will function as you expect.
Adobe has provided different contexts for each movie that is loaded externally. This, my guess anyway, is a security feature to help sandbox externally loaded SWF files. But it doesn’t explain why calling the Singleton once from the main movie before calling it in the loaded movie also fixes the problem. That unfortunately makes no sense at all to me.
— Eric Stewart · Nov 25, 01:13 AM · #
eerr you can do it like this? why all that package and complex stuff?
var strGlobal:String = “Global”;
function scopeTest()
{
this is from the adobe site i think trace(strGlobal); // Global
}
scopeTest();
trace(strGlobal); // Global
this is from adobe site i think
— John · Jan 7, 11:41 AM · #
Thanks! I was sick and tired of sending events around
— Atro · Feb 12, 08:19 AM · #
Thankz a lot Jon. but I was wondering why static on declaration of variables.
This is my first code before I seen this site:
@package gv{@
@ public class globalVars{@
@ private var sessID:String;@
@ public function setSessID(sessVar:String):void{@
@ sessID = sessVar;@
@ }@
@ public function getSess(sessVar:String):void{@
@ sessID = sessVar;@
@ }@
@ }@
@}@
I was wondering why I get “Could not assign to static class [somthing]…”. Are Strings or Objects are normally constructed as static? My apology I have a little background on OOP.
Thankz a lot.
— paulcortez · Mar 16, 12:02 PM · #
Hey Paul,
When a property is declared with the ‘static’ attribute, it means that that property is accessible on the Class level, not the instance level. By declaring a static method or property, you can access it without constructing a new instance of the class. You have probably used the Math class before. When you call Math.random(), you are really calling the static method ‘random()’ on the Math class. If the random() method was not static you would have to do something like:
var myMath:Math = new Math()
var rand:Number = myMath.random();
instead the:
var rand:Number = Math.random() is a nice shortcut.
Static methods and properties are used a lot in Utility classes.. or classes that just store or process information.
In your example above, you would have to create a new instance of the your class and write your sessId variable to that instance. You could run into problems, because you could have more than one instance of your global vars object, meaning more than one sessId.
Although it might be getting out of the scope of this thread, a Singleton Pattern might be of some use to you, although this GlobalVars example will only allow for a single instance of itself :)
btw, sorry for my comment code tags being busted… ill fix that eventually
— Jonathan · Mar 16, 07:21 PM · #
How do you access the global variables set from other classes within the project?
— matt Booth · Mar 22, 02:27 AM · #