2

I have Main.fla and SkinA.fla. Both have MovieClip library item: MC_BrandLogo.
I'm loading the SkinA.swf into Main.swf in the current application domain trying to replace the class inside Main.swf. If there is no library item in the Main.fla, I can instantiate MC_BrandLogo with the correct graphic. If the MC_BrandLogo already exist in the Main.fla then that graphic is used even though I loaded new one in the current application domain.

Is there a way to replace existing linked movie clips with loaded dynamically?

var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onSkinLoaded);
var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
loader.load(new URLRequest("SkinA.swf"));

function onSkinLoaded(e:Event):void {
    trace("loaded Skin");
    addChild(new MC_BrandLogo());
}

EDITED: There is no way to override the images I was trying to override, because this is how application domains work. If the definitions exist in the parent application domain, they are used.

plam4u
  • 317
  • 1
  • 11

2 Answers2

2

Beaten to the punch. JonnyReeves is correct I believe. A good discussion on this topic can be found here:

Application Domains on Senocular

  • Senocular's article is a Great reference; I should have included it in my answer, Wes! – JonnyReeves Feb 05 '12 at 11:12
  • For sure, it's certainly a lot less confusing than Adobes own information on this topic. I think you nail the crux of it though. – WesLastLevel Feb 05 '12 at 11:18
  • @JonnyReeves, I've tried your method but it doesn't work.
    1) ApplicationDomain don't have "getDefinitionByName" but "getDefinition"
    2) using _skinAppDomain.getDefinition returns null for MC_BrandLogo and I'm sure it's linked in the SkinA.swf. Adding the whole loader shows the logo correctly
    3)loader.content.loaderInfo.applicationDomain.getDefinition(brandLogoSymbolName) as Class; is getting the non-null definition but it's the Main's logo placeholder.
    – plam4u Feb 05 '12 at 11:59
  • @WesLastLevel, I've read that article (in fact I had it opened while writing the question) and it works when you don't have placeholder in the Main.swf, but my question is about using both placeholder and new graphics together. – plam4u Feb 05 '12 at 12:03
  • @PlamenAndreev If the class definition is not being found in `SkinA.swf` then I'm guessing you have not created the correct linkage in the Flash Authoring Environment when the SWF was published. SWF Explorer is a library for listing all classes contained in an Application Domain which might come in useful: http://www.bytearray.org/?p=175 – JonnyReeves Feb 05 '12 at 12:14
  • @JonnyReeves, I'll test and see what SWFExplorer traces out. Here is the link to my settings in Flash IDE: http://screencast.com/t/MxaKT9qMHp – plam4u Feb 05 '12 at 12:17
  • @JonnyReeves, I've tested loading the SkinA.swf in a new flash document with the following code: http://screencast.com/t/5zGEN23nKO8q. Output: MC_BrandLogo MC_BrandLogo 1. Also, I changed the name of the linkage to make sure that it's the correct linkage to "skin.MC_BrandLogo" and it traces fine again. Do you know why the _skinAppDomain.getDefinition returns null? – plam4u Feb 05 '12 at 12:23
0

As far as I know you can not overwrite a Class Definition in an ApplicationDomain unless you wish to resort to manipulating bytecode at runtime.

What you can do, however, is load your skin SWF into a child Application Domain and then retrieve the appropriate Class Definition (symbol) via ApplicationDomain.getDefinition; ie:

private var _skinAppDomain : ApplicationDomain;

function loadSkin() : void {
    // Keep a reference to the Skin's application domain.
    _skinAppDomain = new ApplicationDomain();

    var loader:Loader = new Loader();
    var context:LoaderContext = new LoaderContext(false, _skinAppDomain);

    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onSkinLoaded);
    loader.load(new URLRequest("SkinA.swf"));
}

function onSkinLoaded(e:Event) : void {
    var brandLogoSymbolName : String = "MC_BrandLogo";

    // Retrieve the symbol from the Skin's Application Domain directly.
    var brandLogoClipClazz : Class = _skinAppDomain.getDefinition(brandLogoSymbolName);

    // Check we have the symbol.
    if (brandLogoClipClazz == null) {
        throw new Error("Skin SWF must include a symbol named: " + brandLogoSymbolName);
    }

    addChild(new brandLogoClipClazz());
}

To help debug missing symbol names in ApplicaitonDomains you can list all Class Definitions (symbols) contained by using SWF Explorer.

JonnyReeves
  • 6,119
  • 2
  • 26
  • 28