Reading flex 4 gumbo – FXComponent

November 1, 2008

So I’ve been reading the gumbo framework code and there is a lot I learnt from the code. I’ll share some of the things I leanred while browsing the code.

First, the base class of all components in Gumbo is the “FXComponent” Since FXComponent is a subclass of Halo’s UIComponent, it retains backward compatibility with flex 2&3 components but introduces some of its own goodies.

I’ll do an analysis of the code in this component for this post.

public function FxComponent()
{
// Initially state is dirty
skinStateIsDirty = true;
}

As we see gumbo still use the same convention of invalidation -> validation cycle and this variable is used to signal the fact that skin needs validation.

private function setSkin(value:Skin):void
{
if (value === _skin)
return;

_skin = value;
dispatchEvent(new Event(“skinChanged”));
}

setter for skin is private means that this function will be called by some other part of the code. Notice that “skinChanged=true” is not called here which seems a little strange but we will see later why.

override protected function commitProperties():void
{
super.commitProperties();

if (skinChanged)
{
skinChanged = false;
if (skin)
unloadSkin();
loadSkin();
}

if (skinStateIsDirty)
{
skin.currentState = getCurrentSkinState();
skinStateIsDirty = false;
}
}

Here we see the invalidation -> validation in action. Basically this takes place for 2 things, skinChanged and SkinStateDirty and the corresponding function to validate them are unloadSkin()-> loadSkin();  and getCurrentSkinState();

override protected function measure():void
{
if (skin)
{
measuredWidth = skin.getExplicitOrMeasuredWidth();
measuredHeight = skin.getExplicitOrMeasuredHeight();
measuredMinWidth = isNaN( skin.explicitWidth ) ? skin.minWidth : skin.explicitWidth;
measuredMinHeight = isNaN( skin.explicitHeight ) ? skin.minHeight : skin.explicitHeight;
}
}

As we see in the measure function, all the layouts in gumbo are going to be done by skin objects, which are just light weight wrappers for group objects and group objects delegate all their positioning and layout to special layout classes. But more on that perhaps in another post

override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
if (skin)
skin.setActualSize(unscaledWidth, unscaledHeight);

if (focusObj && focusObj is IInvalidating)
IInvalidating(focusObj).invalidateDisplayList();
}

we see here that skin are treated like childrens of the FXComponent and the component is responsible for telling the skin its size.

protected function loadSkin():void
{
// Factory
var skinClassFactory:IFactory = getStyle(“skinFactory”) as IFactory;

if (skinClassFactory)
setSkin( skinClassFactory.newInstance() as Skin );

This function “loads” a skin, as we see skins are set as factories or classes and now its apparant why the setSkin function doesn’t mark skinChanged = true since this is the only place were its called and its during the validation cycle.

if (skin)
{
skin.owner = this;
skin.fxComponent = this;

// As a convenience if someone has declared hostComponent
// we assign a reference to ourselves.  If the hostComponent
// property exists as a direct result of utilizing [HostComponent]
// metadata it will be strongly typed. We need to do more work
// here and only assign if the type exactly matches our component
// type.
if (“hostComponent” in skin)
{
try
{
Object(skin).hostComponent = this;
}
catch (err:Error) {}
}

addChild(skin);

skin.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, skin_propertyChangeHandler);
}
else
{
throw(new Error(“Skin for ” + this + ” cannot be found.”));
}

Some interesting code here:

the hostComponent propert set in skin allow the skin to resize itself to fit certain parameters of the host component, as described here (http://www.philterdesign.com/blog/2008/09/10_reasons_to_dig_skinning_in_1.html)

the skin is indead treated as a Child of the hostComponent, and such, its a UIComponent too =)

Immediately after the skin gets loaded, this gets called:

protected function findSkinParts():void

the skin parts are found by this function:

var skinParts:Array = getSkinPartMetadata(className);

who’s details are something that is beyond my understanding at this point, but in the findSkinParts function we can see that information about the skin parts are tacked unto the object itself

this[part.id] = skin[part.id]; and we also see that each one of these objects should be an IFactory

if (this[part.id] != null && !(this[part.id] is IFactory))
partAdded(part.id, this[part.id]);

which brings us to the next function : partAdded(partName:String, instance:Object):void

which is….. empty…. but its used in child classes since the base class FXComponent itself has no subparts to speak of, it only has itself and its own skin to take care of.

There are also other functions such as createDynamicPartInstance and removeDynamicPartInstance, but they don’t get called anywhere in the base FXComponent class, so I will probably stumble upon them later in my later exploration of the framework.

As you can see, the new gumbo framework:

– keeps the old component lifecycle

– adds the support for skin

– the code is surprisingly readable and consistent.

multidimensional Arrays in Actionscript

December 25, 2007

I was trying to code some image processing algorithms today and I realized that actionscript does not support real multidimensional array

so I can’t do something like

var k = new Array(3,4);

k[i][j] = 3;

Instead, I have to do something like

var k = new Array( 3*4);

k[i*3+j] = 3;

So I’ve created a small ultility to create multidimensional arrays, here it is

public class NKUtil
{
public static function vector( …args ):Array{
var arr:Array;
var len:int = args[0];
arr = new Array(len);
if( args.length > 1 ){
for ( var i:int = 0; i< len; i++ ){
arr[i]=( vector.apply( null, args.slice(1) ) );
}
}
return arr;
}
}

example usage

var k:Array = NKUtil.vector(3,4,5);
for( var i:int =0; i<3; i++){
for ( var j:int =0; j<4; j++){
for( var m:int=0; m<5; m++){
k[i][j][m] = i*j*m;
}

}
}

My New Blog

December 12, 2007

I’ve decided to start a new blog again.

This blog will be used to talk about programming stuff that I do. Most of it will be focused on applications made in Adobe Flex and I will be open-sourcing most of my stuff for people to learn and help me to learn too =)

Thats all for now.

Hello world!

December 12, 2007

Welcome to WordPress.com. This is your first post. Edit or delete it and start blogging!