In actionscript, why is my static class member variable not the same when accessed from different parts of my app? - actionscript-3

I have an actionscript class with a static member variable defined.
public class A
{
public static var x:int;
}
When I try to access it from different parts in my code I don't get the same value in each spot.
A.x
I am accessing the variable in different modules that are loaded, so they are all in their own separate .swf file. Could this by why?

Seems like an application domain problem. The main swf and the modules seem to be accessing their own copies of the A class. You should probably change the way you load your modules.
Check this out:
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/system/LoaderContext.html#applicationDomain
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/system/ApplicationDomain.html

Related

Access to protected function in external swf

I've bought an external component composed by the MXP component and two external swf.
Obviously I haven't any source or fla file.
I've imported the component in my own project and it works fine (combined with the two external swf). Now I've debugged and decompiled one of this two external swf whith a stand alone program (SWF Decompailer) in order to find two functions I wanto to manage.
I've found their name [forceNextImage() and forcePrevImage()] and the class where they are declared.
The problem is that those functions are protected and I've the necessity to call them inside my project (the project where I've imported the components, of course). There's a way to do that? And how?
I hope I've been understandable even with my lacking english, but if not don't esitate to ask me..
Thanks in advance.
Fabrizio
Can you subclass it, and then call it from the subclass?
protected methods are callable from subclasses, so you can extend the component and expose them:
public class YourComponent extends Component
{
public function nextImage():void
{
forceNextImage();
}
public function prevImage():void
{
forcePrevImage();
}
}

Access external SWF classes other than document class AS3?

I'm loading an external SWF as you normally would and I am handling the COMPLETE listener with:
var documentClass:Object;
function onComplete(loadEvent:Event)
{
documentClass = Object(loadEvent.currentTarget.content);
}
This works perfectly and I can access variables and functions from the document class of the external SWF. However not all the other classes in the SWF's library aren't instantiated in the document class. I would also like to access variables and functions in these other classes, and I am currently using, for example:
var documentClass:Object;
var classOne:Class;
function onComplete(loadEvent:Event)
{
documentClass = Object(loadEvent.currentTarget.content);
classOne = loadEvent.target.applicationDomain.getDefinition("ClassName") as Class;
}
This also works. However, there are multiple other classes in the library which I want to access and it is extremely tedious to go through each of them using this method. I was hoping I could use getQualifiedDefinitionNames() (I'm using Flash CC and player 11.3 so it is available) but when I trace it, it doesn't seem to be working.
There has to be an easier way to access the other classes which I don't know of. Can anyone help?
Thank you,
James

Custom AS3 Class not Updating

I've had a similar issue to this, but the means that I solved the last one are not working here.
I have a custom class that consists of 12 separate .as modules. They're declared in the document class as follows:
import trailcrest.v1.s3.averta;
import trailcrest.v1.s3.chronos;
import trailcrest.v1.s3.eripio;
import trailcrest.v1.s3.fabrilla;
import trailcrest.v1.s3.gradua;
import trailcrest.v1.s3.lingua;
import trailcrest.v1.s3.navigare;
import trailcrest.v1.s3.pedem;
import trailcrest.v1.s3.praeferre;
import trailcrest.v1.s3.scriba;
import trailcrest.v1.s3.securos;
import trailcrest.v1.s3.sonus;
public static var Averta:averta = new averta();
public static var Chronos:chronos = new chronos();
public static var Eripio:eripio = new eripio();
public static var Fabrilla:fabrilla = new fabrilla();
public static var Gradua:gradua = new gradua();
public static var Lingua:lingua = new lingua();
public static var Navigare:navigare = new navigare();
public static var Pedem:pedem = new pedem();
public static var Praeferre:praeferre = new praeferre();
public static var Scriba:scriba = new scriba();
public static var Securos:securos = new securos();
public static var Sonus:sonus = new sonus();
This is a new version of the code. I am able to successfully refer to all of these classes and the public variables and functions inside in the "osr.as" document class. I can also SEE one module from another (i.e. Sonus can see Scriba using "osr.Scriba."
Where I'm having trouble is that, while the various modules used to be able to access all of each other's public functions and variables perfectly, after I added some new modules and variables and removed some old ones, Flash Professional is still literally USING the old version. Inside of any module, the code hints are showing all of the old public functions and variables, and none of the new ones.
I am guessing that this has something to do with some sort of temporary file that I can't get to. I absolutely need this working this week!
My .fla is "Tester.fla," and the document class is "osr.as." They're both in the same directory. Also in the same directory is the folder structure "/trailcrest/v1/s3/" which contains all of the Trailcrest modules.
Help??
EDIT: Whenever I try to reference one Trailcrest class from another Trailcrest class (i.e. osr.Sonus.foo), I get...
TypeError: Error #1009: Cannot access a property or method of a null
object reference.
I have confirmed beyond a shadow of a doubt all references.
This is the age old problem of what ultimately boils down to is the Verify Error. It happens when you embed "Class A" in one or more applications, modules, swfs, etc. Ultimately every output swf that uses "Class A" must be recompiled when "Class A" is changed. Otherwise you end up with a situation where 1 module has the newer implementation but others don't. This problem is compounded by the fact that the application domain is defined as a "first in wins" when it encounters a Class of the same name / package - meaning if the old one is referenced first, the newer one loaded later gets ignored.
The more permanent solution is to use class promotion to an RSL that ultimately allows the RSL to control the actual "Class A" reference in which it also implements an "IClassAImpl" interface that all modules use. This allows the compiler to cross link the reference with a signature it knows about without actually embedding the actual class itself.
Well, I finally figured it out. Here's the skinny on what was happening:
#1: Flash was apparently pulling an old version of the Trailcrest modules. To remedy this, I backed up everything and then removed all old instances of Trailcrest from my entire computer. Then, I put only the new modules back. That fixed the problem with Code Hints showing the old modules and variables.
#2: I had been experiencing Error #1009 whenever one Trailcrest class tried to access any component of another Trailcrest class, even though the references were all correct.
The cause was that I was calling functions on the various modules directly from the document class osr.as, outside of a function. This, of course, executes on the program start.
However, all the code within one Trailcrest class that called another Trailcrest class (i.e. osr.Sonus.foo) would not be able to access "foo" because osr.as for some reason or another hadn't finished initializing the classes before it ran the code that called them. This occurred, even though the problem code was well below the code that initialized the classes (see my question).
To fix this, I simply had to wrap the problem code into a public static function in the document class, and then call it from the Timeline. That ensured that all the classes were initialized before they tried referencing each other.
Needless to say, everything is running like a well-oiled machine now. How weird.
I'd welcome any explanation as to WHY this fixed the problem.

AS3 - Global classes?

I know global variables are supposed to be bad but is it possible to create global classes? I am creating an application and I want to have one class that handles sound. From any class I would like to be able to say soundhandler.playSound(); without having to pass references all over the place. It should just know it is there.
Any help greatly appreciated.
You're referring to static members.
Your class SoundHandler would have a static method called playSound(), which can be implemented like so:
package
{
public class SoundHandler
{
public static function playSound():void
{
// #todo Logic
}
}
}
Your playSound() method is now accessible via:
SoundHandler.playSound();
Note: You mentioned global methods being bad, however this is a perfect candidate for these and something I would actually recommend (as much as I hate using static).
Additional: ActionScript 3's Math class contains mostly static members e.g. Math.round()
Your question (comment): Do I need to initiate SoundHandler in the document class?
No, in fact you shouldn't make an instance of SoundHandler at all. The only requirement is that you must have SoundHandler imported in your current class to access it:
import yourpackage.SoundHandler;

Accessing Variables in another class?

First off I don't understand classes, how to "call" or "initiate" them. I'm class ignorant.
I have two .fla files. One of my .fla files consist of 15+ .as files; we'll call this one XML editor. The other .fla file consists of 10+ .as files; we'll call it the interface.
The xmleditor.swf loads the interface.swf.
Within the xmleditor.swf, a login screen appears and the enduser logs in as either a "user" or an "admin". The "user" or "admin" is stored in a public variable called "userType". The userType variable is created in one of the many xmleditor.fla .as files called Login.as.
Once logged in, xmleditor loads the interface.swf. interface.fla uses 10+ .as files. one is called nodeNames.as I need an if statement in nodeNames.as that is something like this:
if (Login.userType == "user"){
trace("do something");
}
I have the following FlashVars.as file but I have no idea what the steps are to make it work.
package extras.utils {
import flash.display.Sprite;
import flash.display.LoaderInfo;
/* In AS3, we need to have a display object on the stage to access FlashVars
* this class can be used once, and then referenced from anywhere as
* FlashVars.data.variableName
*/
public class FlashVars extends Sprite {
public static var data:Object;
public function FlashVars() { }
public function load():void { //Only needs to be called once
data = this.root.loaderInfo.parameters;
}
}
}
Should I use this FlashVars? and if so, how?
Or is there an easier way to access the variable?
well, from what i understand, you Login.as is a class. Then you have two ways of accessing the Login.userType variable : if you want to be able to call it with
Login.userType, you'll need it to be static in your class
public static var userType:String
it is then accessible using Login.userType from anywhere in your application, as long as you import Login.
But it is often considered bad practice to have too many static vars in your app, especially from different classes. so you may want to have an instance of your login class stored in a variable somewhere in your app, along with anything you need
var myLogin = new Login();
myLogin.userType = 'value';
But be aware that this way, every new Login() will carry it's own different userType, so you will want to pass along myLogin to any object needing it.
Object programming can be confusing, but is very powerful, i suggest you read about it (in books or on the web) since the whole thing can't be explained here.
Have fun!