This post describes how to load a runtime shared library (RSL) via actionscript but still be able to use it as a normal RSL within CS4 and CS5. The idea is that instead of letting the flash player automatically load the RSL (whenever it is accessed for the first time), the RSL is loaded with a Loader object via actionscript. The allows the programmer to pick the correct time to load it. Also the loading progress feedback can be shown to the user.
First I describe the various experiments I did; at the end I give a summary of the method I used.
As a start I created two flash files:
- The first file is the RSL (called test.export.picture.fla). I placed a png image inside a MovieClip (to get an asset with a nice size in bytes). Then I checked the Export for runtime sharing in the MovieClip properties, which automatically also checks the export and export in frame 1 checkboxes. As URL I used the swf filename (test.export.picture.swf)
- In the second file (called test.import.picture.fla) I extended the main timeline to be 10 frames. At frame 5 I placed a key frame and via copy and paste I placed a copy of the MovieClip from the first fla file. This will automatically set the Import for runtime sharing checkbox and fills the URL with the value that was entered at the first file.
After building both flash files, everything was working as expected. Then I tested the 2nd file with the bandwidth profiler turned on (ctrl+B) and with the Simulate Download (pressing ctrl+Enter a second time while viewing the movie). This showed that at frame 5 the RSL was being loaded.
As second part of the experiment I added some actionscript code to the 2nd flash file. At the 2nd frame I added code that loaded the RSL swf file directly using a Loader object. The scriptcode also stopped the movie and continue playing it after the RSL file was completly loaded:
var loader: Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
loader.load(new URLRequest('test.export.picture.swf'));
function onComplete(anEvent: Event): void
{
trace('loaded');
play();
}
function onError(anEvent: IOErrorEvent): void
{
trace('error');
} |
var loader: Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
loader.load(new URLRequest('test.export.picture.swf'));
function onComplete(anEvent: Event): void
{
trace('loaded');
play();
}
function onError(anEvent: IOErrorEvent): void
{
trace('error');
}
Again I tested the movie with the bandwidth profiler and simulating the download. As expected at frame 2 the RSL file was loaded. But at frame 5 the same file was loaded again. This is not really what I had hoped for. Although there is probably almost no delay the second time the RSL file is loaded because of (memory) caching, one can never be sure. Also it is not clear if this means the RSL file uses 2x the memory.
Next step I changed the actionscript so that the RSL was loaded into the same context as the main SWF:
var loader: Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
var context: LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;
loader.load(new URLRequest('test.export.picture.swf'), context);
... |
var loader: Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
var context: LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;
loader.load(new URLRequest('test.export.picture.swf'), context);
...
After testing with the bandwidth profiler, nothing seemed to have changed. However I was pretty sure the MovieClip class defined in the RSL file was now available in the main movies context. So as last test I created an empty swf file (by starting a new as3 project without anything in it) and changed the import settings so the URL was pointing to this empty swf file. I tested the movie and it was working (yay!). At frame 5 the small swf got loaded, but since the MovieClip class definition was already available, the flash player still managed to create the MovieClip instance and show it on the main timeline.
Summary
To load and use RSL files via actionscript perform the following steps:
- Create an empty Flash file and compile it into a SWF file. This file will act as a dummy file, used by the player when it has to load a RSL file.
- Create a Flash file to be used as RSL and add assets normally. When enabling Export for runtime put the name of the dummy swf file at the URL. It seems the url entered here is only used to fill in the URL when creating the imported version of the asset (trough copy and paste).
- Copy and paste assets to other library and use them normally.
- Make sure the RSL file is loaded completely before using any of the assets from it. Load it within the context of the main movie using something like:
var loader: Loader = new Loader();
var context: LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;
loader.load(new URLRequest(...), context); |
var loader: Loader = new Loader();
var context: LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;
loader.load(new URLRequest(...), context);
- If everything works ok, the asset should be used the flash player needing it to load the RSL itself.
Note: instead of using a dummy swf file, one can also use the filename of the SWF that will be initially loaded. It seems flash will not try to load it again. This is ofcourse only usable if a RSL is not used with multiple projects.
To use the above also with shared fonts, some extra work is required. This I will describe in my next post.