Cannot create MovieClip from Bytes


#1

I’ve been creating my AssetLibrary at runtime from a manifest. For SWF assets I have things working fine when deploying to HTML5 and converting to .bundle. I am having trouble supporting Flash target using plain old SWF however. You can see from the traces/comments below that everything works until I try to cast the bytes to a MovieClip.

trace("adding a swf file asset");
var id = "/assets/"+swflib+".swf";
//an AssetLibrary was created from a Manifest after  it got added using AssetManifest.addBytes earlier...trace(alp.getLibrary().list("BINARY")); // [/assets/swflibrary.swf]
trace("swflib id:"+id); // swflib id:/assets/swflibrary.swf
trace("exists:"+alp.getLibrary().exists(id,"BINARY")); // exists:true
var bytes = alp.getLibrary().getBytes (id); 
trace("bytes:"+bytes); // outputs: CWS S
var ba = ByteArray.fromBytes(bytes);
trace("byteArray:"+ba); // outputs: CWS S
var swf = new format.SWF(ba);
trace("swf:"+swf); // [object SWF]
var mc:MovieClip; 

for (key in swf.symbols.keys()) {
	trace(key); //LittleBoy
}
trace("actor.att.src:"+actor.att.src); // actor.att.src:LittleBoy
if (swf.symbols.exists (actor.att.src)) {

	var symbol:Dynamic = null;
	var charId:Int;
	charId = swf.symbols.get (actor.att.src);
	
	trace("making the actor..."); // making the actor...
	symbol = swf.data.getCharacter (charId);

	if (Std.is (symbol, SWFTimelineContainer)) {
		trace("attempt casting!"); // attempt casting!
		mc = cast symbol;
		trace("the movieclip is:"+mc); // NEVER GETS HERE
		a.addChild(mc);
		
	} 
}

I got some of this code from the format.SWF file, where the createMovieClip function has a similar “cast symbol” attempt commented out. It appears that my data is obviously there, since I can look up the symbol name. How should I properly convert the data to a MovieClip?


#2

On Flash, it does not resolve as a format.SWF, but instead, you can use flash.display.Loader to load a SWF, then call getDefinition to grab loaded content from the SWF. This is effectively what the SWFLibrary class should be doing in OpenFL (internally)


#3

I would like the loaded SWF to be contained in an AssetLibrary if I can because the rest of my framework retrieves other assets from named AssetLibraries. Is that possible?


#4

Other than using an asset library like the SWF library (which loads the SWF into memory as part of the load() process) you could use a Loader at runtime to load SWF data from bytes. This adds an extra step, but effectively is what is required on the Flash target. It’s not entirely unlike BitmapData, which must be loaded from bytes at runtime to become usable, and cannot be done immediately


#5

I was actually unfamiliar with the SWFLibrary; I’ll give that a try. Thanks!


#6

Okay, I was able to successfully convert the bytes using loadbytes :

var id = "/assets/"+swflib+".swf";
//it got added as bytes earlier...
var bytes = alp.getLibrary().getBytes (id);
var mc:MovieClip; 
var context = new LoaderContext (false, ApplicationDomain.currentDomain, null);
context.allowCodeImport = true;
var loader = new Loader ();
loader.contentLoaderInfo.addEventListener (Event.COMPLETE, function (_) {
	trace("done:"+loader.content);
	mc = cast Type.createInstance (ApplicationDomain.currentDomain.getDefinition (actor.att.src), []); //where actor.att.src is the name of the MovieClip class
	trace("mc:"+mc);
	a.addChild(mc);
	a.init();
});
loader.loadBytes (bytes, context);

And so ends many days of debugging!