Search code examples
actionscript-3actionscriptloadermax

Duplicated a swf loaded with LoaderMax


i'm trying to duplicate a swf loaded using greensocks LoaderMax but i don't seem to be able to

i'm using the following code:

private var _assetCache : Dictionary;

public function getAssetById(assetId:String):DisplayObject
{
    var asset:DisplayObject;

    if (!_assetCache[assetId])
    {
        _assetCache[assetId] = LoaderMax.getContent(assetId).rawContent;
    }

    asset = _assetCache[assetId];

    // duplicate bitmap
    if (asset is Bitmap)
    {
        var bmd:BitmapData = new BitmapData(asset.width, asset.height, true, 0);
        return new Bitmap(bmd, "auto", true);
    }
    // otherwise return 
    return SpriteUtils.duplicateDisplayObject(asset);
    //return asset; // if previous line is commented out, this works well but there will be only a single copy of the loaded swf, kinda negating the use of a cache
}

and this is SpriteUtils.duplicateDisplayObject(asset) (taken from this

static public function duplicateDisplayObject(target:DisplayObject, autoAdd:Boolean = false):DisplayObject
{
    // create duplicate
    var targetClass:Class = Object(target).constructor;
    var duplicate:DisplayObject = new targetClass();
    trace(duplicate, duplicate.height); // traces [MovieClip, 0]
    // duplicate properties
    duplicate.transform = target.transform;
    duplicate.filters = target.filters;
    duplicate.cacheAsBitmap = target.cacheAsBitmap;
    duplicate.opaqueBackground = target.opaqueBackground;
    if (target.scale9Grid)
    {
        var rect:Rectangle = target.scale9Grid;
        // WAS Flash 9 bug where returned scale9Grid is 20x larger than assigned
        // rect.x /= 20, rect.y /= 20, rect.width /= 20, rect.height /= 20;
        duplicate.scale9Grid = rect;
    }

    // add to target parent's display list
    // if autoAdd was provided as true
    if (autoAdd && target.parent)
    {
        target.parent.addChild(duplicate);
    }
    return duplicate;
}

if i simply return the asset from _assetCache (which is a dictionary) without duplicating it, it works and traces as a MovieClip but when i try to duplicate it, even though the traces tell me that the duplicate is a movieclip. Note the clip being loaded is a simple vector graphic on the stage of the root of the timeline

thanks in advance

obie


Solution

  • I don't think simply calling the constructor will work.

    Try doing this (I've assumed certain previous knowledge since you're able to get rawContent above):

    1) Load the data in using DataLoader in binary mode.... in the context of LoaderMax it would be like: swfLoader = new LoaderMax({name: "swfLoader", onProgress:swfProgressHandler, onChildComplete: swfLoaded, auditSize:false, maxConnections: 2}); swfLoader.append(new DataLoader(url, {format: 'binary'})); (the main point is to use DataLoader with format='binary')

    2) Upon complete, store the ByteArray which this returns into your dictionary. The first part of your above code will basically be unchanged, though the bytearray might be in content rather than rawContent

    3) Whenever you need a duplicate copy, use Loader.loadBytes() on the ByteArray. i.e. var ldr:Loader = new Loader(); ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, swfReallyLoaded); ldr.loadBytes(_assetCache[assetId]);

    As with all loading, you might need to set a LoaderContext, and if in AIR- allowLoadBytesCodeExecution = true; allowCodeImport = true;