开发者

Managing Singletons in external swfs

I'm dealing with the scenario whereby my code might be included in other Flash content either included via import .as commands and then referenced as a Singleton, e.g.

import com.as3.Singleton;
...
...

Singleton.birth();
Singleton.getInstance().test();

...but also imported as a runtime library; with the Singleton class exported as a .swf beforehand (instead of pre-baking the class).

How should I reference the Singleton once Event.COMPLETE has fired off from the Loader that brings in the swf? Normally I'd code something like:

public function singletonCompleteHandler(event:Event):void {    
var mySing:Singleto开发者_JAVA技巧n = _loader.contentLoaderInfo.content as Singleton;
}

...but I know I don't want to be referencing the singleton via a "var" reference. I'm not explaining very well, but basically once the singleton.swf has loaded in I need to use the code within it within a singleton model (i.e. ensure there's only one instance of it throughout my application).

Copy of the Singleton class included below (thanks for any thoughts on this by the way).

package
{
    public class Singleton extends Sprite
    {
        private static var instance:Singleton;

        public function Singleton() {
            if (instance) {
                throw new Error("Singleton can only be accessed through Singleton.getInstance()");
            }
        }

        public static function birth() {
            if (instance == null) {
                instance = new Singleton();
            }
        }

        public static function getInstance():Singleton {
            return instance;
        }

        public function test():void {
            trace("Testing our singleton.");
        }
    }
}


First of all, if you're loading it dynamically, then you don't want to have a reference to it in your loading SWF (otherwise it would defeat the point).

So I'm guessing you're looking to do something like this:

function completeHandler(event:Event):void
{
    var singleton:Object = loader.contentLoaderInfo.content;

    var instance:IMyObject = singleton.getInstance();
    instance.test();
}

IMyObject is of course optional here. If you do it like this, your singleton instance will have to implement IMyObject.

interface IMyObject
{
    function test():void;
}

This is all to avoid having to reference the actual class in your loading SWF. Like I said, the interface is optional: you can just use Object instead.

... and now on to the main point: load the singleton SWF into the loading SWF's own "application domain".

http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/system/LoaderContext.html#applicationDomain

var lc:LoaderContext = new LoaderContext();
lc.applicationDomain = ApplicationDomain.currentDomain;

loader.load(new URLRequest("Singleton.swf"), lc);

You see, normally when you load a SWF, it gets loaded into its own application domain. But this makes it impossible to enforce the singleton pattern on the loaded SWF, because each instance of the class can live in its own application domain (hence you can end up with multiple instances). So if you want to enforce this across multiple SWF loads then you want to load it into the loading SWF's application domain.


If your question is "How should I reference the Singleton once Event.COMPLETE has fired off from the Loader that brings in the swf?", then you can do it with:

var Singleton:Object = _loader.contentLoaderInfo.applicationDomain.getDefinition('Singleton');

But, I'm not sure what you mean about not wanting to use a "var" reference.

On a side-note, there's a good chance a global variable would be a better option than a Singleton class for an API.

package myPackage
{
    public var myGlobal:MyGlobal = new MyGlobal();
}

Which you can access with myPackage.myGlobal

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜