Flash: FDT and AIR 1.0
Recently upgraded from FDT Professional to FDT Enterprise. I was excited to see that AIR is now supported. Of course it's been out for several months, just haven't paid any attention to it. Updating since a few things have changed since AIR went 1.0
- Download + Install the AIR runtime (now released)
- Download the Flex SDK (now open sourced),
- unzip the Flex SDK to someplace reasonable e.g. C:\CodeProjects\AS3.0\Flex3.0.0.47\
- Go to 'Window>Preferences' then click on the 'AS3 Core Libraries' Tab, then the 'Add' button
- This will get you to the Define a New Path Variable
- Finally you'll want to update the Core Library for the package you are using via right clicking over the project and selecting 'properties' then the 'Change Core Library' button on the bottom right:
- After you select the Core Library you created earlier, it will update and rebuild all the projects, and here's what it will look like after:
- I typically add the CS3CoreComponents too, as I do lots of project that are Flash First instead of Flex Based.
- Past that follow the instructions starting with step 5. on adding the sample AIR resources folder,
- download and replace the HelloWorld Application Descriptor, else you will get a series of errors like here
- modify the HelloWorld to match whatever you are using.
- Open up the Build_AIR.xml for editing
- change the 'sdk_dir' to point to the Flex3 path on your harddrive you downloaded earlier,
- change the 'app_name' to whatever you called your app, e.g.
- Then follow steps 8 and on, to build the swf and package it for AIR, if successful, you should then get something that looks like this. Congratulations!.
If your curious about what else has changed since the original article check the devnet.
AS3: MovieClip.addFrameScript
MovieClip.addFrameScript is a very powerful way to decouple script from the timeline. This post help you understand how it works.
When movies are compiled (including the top level swf), if no class is provided. Flash creates one for you behind the scenes. 1 Class is created per 1 MovieClip, typically sharing the same name. It helps to understand how the conversion happens, to make best use of it, and writing code on the timeline in general.
- imports are only needed once in a timeline
- variables declared on a frame, end up as class variables,
- you can't redeclare variables on multiple frames.
- only one function is called per frame, this can be tweaked, overridden or amended with addFrameScript
You can't redeclare variables,
on frame1 and frame2 put:
var aName:String = "A";
will give you the following error:
1151: A conflict exists with definition aFrame in namespace internal.
however putting on Frame 1
var aName:String ="A"; //frame1
and on Frame2
aName = "B" //frame2
works fine.
MovieClip.addFrameScript
Is the undocumented glue between the timeline frame and the class's function ( if bound). There can only be one script/function bound to a frame using the built in addFrameScript, though an alternative approach is to poll currentFrame changing (via Event.ENTER_FRAME).
This binding happens via addFrameScript(frameNumber-1, functionToCall...); Note that the first argument is ZERO BASED (while normally the timeline is 1 based)
During the Fla.compilation our script gets put into a function like:
Class Test_fla{
function frame1():*{
var aName:String = "A";
}
function frame2():*{
aName = "B";
}
}
The important thing to note is the frame1...frameN naming, where N is the frame number 1-whatever, We can validate this by decompiling the swf, using the AbcDump utility, which takes our test.swf and outputs:
function Test_fla::frame1():* /* disp_id 0*/
{
// local_count=1 max_scope=1 max_stack=2 code_len=16
0 getlocal0
1 pushscope
2 findpropstrict trace
4 pushstring "onFrame1"
6 callpropvoid trace (1)
9 findproperty aFrame
11 pushstring "aFrame"
13 initproperty aFrame
15 returnvoid
}
So the end will be a frame to function mapping (which we can't see) like:
- [0]= frame1()
- [1]= frame2()
Note again the frameNumber is zero based, while the script is 1 based.
Consequences
which has 2 consequences,
- you can't name your own functions frameN if one already exists. This is the same error as compiling in the same *.as:
function frame1(){}
function frame1(){
}
- you can call and over ride these functions,
addFrameScript(0, overrideFrame1);
function overrideFrame1():*{//do something before
frame1();
//do something after
}
In addition the top level Class, will be shared across different scenes, but these can have on the timeline different configuration values (say which language to use), and when used with jsfl to publish all scenes, create a handful of starter files.
Conclusion
This is kick ass for completely separating a UI.swf from a Controller.swf Keeping designers working on the timeline, and coders out of the design.
For the coders, and others working in Flash, is the ability to use addFrameScript to perform actions when a frame is fully initialized and children are on stage, similar to onLoad() in AS2, where-as use of ENTER_FRAME gets called prior to children in that movieclip getting called...this is similar to onInit() in AS2. So for example you can have a button only on a particular frame and setup it's event listener to call your controller...in another swf, regardless of what the playhead is doing.
In someways I find this cleaner than watching using addedToStage, rendered etc.
REFERENCES:
[1] Senoculars post
[2] FlashGurus info as Senocular
[3] BIG SPACESHIP, Extending addFrameScript to use the frame labels instead of framenumbers... the same glue I'm using as well, though I'm more interested in events being generated, than script.
[4] an alternate approach on evilzug's journal using ENTER_FRAME
You should be aware if using that approach that when the framescript is called via the ENTER_FRAME, items in the frame may have not been added yet, so this approach can't be used to bind to objects on the timeline (e.g. to registerListeners to buttons), this the addFrameScript does not suffer from.
Here's an output with one on the timeline the other added via oizys's frameScript approach:
entered frame 3
onReachedInstructions instructions null <- no button yet, via modified addFrameScript
timeline reached instructions [object SimpleButton] <- normal addFrameScript
onReachedInstructions instructions [object SimpleButton] <- now the button exists
DRM, MetaData and swfs.
DRM in flash can be tricky, how is it you identify and pass id's to a swf duplicated a thousand times to know where it goes?
1) A temp approach is using server generated FlashVars in AS3, good for session ID's
http://blogs.adobe.com/pdehaan/2006/07/using_flashvars_with_actionscr.html
2) First not visible to actionscript is the metadata tag, preferrably writing it on th fly:
http://tutorials.lastashero.com/2005/10/using_swf_metadata_in_flash_8.html (via the IDE)
The metadata can easily be retrieved by some search engine swf plugins, it's actually what it was designed for.
There is a $30 dollar utility to batch do this to your swfs:
http://www.polarswf.com/
3) Accessible to actionscript is rewriting of variables in the swf This is useful when root vars aren't an option, and or license keys (e.g. encrypted tokens) need to be embedded into the swf.
http://neurofuzzy.net/index.php?p=25
Both 2 and 3 can be accomplished via AS3 and ByteArray. Though I haven't tried it yet.
Compiling AS2.0 Projects with mx.* dependencies in FlashDevelop Beta 3
FlashDevelop Beta3 comes bundled with MTASC, but it by default misses an important configuration option, so building projects with references to mx.* will complain, even with the -mx option set, like:
characters 8-25 : type error class not found : mx.controls.Button
You'll need to add the following to the classpath (preferably global):
C:\Program Files\Adobe\Adobe Flash CS3\en\First Run\Classes
One trick to editing it in FlashDevelop since the file selector doesn't allow you to paste it in directly, opening up a windows Explorer window while the file dialog is open, and pasting the above into the address bar, a neat trick of windows is all windows are listening to the same events, so it will take the FlashDevelop tree browser to the correct spot.
Tools: FDT + Eclipse vrs FlashDevelop
So after another round of flux in my development environment, I resorted to using Eclipse (for coding) AND FlashDevelop (for compiling and quick projects) in tandem (along with SOS for trace debugging). Talk about a lot of desktop space!
This is because FDT+Eclipse, my favorite tool for ActionScript development is still in Beta (still a great code editor!) and in general building requires Ant tasks in Eclipse, which doesn't support the Flex Compiler Shell (huge speed increases), while FlashDevelop is an good editor, but has great compiler support.
About 2 months ago, with significant trepidation. I finally bit the bullet and made the move to AS3. It's been about 2 pretty turbulent months since. Learning the IDE of 2 major tools (Flash CS3, Flex 3.0 beta ), the massive syntax changes, new workflow, starting to get large libraries converted....breaking across the rocks of different paradigms.   Then midway the Flex beta license ran out (30 days is after all reasonable),. It wasn't worth it spending $300-$500 for a license to FlexBuilder 2.0 to keep going.
- I'm going to Max in October, I know 3.0 is out in a few months,
- The code editor is an order of magnitude weaker than FDT, and still quirky enough to make it unuseable at times in the beta, I guess some of my code does some tricky things which causes Flex's language parser to barf.
- I don't plan on using FlexBuilder/Flex on most of my projects...we aren't that data/standard control centric.
This created a window of no reasonable workflow. FlashCS3 does compile AS3 well (I first started having to use it with FlexBuilder 3.0, when running into quirks in it's parser). But the editor isn't much better than a plain text editor, for dealing with large libraries and components. So I started investigating other platforms, Sepy and FlashDevelop...etc. Which is about as motivating as looking at a bicycle after driving an F1,...but admittedly better than walking barefoot or standing still.   I was hoping that in my lack of paying attention that the years since I last reviewed would have some new releases, and while I didn't have time to investigate Sepy, I was pleased with FlashDevelop Beta 3. In a sunday afternoon I got from ground zero to building an AS2, and an AS3 project both using the Flash CS3, and separate the Mxmlc.exe, which nicely prompted me to look for the 'Flex Compiler Shell', which I hadn't heard of before.
http://labs.adobe.com/wiki/index.php/Flex_Compiler_Shell
The compiler shell is designed to startup once then talk with it, telling it to recompile files, typically by getting an id back on the first compile then recompiling. This can amount to huge timesavings. Once installed and incremental compiling is on, It's similar the speed jump to me from using Flash to using MTASC.
YAY!!!!
Incremental compiling has been high on my list of things I've been looking for out of AS3, Java has had this for almost a 8 years, and I grew to depend on it. Java is still way ahead...you can hot fix code running in the VM without restarting...while debugging, even remotely (if allowed)!.
FlashDevelop Beta 3 supports the Flex Compiler Shell without anything special, just drop in and go (very nice!). Sadly for Eclipse/Ant/FDT it won't work well, as the major performance increase is from not having to startup the mxmlc.exe everytime, but ant starts up and closes down as soon as it's finished, and there is no easy way to modify Ant/Eclipse to keep the process/dialog open. But since it's not terribly difficult to have both open, that's what I've done.
The biggest thing that I miss via this is the errors output by the compiler (both the syntax check, and full compile errors) show up in FlashDevelop, which clicking on lets you jump to, when I'd rather do it in Eclipse. Both tools are smart to watch for file changes, so it's possible to edit in both places. If a bit more UI to wrangle than idea;
