Monday, May 07, 2007

Loading Multiple Independent Instances of a Module

So, it's Monday night... my wife's contractions are 13 minutes apart, and it seems I have nothing better to do than blog. Of course, this is more akin to the calm before the storm that will be the next 24 hours and probably the next six months. Eventually I will once again emerge from the dark precipice that lies ominously before me. But on to modules.

I love Cairngorm... I just upgraded all my projects 2.2 and it was painless, nothing like child labor, I'm told. I am working on a project where we have to build all these pretty much independent modules, and in these modules we stick to Cairngorm as well.

The first problem we ran into occurred when attempting to load 2 instances of the same module. ModuleManager, as it turns out, keys modules by url. So if you try to load the same module twice, you're just getting a reference to the same one. There is no way around this (or so I thought) This has a number of repercussions:

  • Only one ServiceLocator instance can be instantiated - this wonderful little Error message pops up the minute you load a second instance of the module. Quick workaround is to declare the system locator code much like you do model:
    private var dataServices:ServiceLocator = ServiceLocator.getInstance();
    and abstain from using the mxml format:
    <business:Services id="dataServices" />
  • All your module instances will share the same model... so if you say do a search, get a searchresult back and stick that in your model, all your modules will display the same search results, which defeats the purpose of having separate file/image search browsers (for example).

Here's a couple other funky things I tried:

  • Created 2 modules pretty much identical, Mod1.swf and Mod 2.swf. I loaded them up and they both worked fine and independently
  • Created a copy of Mod1.swf and called it Mod1a.swf. I loaded them up and they both worked fine.
  • Tried loading two Mod1.swf and suddenly no independence, plus the ServiceLocator error.

I tried wiring up my own ModuleManager, but after a good couple hours I gave up... I was getting all sorts of weird behaviour. I figured out that everything is based around the url that you pass to ModuleManager or ModuleLoader. I was pretty much ready to give up when I had this really silly notion, I did this:

private var count:int;
private var spaces:String = "";
private function LoadModule():void{
for (var x:int; x < count; x++) spaces += " ";
var info:IModuleInfo = ModuleManager.getModule("mod1.swf" + spaces);
info.addEventListener(ModuleEvent.READY, done);
info.load();
count ++;
}
private function done(event:ModuleEvent):void{
var visual:DisplayObject = event.module.factory.create() as DisplayObject;
tabber.addChild(visual);
}
Much to my surprise, this hack worked. The modules loaded successfully and ran independently. Of course, I probably need to test this some more, but I figured I'd blog it quick before the trauma of childbirth hopefully graces me with some convenient and kind short term memory loss.

5 comments:

Anonymous said...

Fantastic!!!
Really simple and so important...
Thank's for your posts.

PS : is-it a boy or a girl?

Unknown said...

not sure if this helps with your case, but i simply appended a unique url to the url.

module.swf?uid=createUID(); and that seemed to work fine, it creates a new instance.

Rebelheart said...

I am already using this in one of my projects.This works fine when I load two instances of a module with a unique url inside the main application .

But , when I load two instances of the same module with a unique url inside another module , the service locator error pops up .Any ideas on cracking this ?

Vic Rubba said...

I actually figured out an alternative solution, send me an email and we can discuss further.

Anonymous said...

This entry saved my life... THANKS A LOT!