External Runtime Library Update

December 22nd, 2007

I just built a utility that will allow you to dynamically load in a swf with library assets and pull them out to use them anywhere in your application. This is the evolution of this code example from Adobe. Here is what you need to know to get it up and running quickly:

Create two FLA’s, one is the main app, the other the skin. In the main app imports the utility and have it load in the skin swf. Once the skin is loaded, you can use the utility to pull out library assets based on the full class path name. In the skin create some library items and link them up to “real” class file documents. You cannot use the default setting where flash offers to create the class path for you, it mush be a real file on your computer in the src folder. Make sure “load in first frame” is checked and you should be able to pull the asset out of the loaded skin and use in your main app.

One thing to remember, classes that you load into your main file do not override classes already existing in the library. I have yet to figure out how to access two classes with the same name that are in the Main and Skin file. It may have something to do with the name space loaded classes go to but could not find any documentation to explain it. If you have any suggestions please leave me a comment bellow.

package com.jessefreeman.utils {
       
        import flash.display.DisplayObject;
        import flash.display.Loader;
        import flash.display.MovieClip;
        import flash.events.*;
        import flash.events.Event;
        import flash.events.EventDispatcher;
        import flash.events.IEventDispatcher;
        import flash.net.URLLoader;
        import flash.net.URLRequest;
        import flash.system.ApplicationDomain;
        import flash.system.LoaderContext;
        import flash.utils.Proxy;
        import flash.utils.getDefinitionByName;
        public class RuntimeAssetExplorerUtility extends Proxy implements IEventDispatcher {
               
                public static const INIT:String = “init”;
                private static var __instance:RuntimeAssetExplorerUtility;
                private var eventDispatcher:EventDispatcher;
                private var data:XML;
                private var urlLoader:URLLoader;
               
                private var _assets_list:Array;
               
                /**
                 * Use RuntimeAssetExplorerUtility.instance to access method on the utility.
                 * @return instance: Reference to the class
                 */

                public static function get instance ():RuntimeAssetExplorerUtility{
                        if(RuntimeAssetExplorerUtility.__instance == null) {
                                RuntimeAssetExplorerUtility.__instance = new RuntimeAssetExplorerUtility(new SingletonEnforcer());
                        }
                        return RuntimeAssetExplorerUtility.__instance;
                }
               
                /**
                 * A singleton Utility used to load external swfs and pull Linked Library Elements out of it. External swf’s library assets must
                 * be linked to real class files for them to get compiled into the swf and become accessible. Using Flash’s auto class creator
                 * when the class does not exist will not work.
                 */

                public function RuntimeAssetExplorerUtility(enforcer:SingletonEnforcer) {
                        eventDispatcher = new EventDispatcher();
                }
               
                /**
                 * Loads and external library swf
                 * @param url: String path to external swf
                 */

                public function load_library(url:String):void{
                        var path:URLRequest = new URLRequest(url);
                        var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
                        var loader:Loader = new Loader();
                        loader.contentLoaderInfo.addEventListener(Event.COMPLETE,library_load_complete);
                        loader.load(path,context);
                }
               
                /**
                 * Fires off an INIT event to let listeners know the library is availible for use.
                 */

                private function library_load_complete(event:Event):void {                 
                        var library_assets:* = event.target.content;
               
                        dispatchEvent(new Event(RuntimeAssetExplorerUtility.INIT, true, true));
                }
               
                /**
                 * This returns a libary assets and when it is created, passes in the config object into the class’s construtor.
                 * @param class_name: Full class path name to library asset - "com.jessefreeman.ui.Button"
                 * @param config: Object with configuration data used by the constructor of the class being retrieved.
                 * @return: initialized MovieClip instance of class. Asset will still need to be added to the display tree to be seen.
                 * @example
                 *
                 * var header_config:Object = new Object()
                 *            header_config.x = 0;
                 *            header_config.y = 0;
                 *           
                 *      addChild(RuntimeAssetExplorerUtility.instance.add_asset_to_stage(
"com.photogallery.v2.views.skins.assets.Header",header_config))
                 */

                public function get_library_asset(class_name:String, config:Object):* {
                       
                        var AssetClass:Class = getDefinitionByName(class_name) as Class;
                       
                        if(AssetClass) {
                                var mc:* = new AssetClass(config);
                                return mc;
                        }else{
                                return null;   
                        }

                }
               
                /** Following allows Event dipatch and listen support to Singleton **/

                public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, weakRef:Boolean = false):void {
                        eventDispatcher.addEventListener(type, listener, useCapture, priority, weakRef);
                }
               
                public function dispatchEvent(event:Event):Boolean {
                        return eventDispatcher.dispatchEvent(event);
                }
               
                public function hasEventListener(type:String):Boolean {
                        return eventDispatcher.hasEventListener(type);
                }
               
                public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void {
                        eventDispatcher.removeEventListener(type, listener, useCapture);
                }
               
                public function willTrigger(type:String):Boolean {
                        return eventDispatcher.willTrigger(type);
                }

        }
}

class SingletonEnforcer {}

Since this is a singleton class you would call it by the ClassName.intance then the method like so RuntimeAssetExplorerUtility.instance.load_library(”/path/to/library.swf”);

This can also be used for Fonts. It is somewhat similar to what Flex does with embedding assets and is a good step in helping bridge the gap between the two in case you are getting ready to make the Flex move from Flash CS 3.

3 Responses to “External Runtime Library Update”

  1. The Flash Art of War » Blog Archive » Eclipse, FTD 3, and FLEX 3 SDK Says:

    [...] is to use the SDK to compile my main apps and use the IDE to create swf libraries to use with my External Runtime Library Utility. Pick up the tutorial here or the PDF here. p Posted by FlashBum Filed in Waging [...]

  2. Mike_G Says:

    Thanks for the post. I’ve been looking for a way to implement this technique into the GAIA framework (not sure if your familiar?). GAIA uses multiple SWFs as “pages”. I want to have access to assets that are loaded once (when the site initially loads). I can basically get this working, but I have to set up the URLRequest to load the remote library into every page SWF. This isn’t ideal.

    I was wondering if I could trouble you to post some example source files of this working. It would be greatly appreciated.

    Many thanks in advance!

  3. FlashBum Says:

    I will see what I can put together for you in a future post. Hope it works out.

Leave a Reply