Eclipse Problem Markers from Flex Ant Builds

Two of the most popular ways to build flex projects are:

  1. Use Flex Builder
  2. Use the Flex SDK Ant tasks

In our case, we had been using 1 for development and 2 for production for some time. This gave us the best of both worlds: nice IDE features (e.g. problem markers and jumping to definitions) during development time and also the ability to fine-tune and optimize for production deployment.

Recently, however, due to increasing project complexity (project dependencies anyone?) and flex builder bugs, we have been forced to switch over to using  Flex Ant tasks exclusively. This means configuring our Eclipse projects to have an Ant Builder which executes our ant tasks in place of Flex Builder. The one benefit of this is that it increases the transparency of the build process, with only a single code path for building and saving us the headache of having to define compiler settings and modules in more than once place.

Aside from speed, the one major annoyance of this route is that no problem markers are generated during the build process. Consequently, you have to manually examine the console output. Once you manage to locate the error, you still have to parse the output, extract file names and line numbers, and manually open the files… at least until now!

The Solution: FlexMarkers

This morning I finally got fed up with this process and spent the better half of the day developing an eclipse plugin (my first one), FlexMarkers, which solves this problem. It inspects the console output from the Ant Builder as it is produced and creates problem markers for both errors and warnings. With this plugin you see mxmlc and compc errors in the Eclipse Problems view and can double click on them and go directly to the file and line number where the problem occurred. This essentially duplicates the behavior of Flex Builder, without having to use Flex Builder to build your project.

You can find the update site here: http://hempton.com/eclipse/update

So far, I have only tested it on Eclipse 3.4.2. If you use an Eclipse Ant Builder which executes <mxmlc> or <compc> tasks, definitely give it a try!

9-Grid Scaling Support in Javascript/CSS

If you have ever spent any time developing and styling flex applications, you have probably come to find the 9-grid scaling feature indispensable. For those of you unfortunate enough to have never experienced this feature, it enables you to easily scale an image while preserving the scale of certain portions of the image based where it lies within a specified grid. Parts of the image which lie in the corners of the grid will not be scaled and parts which lie in the sides will only be scaled in one direction.

Traditionally, to achieve this same effect in plain html/css you would slice the background image into multiple files and have extra structural markup in order to place the images in the appropriate places. This is particularly annoying for fluid layouts. Being faced with a small side project in html/css and desperately wanting to avoid this css styling tedium, I created a jQuery plugin which brings 9-grid scaling support to html/css. I have also put up some examples and I have also put it up on google code. I am looking forward to using this as a more efficient alternative.

Two Nasty Flex Bugs to Watch Out For

I ran across several bugsfeatures today that I thought would be worthwhile to share. These are of the variety that take a while to figure out and are not very intuitive. Both were encountered using Flex 3.1

Modules Loading Events Never Fire

This one I encountered while manually loading modules using the ModuleManager. Apparently the ModuleManager maintains nothing but weak references to the IModuleInfo object returned using getModule. If you do not maintain a reference to the IModuleInfo object, the object can potentially be garbage collected and any event handlers you added to it will be lost. For instance, the following example will not work as expected:

private function initApp():void {
	var info:IModuleInfo = ModuleManager.getModule("ColumnChartModule.swf");
	info.addEventListener(ModuleEvent.READY, modEventHandler);           
 
	info.load();
}
 
private function modEventHandler(e:ModuleEvent):void {
	container.addChild(e.module.factory.create() as ColumnChartModule);
}

In the above example, the IModuleInfo instance will be garbage collected before the modEventHandler method is called. Instead, the above example should be changed to the following:

public var info:IModuleInfo;
 
private function initApp():void {
    info = ModuleManager.getModule("ColumnChartModule.swf");
    info.addEventListener(ModuleEvent.READY, modEventHandler);           
 
    info.load();
}
 
private function modEventHandler(e:ModuleEvent):void {
    container.addChild(info.factory.create() as ColumnChartModule);
}

This was actually filed as a bug against flex, but was closed as “Not a bug”, despite the fact that it is a regression from Flex 2.

Tweens Mysteriously Stop and Never Finish

A common pattern when using tweens is the following:

private var _tween:Tween;
 
public function eventHandler(e:Event):void
{
	if(_tween)
	{
		_tween.stop();
	}
 
	// do something and possibly return
 
	_tween = new Tween(...);
	_tween.setTweenHandlers(updateHandler, updateHandler);
}
 
private function updateHandler(c:Number):void
{
	// update something
}

However, when dealing with complex user interfaces that use the above pattern in multiple places simultaneously, I noticed that some Tween instances will stop and never finish, ostensibly at random times. After examining the Flex internal code, I discovered that the logic which manages the Tween objects and invokes their handlers re-uses tween identifiers. Thus, if a Tween has had its stop() method called, its identifier will be reused by future Tween objects. Moreover, if you call the stop() method on a Tween after it has already been stopped, if there is a new Tween which took the identifier of the already stopped Tween, this new Tween will also be stopped by the second stop call.

This fix for this is rigorously make sure that all stop() method calls are called only once, or not at all if the Tween has stopped because it has ended. The above code should be changed to:

private var _tween:Tween;
 
public function eventHandler(e:Event):void
{
	if(_tween)
	{
		_tween.stop();
		_tween = null;
	}
 
	// do something and possibly return
 
	_tween = new Tween(...);
	_tween.setTweenHandlers(updateHandler, finishHandler);
}
 
private function updateHandler(c:Number):void
{
	// update something
}
 
private function finishHandler(c:Number):void
{
	updateHandler(c);
	_tween = null;
}

Google Chrome: Why I’m Not Excited

There is currently a massive amount of buzz around Google’s recently launched browser, Google Chrome. And why not? It’s a new WebKit based browser with a clean minimalist UI and a purportedly super fast V8 Javascript interpreter. To top it off, each webpage executes in its own process and it’s made by Google! It’s the next step in the battle to legitimize web based applications as viable replacements for their desktop counterparts.

Why am I not excited? Adoption rates aside, the big reason is that Chrome’s V8 is not the kind of Javascript engine I would like to see in the next generation of web-browsers. Don’t get me wrong, I fully believe that V8 will be one of the fastest Javascript engines out there, but it’s in its optimizations where the problem lies. When V8 interprets Javascript, it transitions directly from Javascript source code to machine code. There is no intermediate bytecode format! This means that Chrome is designed around Javascript as the be-all end-all language. Chrome isn’t just bad news for Adobe, it’s bad news for developers in general.

In my ideal world, the next generation web-browser will have a generic, standardized bytecode format to which Javascript is compiled, but also such that it will leave the option open for compilers for other languages– a la the good old JVM.  Imagine if you could write the client-side portion of a website using your language of choice, e.g. Ruby, Python, or even Scala (my personal favorite/hobby language). I have high hopes that something like Mozilla and Adobe’s collaborative effort, Tamarin, will turn into this.

As the client-side portion of websites becomes increasingly complex, it also scares me to think that everyone will be monogamously tied to Javascript. Without letting this post turn into a language rant, I am obliged to say that Javascript is in desperate need of better tooling and debugging support; I also feel that Javascript is hard to use and maintain on large, intensive projects, but maybe that’s just me. I realize that the last few sentences sound like cookie-cutter arguments against dynamic languages in general, but I’ll save that for another post.

As of late, as an alternative to Javascript, I have been doing most of my client-side programming in Flash using AS3 and the Flex SDK, not so much for the additional features as for the streamlined development process. AS3 is based on ECMA script, on which Javascript is based as well, but the support for namespaces, optional static typing, and better IDE support (Flex Builder) makes me much more prolific. Let’s also face it: all the major web-browsers are totally dependent on Flash, if not just for serving video, and that’s not going to change any time soon. Google knows this and adds the flash plug-in to Chrome automatically. Ironically, it is Flash and other plug-ins which break Chrome’s pristine process model, since the grandfathered-in plug-in architecture requires less restricted access.

On the bright side however, I have been using Chrome as my default browser for the last couple of days and have had an overall good experience. In terms of UI, it is a nice incremental improvement over other browsers. Combining the search into the address bar more intelligently is extremely convenient and long overdue. I also really like having the tabs on the top of the page.

Come Play in My Sandbox

Sandbox Thumbnail My favorite part about flying is that I use it as an excuse to focus on small personal projects. Last night, on my red-eye flight back from west coast demo day 2008 (oh yeah, in case you didn’t know, I am in YCombinator Summer ‘08, co-founder of MeetCast) I made a custom RSS reader for my blog. This isn’t any ordinary RSS reader, however, it is in the form of a physics sandbox. You can see it in action here.

It’s still pretty rough, but is still fun to play around with. I used the as3 version of Box2D for the physics, which I am really impressed with. Eventually I will add more parameters besides gravity, as well as more feeds (e.g Twitter).

Paperblocks: 3D Tetris

pblocks screenshotA while back I created this game while teaching myself Flex 3 and Papervision 3D 2.0 and I figured it merited a blog post. It’s of the 3D Tetris breed and took me several weeks to complete. You can see it in action here. Try it out and submit your high scores! Feedback is welcome.

Flex ScrollPolicy.AUTO Not Good Enough

One of my biggest gripes so far with the flex scrolling system is the automatic scrolling policy: a container’s viewing area is not changed by the introduction of scroll bars. This is especially troublesome in the vertical case and seems to be a pretty shitty way of doing things in general. For example, if the vertical size of the children increases beyond the height of their container, a vertical scroll bar will be created and displayed, however the children will not be resized. Consequently, if some of the children have variable widths (e.g. width=”100%”), they may be overlapped by the vertical scroll bar, causing a horizontal scroll bar to be displayed. When the scrolling policy is set to ScrollPolicy.ON, however, the children are resized to take the scroll bar into account at the price of the scroll bar always displaying, even when it is not needed. Yuck.

I have heard several justifications for this. One is that it prevents a cascading resize effect where all the descendants of the container are resized, each one introducing a vertical scroll bar. Another is that it is faster due to the fact that it requires only a single pass on the children, whereas to do it the correct way would require sizing the children, checking if scroll bars are required, and then adjusting the size of the children based on the new size when scroll bars are introduced. In both cases the justification is entirely dwarfed by the current behavior.

Fortunately there is a fix for this: create a custom container and add the following override for the validateDisplayList method:

import mx.core.ScrollPolicy;
public override function validateDisplayList():void
{
    super.validateDisplayList();
 
    if(null != verticalScrollBar &amp;&amp; verticalScrollBar.maxScrollPosition == 0
        && verticalScrollPolicy != ScrollPolicy.AUTO)
    {
        verticalScrollPolicy = ScrollPolicy.AUTO;
    }
 
    else if(null != verticalScrollBar)
    {
        verticalScrollPolicy = ScrollPolicy.ON;
    }
}

This is a hack which toggles between ScrollPolicy.AUTO and ScrollPolicy.ON as needed to gain the desired behavior. It comes at the price of invalidating the verticalScrollPolicy property. Hopefully this behavior will be more tightly integrated into future versions of Flex (maybe another ScrollPolicy is in order?).