Custom AS3 Class not Updating - actionscript-3

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.

Related

AS3 package issue

Really want to refactor and re-architect my project, it's become basically an 11k line monobloc that desperately needs to be split into multiple classes (and class files) inside a single package.
Yes I know I should have figured all this out when I started, but this is play not work and I was brand new to AS3 when I started. And I've kept building and building and it all works, it's just become very hard to manage.
My immediate goal is to define a package and then start breaking out function groups from the current main class into subclasses that extend the base. But I'm having a problem with the first step - defining the package.
I'm getting:
C:\Users\Vossie\Documents\Fex Line of Battle Project\trunk\line_of_battle\LOB_Core.as, Line 1, Column 1 5001: The name of package 'line_of_battle' does not reflect the location of this file. Please change the package definition's name inside this file, or move the file. C:\Users\Vossie\Documents\Fex Line of Battle Project\trunk\line_of_battle\LOB_Core.as
So I've checked:
package line_of_battle {
public class LOB_Core extends flash.display.MovieClip {
Filename is LOB_Core.as.
Path:
I explicitly added it to the class search path:
So:
Name of package agrees with name of folder (I actually pasted it from folder to .as file)
Package file is within that folder.
Class search path includes that folder
Shouldn't matter for this but filename and public class name match
I've searched stack overflow and one similar case involved a text case mismatch that I don't see here. One other related question the guy's question turned into just how to make classes and name the files correctly.
According to the documentation I read, this should work fine. Can someone tell me what I am missing?
Edit - This is the code that's triggering the error, LOB_Core.as:1102 -
var test:LOB_Scenario_Data = new LOB_Scenario_Data();
And the class that is calling:
package line_of_battle {
import line_of_battle.LOB_Core.*;
public class LOB_Scenario_Data extends LOB_Core {
public function LOB_Scenario_Data() {
// constructor code
trace("BIG MONKEYS");
}
}
}

Embedding png throws Error #1065: Variable FlexVersion is not defined

I've found several articles relating to variable FlexVersion and error 1065, but nothing seems to help.
EDIT:I've attempted to implement SEVERAL guides on embedding images into flashDevelop with the same result. Everything works correctly until I try to add the embedded image, then I get the above error.
Has no one here seen this error?
My Class (which I've stripped down to nothing in order to pinpoint the issue):
package {
import flash.display.Sprite;
import flash.display.Bitmap;
public class JMouse extends Sprite {
[Embed(source = "../lib/jacobsLadder.png")]
private var Picture:Class;
//private var pic:Bitmap = new Picture(); // THIS LINE
public function JMouse() {
init();
}
private function init():void {
}
}
throws the error when the line "THIS LINE" is not commented out. I've tried adding "as Bitmap" to the end of this line without luck.
I am calling this class from my document class:
jMouse = new JMouse();
the file, jacobsLadder.png, is in my lib folder, and I used FlashDevelop to "Generate Embed Code."
I am using FlashDevelop 5.0.1.3 for .NET 3.5
Any Ideas?
EDIT: I also tried this (and similar variations), as per the suggestion:
"The type of code you can run at variable declaration scope is limited. Creating an instance of Picture requires decoding and so will fail at that point. Instead create your instance of Picture within an instance methods or the constructor."
[Embed(source = "../lib/jacobsLadder.png")]
public static var Picture:Class;
public function JMouse() {
var pic:Bitmap = new Picture();
init();
}
But I get the same error.
The type of code you can run at variable declaration scope is limited. Creating an instance of Picture requires decoding and so will fail at that point. Instead create your instance of Picture within an instance methods or the constructor.
ANSWER: Load the bitmapdata with a loader.
Although the OP (me) was asking how to embed the file, the mysterious problem of "Error #1065: Variable FlexVersion is not defined" issue is apparently an insurmountable one, and I hope that anyone else who may come across this problem may find solace in the following (courtesy of John Mark Isaac Madison et al):
How do you load a bitmap file into a BitmapData object?
While not the an answer, per se, it at least allows the OP to continue on in his work as an alternative to lighting his house on fire.

passing custom events between modules through parent application

I have created a custom event that I want to use to pass a string between two modules. The event looks like this:
package com.mypackage.events
{
import flash.events.Event;
public class ThumbDeleteEvent extends Event
{
public static const THUMBS_DELETED:String = "thumbsDeleted";
public var files:String;
public function ThumbDeleteEvent(type:String, files:String)
{
super(type);
this.files = files;
}
// Override the inherited clone() method.
override public function clone():Event {
return new ThumbDeleteEvent(type, files);
}
}
}
In one module I dispatch the event like so:
parentApplication.dispatchEvent(new ThumbDeleteEvent("parentApplication.thumbsDeleted", files));
and in another module I listen for the event like so:
public function init():void {
parentApplication.addEventListener("parentApplication.thumbsDeleted", onThumbsDelete);
}
if I use ThumbsDeleteEvent as the type passed in to the listener function like this:
public function onThumbsDelete(evt:ThumbDeleteEvent):void{
trace("thumb delete event for thumbs: "+evt.files);
}
I get the following error:
TypeError: Error #1034: Type Coercion failed: cannot convert com.mypackage.events::ThumbDeleteEvent#26748a31 to com.mypackage.events.ThumbDeleteEvent.
if I just use Event as the type passed in to the listener function like this:
public function onThumbsDelete(evt:ThumbDeleteEvent):void{
if(evt is ThumbDeleteEvent){
trace("thumb delete event for thumbs: "+(evt as ThumbDeleteEvent).files);
}else{
var type:XML = describeType(evt);
trace(type.toXMLString());
}
}
It works but does not think it is a ThumbDeleteEvent type class (it hits the else statement) the xml output of describe type says its type is:
type name="com.mypackage.events::ThumbDeleteEvent"
What is going on here? If I put a breakpoint in the debugger it says the event is a ThumbDeleteEvent and I can see the files parameter and its right???
The issue here is that one swf has their definition of that class, and then the other swf has its own version of that exact same class. When trying to cast between them flash does a bytecode-check to see if the definitions are the same, and if you ever changed something in that as file without updating both with the exact same info you will run into this issue. That is, compile both swf-files, then change a space in the as-file, and compile only one swf file.
Urgh it's coming back to me, all those issues with shared code between different modules. I always just slug my way through these errors until I get it to work and can never really remember what it is since it can be so many issues.
Make sure both compiled swf-files have up-to-date-versions of the file.
Make sure both swf-files have same linkage-nesting to the code-file.
If that doesn't work [can't really remember since this issue is kind of like solve-once and copy to every other project].
See in which order things are added to ApplicationDomain and make sure nothing else has their own out-of-date-version of it through something imported in flash library
Move shared code into seperate code library linked in with "dynamic binding"
Try with sharing the Interface instead
Change how assets are loaded into the ApplicationDomain
Hopefully someone has more knowledge of this issue and can tell exactly what steps to use, but this is at least a starting point... I might have more time to research this and write a post about it sometime in the future later today.
Edit:
from another SO-thread Custom AS3 Class not Updating
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.

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!

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

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