Archive for the 'flex 3' Category

New Object Handles release

I just whipped up a new ObjectHandles release.  Couple notable things…

They now automatically remove themselves from the SelectionManager when removed from the stage (they add themselves back when added as well).  This fixes a fairly serious memory leak.

I’m deprecating the useage of the Handle class.  It draws the handles through the drawing API.  Now, instead use the ImageHandle class which draws the handles from an embedded image.  There was some wonky logic in there that turned clipping on or off depending on this setting and that was just plain dumb.  Lets just do it one way.  I included sample .png files to simulate the old look.

I fixed some weird flickering when resizing to the left or up.  It only happened on certain cases, and I’m not sure why.  I think it had to do with delayed execution of the Flex layout manager.  Now, I delay the setting of x,y,width, and height and force a validateNow() right after setting those.  Let me know if this causes any problems in your application.

I still don’t have conditional compile for Flex2/Flex3 in there, so this will only compile under Flex 3.  Does anyone know how to get that conditional compiling to detect Flex version without having to pass an extra compiler param?

 

Slow Flex Builder compile and refresh solution – Modules

For the past month I’ve been plagued with up to three minute compile times on Flex Builder 3 Beta 2. I’ve also been plagued with long several minute waits of “Refresing bin/”.

Last week I solved the issue for one of my projects and prevented it from happening to another.

Apparently embedding graphics causes a performance hit in compiling, refreshing directories, and even just before launching. So if you have a hundred or so of these:

<mx:Button icon=”@Embed(…)” />

You’ll be in a world of pain. The easiest solution is to move those embed calls into your style sheet and then compile your style sheet as a module.

Here’s how to make a style sheet module:

1) Create a new MXML module (file->new->flex->MXML module)
2) Add your stylesheet reference to that.

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Module xmlns:mx=”http://www.adobe.com/2006/mxml”
layout=”absolute” width=”0″ height=”0″
creationComplete=”trace(‘iconsloaded’)”>
<mx:Style source=”style.css” />
</mx:Module>

3) Next, remove the reference to your style sheet from your main application.
4) Now, in your main MXML or AS file add some code to load your module.

protected var styleLoader:ModuleLoader;protected function init() : void{    styleLoader = new ModuleLoader();    styleLoader.addEventListener(ModuleEvent.READY, onModuleLoad );    styleLoader.addEventListener(ModuleEvent.ERROR, onModuleError );    styleLoader.url = "IconsModule.swf";       styleLoader.loadModule();}protected function onModuleLoad( e:ModuleEvent ) : void{    maximize();    var mainApp:MainApplication = new MainApplication();    mainApp.percentHeight = 100;    mainApp.percentWidth = 100;    addChild(mainApp);   }

protected function onModuleError(e : ModuleEvent ) : void{    Alert.show("Could not load module IconsModule.swf","Error",Alert.OK );}

You can see there that I intialize my main application component after the module has loaded. I didn’t have to do this in a Flex app, but in my AIR app that component wouldn’t get all of the new styles if created before the module was loaded.

Option 2

Sometimes, it wasn’t practical for me to put the embedded graphic in a stylesheet. In those cases I:

1) Made an interface listing all the embedded graphics

public interface MyGraphicsModule{// Bindable tags are there purely to suppress warnings,// these properties never change after startup.[Bindable(event="moduleChanged")] function get addIcon() : Class;...}

2) Make a class that implements that interface and extends ModuleBase, also embed the graphics in there.

public class MyGraphics extends ModuleBase implements TimeLinerGraphicsModule{[Embed(source="/art/toolbars/add.png")]protected var _addIcon:Class;public function get addIcon() : Class { return _addIcon; }

...}

NEVER import or otherwise use this class into your application. The goal is to keep it completely separate.

3) Create a module manager class

public class MyModules{[Bindable] public static var graphics:MyGraphicsModule;}

4) Set MyGraphics to be a module that gets built in your Project->Properties->Flex Modules settings.

5) Load your module somewhere at startup

public function loadModules() : void{graphicsModuleLoader = new ModuleLoader();graphicsModuleLoader.addEventListener(ModuleEvent.READY, onModuleLoaded );graphicsModuleLoader.addEventListener(ModuleEvent.ERROR, onModuleLoadFailure );graphicsModuleLoader.url = "MyGraphics.swf";graphicsModuleLoader.loadModule();}

protected function onModuleLoaded( event:ModuleEvent ) : void{if( event.target == graphicsModuleLoader ){var o:Object = event.module.factory.create();MyModules.graphics = event.module.factory.create() as MyGraphicsModule;}}

6) Find the spot in your code that used that icon and replace it

So this:

[Embed(source="/art/icons/addIcon.png")]public var addIcon:Class;

Would become this:

public var addIcon:Class = MyModules.graphics.addIcon;

This all seems like a pretty tedius job to do, but I ended up writing a perl script to scour the source tree, find all the references, and replace them for me. Unfortunately I did that script as part of my day-job and can’t share it with everyone right now. I’ll ask for permission on Monday.

The end result was we went from a 3.5 minute wait from saving a code change to executing the application to a 20 second wait. Not too shabby considering the size of the codebase we have.