Archive for January, 2007

Macros that are available in html-template files

In a post last month, I briefly mentioned the list of macro substitutions that are available in the files in the html-template folder. Here, I’ll offer a little more information on those. I’ll try to make sure this makes it into the next version of the documentation.

${project}
The name of the project, e.g. MyProject.
${application}
The name of the application, e.g. MyApp.
${version_major}
The major version number of the version of Flash that is required to run this app, e.g. 9 for version 9.0 r28. You can change this and the other ${version_...} macros by going to Project > Properties, then “Flex Compiler” or “ActionScript Compiler,” and then changing the player version number in the “HTML wrapper” section.
${version_minor}
The minor version number of the version of Flash that is required to run this app, e.g. 0 for version 9.0 r28.
${version_revision}
The revision number of the version of Flash that is required to run this app, e.g. 28 for version 9.0 r28.
${build_suffix}
This is equal to "-debug" when building the debug version of the SWF, and "" when building the release version.
${swf}
The name of the SWF, not including the .swf extension, e.g. MyApp or MyApp-debug. This is essentially a convenience macro which is equivalent to ${application}${build_suffix}.
${bgcolor}
The background color of the application, as specified in the backgroundColor attribute of the <mx:Application> tag, or, in the case of ActionScript-only projects, in the backgroundColor field of the [SWF] metadata attribute of the main application class, e.g. [SWF(backgroundColor="#ffffff")] public class MyApp extends Sprite (see this post for more information on setting the width, height, and background color of an ActionScript project). The result is in the form #rrggbb, e.g. #ffffff. This can actually be a little tricky to use, because by default, the background of a Flex app is actually a gentle gradient from one color to another; if you want the HTML background to match the background of your Flex app, you may need to fiddle with both the backgroundColor and backgroundGradientColors attributes of the <mx:Application> tag.
${width}
The width of the application, as specified in the width attribute of the <mx:Application> tag, or, in the case of ActionScript-only projects, in the width field of the [SWF] metadata attribute of the main application class, e.g. [SWF(width="300", height="400")] public class MyApp extends Sprite.
${height}
The height of the application, as specified in the height attribute of the <mx:Application> tag, or, in the case of ActionScript-only projects, in the height field of the [SWF] metadata attribute of the main application class, e.g. [SWF(width="300", height="400")] public class MyApp extends Sprite.
${title}
The title of the application, as specified in the pageTitle attribute of the <mx:Application> tag, or, in the case of ActionScript-only projects, in the pageTitle field of the [SWF] metadata attribute of the main application class, e.g. [SWF(pageTitle="flex r00lz")] public class MyApp extends Sprite.

Meet me at “Meet the Flex Team”

Meet me and many other Flex/Flex Builder team members at “Meet the Flex Team” on Thursday, January 25th, at the San Francisco office of Adobe. See our very cool building, with lots of exposed wood beams and brick walls; and tell me that debugger feature you desperately need. (Seriously — I want to hear requests.)

Solution to quiz #1: inner functions and garbage collection

Yesterday I posted a quiz with a bit of code that has a bug. Here's the solution.

The interesting thing about challenging readers to find a bug is that they will inevitably point out things that hadn't occurred to me. I'll discuss each of those.

Here's the code again:

package {
    import flash.display.Sprite;
    import flash.events.Event;
 
    public class MyClass extends Sprite
    {
        public function MyClass()
        {
            this.addEventListener(Event.ENTER_FRAME,
                function(e:Event):void { trace("enter frame") },
                false, 0, true);
        }
    }
}

Two readers had the answer I was looking for: The callback function is an inner function rather than a member function, but we passed "true" for the "useWeakReference" parameter of addEventListener().

When you pass a regular method to addEventListener(), that method always has a specific "this" object associated with it -- the object that was "this" at the point where the reference to the method was created. But when you pass an inner function, inner functions do not have a specific associated "this" object. So unless you created some other sort of reference to the function, e.g. by assigning it to a member variable of an object or something, it will just disappear when garbage collection takes place.

As for other answers: Two readers guessed that the bug was that I was listening for the ENTER_FRAME event, but Sprite doesn't have a timeline (if you want a timeline, you should extend MovieClip), so it wouldn't work. I actually don't know a lot about that part of Flash, but I checked the docs, and it looks like the ENTER_FRAME (aka "enterFrame") event is part of class DisplayObject, which is not a MovieClip; the docs say, "Dispatched when the playhead is entering a new frame. If the playhead is not moving, or if there is only one frame, this event is dispatched continuously in conjunction with the frame rate." The implication there is that you don't have to have your own timeline in order to listen for frame events. Perhaps you are listening to the playhead of the timeline that contains you? Or maybe no specific timeline is involved -- maybe it just means the player has moved to its next frame.

Finally, another reader suggested that since the listener is created inline, it will never be possible to remove it, because there is no way to refer to it. That is certainly true, and I guess it could be considered a bug in some cases, but it isn't a bug in the sense I was thinking of. For many programs, it is common usage to add event listeners using inner functions, because the program has no expectation of ever needing to remove those listeners.

Next Page »