Run-time class and asset sharing across multiple SWFs in Flex (AS3)

I have recently ported some Flash 8 widgets to AS3 for use in a prototype site we will be launching in the next few weeks. The widgets are all quite simple, displaying graphs, but became fairly heavy due to an embedded font and graphics. All told the four SWFs totalled over 300K so I decided to do some optimisation.

Sharing library assets and classes at run-time means the user can download (and cache) the library SWFs once and use them across the visible SWFs in the page. Doing so has reduced the total footprint to under 100K and has the added bonus of meaning I can change the font for example without having to re-compiled the visible SWFs.

Sharing simple assets

For some of the widgets, access to remote assets was required from more than one class. To achieve this, I wrapped the asset and embedded font classes in classes with static access:

Shared assetsThe static asset access class looks something like this:

package com.fridayforward.sharedAssets {
    
    public class Library {

        private static _callback:Function;
        private static _assets:LoaderInfo;

        public static function init(callback:Function, url:String="../sharedassets.swf"):void {

            // set callback function
            _callback = callback;

            // load assets            
            var request:URLRequest = new URLRequest(url);
            var loader = new Loader();            
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
            loader.load(request);
        }

        private static function onLoaded(event:Event):void {

            // retrieve assets
            _assets = LoaderInfo(event.target);

            // callback
            _callback();
        }

        public static function getAsset(id:String):Sprite {

            // return asset class
            var c:Class = _assets.applicationDomain.getDefinition(id) as Class;
            return Sprite(new c());
        }
    }
}

The assets are loaded in the application constructor, with a callback to continue once assets are available:

package {

    import com.fridayforward.sharedAssets.Library;

    public class Application    {

        public function Application():void {

            // load assets
            Library.init(init);
        }

        private function init():void {

            // now have access to asset library
            // continue with application...
        }
    }
}

The assets can then be accessed from anywhere within the application:

var myAsset:Sprite = Library.getAsset("MyAsset");
addChild(myAsset);

This worked nicely for sharing simple assets but I also wanted to share embedded fonts used in TextFields. To do this, I created a separate AS3 application which contains a class that embeds any fonts I want to share and creates TextFields using them. This class is then made available through a static class to all parts of my applications.

The static Text class looks something like:

package com.fridayforward.sharedFonts {

    public class Text {

        private static _callback:Function;
        private static _textField:Object;

        public static function init(callback:Function, url:String="../embeddedFonts.swf"):void {

            // set callback function
            _callback = callback;

            // load assets
            var request:URLRequest = new URLRequest(url);
            var loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
            loader.load(request);
        }

        private static function onLoaded(event:Event):void {

            // retrieve assets
            var tfClass = event.target.applicationDomain.getDefinition("EmbeddedTextField") as Class;
            _textField = new tfClass();

            // callback
            _callback();
        }

        public static function textField(text:String, size:uint, color:uint=0, ...):TextField {

            // pass to EmbeddedTextField object
            return TextField(_textField.textField(text, size, color, ...));
        }
    }
}

The root class of the EmbeddedText application simply acts as a wrapper to allow access to the contained EmbeddedTextField class:

package {

    import com.fridayforward.sharedFonts.EmbeddedText;

    public class EmbeddedText extends Sprite {

        public var embeddedTextField;

        public function EmbeddedText():void { }
    }
}

The EmbeddedTextField class provides the functionality to create TextFields:

package com.fridayforward.sharedFonts {

    import flash.text.AntiAliasType;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;

    public class EmbeddedTextField {

        [Embed(source="...VAG Rounded BT.ttf", fontName="VAG", mimeType="application/x-font")]
        private var vagFont:Class;

        public function EmbeddedTextField():void { }

        public function textField(text:String, size:uint, color:uint=0, ...):TextField {

            var format:TextFormat = new TextFormat();
            format.font = "VAG";
            format.size = size;
            format.color = color;

            var tf:TextField = new TextField();
            tf.text = text;

            return tf;
        }
    }
}

This is then accessed in the same way as before:

package {

    import com.fridayforward.sharedFonts.Text;

    public class Application {

        public function Application():void {

            // load assets
            Text.init(init);
        }

        private function init():void {

            // continue with application...
            addChild(Text.textField("Application Title", 20, 0));
        }
    }
}

If you have a large library of assets you need to load it might be a good idea to display a preloader while waiting for them to download.

2 Comments for Run-time class and asset sharing across multiple SWFs in Flex (AS3)

  • 7:02 pm, 13th February 2009
JJ

Just what i was looking for, thanks!

  • 6:21 pm, 28th October 2010
IJGald

Thank you! This will be very helpfull

Leave a comment

  • Name
  • Email
  • URL
  • Comment

Last.fm

  • No recently listened tracks.

Twitter