Hi, I'm Ben. This is my blog. I write about Flex,
Flash, software development, and other miscellany.

Coding in Flex Builder, Compiling in Flash Authoring

Nostalgia and complaining

Years ago, before AS3 and Flex 2 were on the scene, I was a Flash developer. I dabbled in other things like PHP, JavaScript and the horrific “classic” ASP, but Flash development with AS2 was always more interesting to me. I worked with great designers who of course used Macs, while me and the rest of the developers were on PCs. (Don’t worry, I use a Mac now.) In order to preserve the designers’ fonts and hand crafted animations, we taught them how to assign linkage names to their symbols and would have them deliver a .swf to us that had nothing on the stage, allowing us to pull symbols out of the library as we needed. Using the fantastic MTASC compiler and an editor like PrimalScript, our class-based AS2 code would be injected into the designers’ .swf, bringing the site/game/whatever to life. Ahh, those were the days.

Fast forward to last week when I was assigned to my first ever non-Flex AS3 project and discovered that developing like we used to in Flash (tying AS classes to library symbols) is pretty painful these days. Or at least it was for me, until I constructed a very convenient workflow that you can probably guess at based on the title of this post. Now, I should probably explain what I mean by painful. You can write your AS3 classes in Flash authoring, and the process is very straightforward; just create classes whose names match the symbol linkage names and you’re done. Just like AS2. However, Flash authoring’s code editor is absolutely abysmal. I mean, I knew it was bad, but I was actually shocked at how bad it is. It won’t even create import statements for you when you create properties! If you have used Flex Builder or any other decent editor for more than 10 minutes, this is completely unacceptable. You could also write your code in Flex Builder, save, switch to Flash authoring and then test movie or publish from there. Honestly though, do you really want to do that 500 times a day? Me neither.

So, what is this better way you ask? Well, we use one improvement that did come with Flash authoring’s support of AS3, which is the document class construct. This means that you simply create a custom class to represent your application, make sure it extends MovieClip, and tell the .fla to use it. We don’t need any code at all in our .fla, unlike back in the day. This essentially means that your custom class is your root timeline, and adding display objects to it is like adding them to the stage.

Coding in Flex Builder

Since I use a Mac, Flex Builder and FDT are the only realistic options for AS3 editors, as far as I know. If you are on a PC, FlashDevelop is also a great program. Now, Flex Builder allows you to create ActionScript projects. In contrast to a Flex project, I assumed an ActionScript would be devoid of any reference to Flex SDKs, but this is not the case. Your ActionScript project will still reference an SDK in the compiler settings and in the build path dialog, but that is OK. Since you don’t reference any Flex classes, you will not be pulling the framework into your .swf. I think it is only referenced so Flex Builder knows where to find mxmlc, but I am not completely sure. In order to use library symbols as class instances, you will need to create corresponding classes (that extend MovieClip) for them that match the name specified in the their linkage field. Whether you need to add custom code or not, the classes must exist in order for you to reference them in Flex Builder. To reference their properties, like child text fields or buttons I declare those properties in the class and turn off “Automatically declare stage instances” in the .fla’s publish settings.

Compiling in Flash authoring

OK, none of that was revolutionary but now comes the hard part. How do you compile/test your project without having to switch back to Flash every time? The first piece of the puzzle is to use the flashcommand Python script that Mike Chambers posted a long time ago. (It is only for OS X in its current state but I would assume creating a PC-friendly version wouldn’t be too hard.) All this really does is open Flash if necessary, and compile the .fla(s) you tell it to, by writing JSFL to a temporary file and then running a line of AppleScript to execute the JSFL code. That is really great, but switching to Terminal every time I want to compile is no better than switching to Flash. I needed something I could trigger from within Flex Builder, so I naturally turned to Ant. All you need is a super simple build file, like this:

As you can see, it just sets up a couple of properties and asks Python to run the flashcommand script. The -e argument tells flashcommand to include doc.exportSWF() in the generated JSFL, which will publish the .swf to the location specified in the -o argument. If this is all you need to do, but want to then launch the newly created file in Flash Player, you can add the following to your build.xml file.

That was my initial approach but it makes viewing your traces kind of a pain. The easiest way I found was to tail your flashlog.txt file but that still kind of sucks. Its especially bad because a LOT of .swfs on the web still include trace statements, meaning your Terminal is flooded with statements generated by every banner ad running in your open browsers.

What I ended up doing was to edit flashcommand so that the -e argument also adds fl.getDocumentDOM().testMovie() to the generated JSFL, causing Flash authoring to execute a test movie action. I also added activate to the end of the generated AppleScript so that Flash’s test movie window would be brought into focus and ready for interaction. This allows you to use Flash’s built in Output panel to view your trace statements, and your trace statements only. (I tried making the test movie option a separate command line argument but couldn’t get it working correctly. If any Python hackers out there want to show me the way I’d be much obliged.)

Set up a keyboard shortcut in Flex Builder for running Ant and your workflow is almost identical to a Flex or code-only ActionScript project. Your .swf will be generated and published to whatever location you’ve specified, and will also be opened in Flash authoring for visual inspection and testing. I am probably not the first to come up with something like this, but I didn’t find any good links on the subject and other people expressed an interest in hearing about my workflow. If you have suggestions on further improvements (like how to use Flex Builder’s debugger for these projects) I would love to hear them. Regardless, I hope this is useful to other coders who find themselves needing to develop AS3 projects that associate custom classes with library symbols.

If you’d like to replicate this setup, you can download my modified version of flashcommand.

Enjoy!

ArrayCollection for AS2

Did you know that AS2 includes rudimentary implementations of collections and iterators? I didn't until a few months back, but they do come in handy from time to time. An added bonus is that they make me less sad about developing in AS2 and missing out on all that AS3 goodness when the project requires FP8 compatibility.

Anyhow, the default implementation still leaves a bit to be desired, especially for those of us who spend the majority of our time coding AS3. The built-in class not only bears the unfortunate name CollectionImpl (which implements the Collection interface, both of which reside in the mx.utils package), but it also lacks some methods I've grown to appreciate in AS3's ArrayCollection class. Those methods are as follows:

  • length (getter)
  • addItemAt()
  • contains()
  • getItemIndex()
  • removeAll()
  • removeItemAt()

The following class provides those methods. I know, nothing fancy or impressive, but useful (in my opinion) nonetheless. CollectionImpl isn't all bad though, it does provide us with most of the basic collection-related functionality you would expect, including the removeItem() method that was left off of AS3's ArrayCollection class. As such, this class inherits from CollectionImpl and attempts to fill in the blanks.

import mx.utils.Collection;
import mx.utils.CollectionImpl;

class com.returnundefined.utils.ArrayCollection extends CollectionImpl implements Collection
{
    private var _items:Array;

    public function ArrayCollection(arr:Array)
    {
        super();
        _items = (arr == null) ? new Array() : arr;
    }

    public function get length():Number
    {
        return _items.length;
    }

    public function addItemAt(item:Object, index:Number):Boolean
    {
        var result:Boolean = false;

        if(item != null)
        {
            _items.splice(index, 0, item);
            result = true;
        }

        return result;
    }

    public function contains(item:Object):Boolean
    {
        return getItemIndex> -1;
    }

    public function getItemIndex(item:Object):Number
    {
        var index:Number = -1;
        var len:Number = length;
        for(var i:Number = 0; i <len; i++)
        {
            if (_items[i] == item)
            {
                index = i;
                break;
            }
        }
        return index;
    }

    public function removeAll():Void
    {
        _items = new Array();
    }

    public function removeItemAt(index:Number):Boolean
    {
        return removeItem(getItemAt(index));
    }
}

Feel free to alter the package path here and insert this class into your library wherever you want.