Friday, January 23, 2009

Different ways of forcing Flex to compile a class

As a user of Spring Actionscript I have, of course, run into the problem of classes not being compiled into the swf file.

When you have defined an object in the Spring AS configuration, but there's not direct reference in your source code to the class, the Flex compiler will optimize the class out of the swf and you end up with runtime errors such as this:


a class with the name 'x.y.z' could not be found


So far I know of three different ways to tackle this problem:

1. Add dummy variables in your source code like this:



privare var _dummy1:MyClass;
privare var _dummy2:MyOtherClass;



2. Add a Frame tag for each class you want to be included to one dummy class, and include only that dummy class. Code would look like this:



package com.myclasses
{
[Frame(extraClass="com.myclasses.MyClass")]
[Frame(extraClass="com.myclasses.MyOtherClass")]
public class MyDummyClass
{
}
}



3. Use a bit of XSLT, an ANT script and add this a builder in FlexBuilder. I have posted a PDF with a how-to on the springsource forums over here:

Spring Actionscript forum post

Hopefully in the future there will be a more elegant way of forcing certain classes to be included, but until then, pick one of these solutions.

Wednesday, January 14, 2009

Introducing: As3UndoHistory

Ok, so I've released a first version of my little undohistory lib on google code,
go and get it here:
as3undohistory

You can pull the sources right from the SVN repository there. So far I haven't made a release package because the whole thing's fairly small anyways.

There's three projects in the repository, the actual library, a unit test project and an example application which showcases what the library actually does.

I have no idea how well the library scales, I guess registering a few thousand objects with each 50 properties and then changing each property say 200 times will eventually eat a bunch of memory. It might be worth a stress test at some point. But on the other hand, I wouldn't know how to record changes in a different way than this. But then again, I'm just a bonehead, so if anyone has a better approach to this kind of edit history recording, I'd love to hear it.

I'll be working on the documentation some more this evening I guess because, right now, its almost non-existent. Should anybody be interested in using the library, go ahead and please give me a yell should you find any bugs.

Cheers.

Tuesday, January 13, 2009

undo history management in Flex

So I have a major flu which puts me in bed bored out of my skull...
I have this ongoing project, a Flex application, which is basically a sort of mind mapping system crossed with a drawing application. Now one of the next feature requests that the client made is an undo history.

Yikez.

So, I've been toying around with how to do it, and came up with, what I think, is a workable solution. I don't follow the usual command pattern which you find in most google searches on flex + undo history. What I basically needed was a recording of all the property changes on a bunch of objects.
I.e. property color was set to #00000, property width was set to 150, etc, etc.
These changes have to be recorded chronologically and undoing would basically be a matter of popping entries off a stack.

So, my solution makes use of some metadata and requires the objects that will be monitored to implement their properties with getters and setters.
An undoable property would look something like this:


[Undoable]
public function get testStringProperty():String
{
return _testStringProperty;
}
[Bindable(event="testStringPropertyChanged")]
public function set testStringProperty(value:String):void
{
if (value != _testStringProperty)
{
_testStringProperty = value;
dispatchEvent(new Event("testStringPropertyChanged"));
}
}

The object that implements this property needs to be registered once with a history manager class which analyzes the metadata and sets up eventlisteners,etc. In my implementation I use Christophe Herremans as3reflect library for retrieving the metadata.

My undo history manager also supports simple transactions, in the case several property changes represent only one user gesture. This is simply a matter of calling startTransaction and endTransaction on the history manager.

Anyways, I'm still busy cleaning up the code, finishing the documentation and making a little example application. But when I'm finished I'll release this on google code so maybe somebody else can benefit from this as well.

Or maybe someone on the interwebs thinks my solution is absolutely ridiculous, then I'd like to hear about it too :)

For now, I'm going back to being sick with the flu.

Cheers.