How to preload bundles generated from SWF files?


#1

I would like to use the openfl process SWF_FILE.swf command to generate the classes for my assets and be able to just use them at run-time like as if I had <library path="path/swffile.swf" generate="true" preload="true" /> in my project.xml file.

I’m not sure how to setup my project.xml file so that I have access to my generated classes and not use the SWF file any longer.

Do I always need to use AssetLibrary to load my bundles first?


#2

I haven’t tried this recently, but there’s a possibility it might preload if you do the following:

  1. Process your SWF, put it in your assets in a directory to be included (such as “Assets”)
  2. Make sure your asset directory is set to preload (such as `
  3. Access your library using the relative name, such as Assets.loadLibrary ("assets/library.bundle");

I’m not sure if in this case, the whole library will be preloaded, or if it will only preload the asset manifest, but I think testing is a start to determining how to move forward with this feature


#3

I would love to use openfl process swfFile.swf to generate my classes so I can easily access objects and nested objects of my to-be-imported MovieClips (FlashDevelop has problems with recognizing some generated classes and it breaks auto-completion). And then use the generate=true preload=true to actually compile the app with the proper classes to be generated once again in the binaries.

So I’ll try using something like <source path="assets/myBundle.bundle/src" if="false" /> to get access to my generated classes (since they’re all in the common namespace package of package ;) and not use the same classes twice in the actual app.

It would be nice if there would be a well-defined flow of how to properly use openfl process though. Or maybe have some kind of a flag for the compiler to load a bundle list during compile-time so the devs can choose what to load during run-time and what to load during compile-time.


#4

I’ve been looking deeper into generated classes and I can see that it omits any info of the nested objects. For example I’ve created a MovieClip that has two objects: a TextField with an instance name of tf and another MovieClip with an instance name of testMC. Usually I would expect those names to be accessible through the generated classes, but the current generated class has no such info:

package ; #if !flash

import openfl._internal.formats.swf.SWFLite;
import openfl.display.MovieClip;
import openfl.Assets;


class BigMenuMC extends MovieClip {
	
	@:keep public var mainLayer (default, null):openfl.display.MovieClip; // it does pick up the layer names, that's interesting to note
	@:keep public var mainLayer_prop_ (default, null):privatePkg.___LayerProp___;
	
	public function new () {
		
		super ();
		
		var swfLite = SWFLite.instances.get ("lib/testSWF/testSWF.bin");
		var symbol = swfLite.symbols.get (9);
		
		__fromSymbol (swfLite, cast symbol);
	}
}
#else
@:bind @:native("BigMenuMC") class BigMenuMC extends flash.display.MovieClip {
	
	
	@:keep public var mainLayer (default, null):openfl.display.MovieClip;
	@:keep public var mainLayer_prop_ (default, null):privatePkg.___LayerProp___;
	
	
	public function new () {
		super ();
	}
}
#end

I’m wondering since when was this feature changed, because usually I remember all the nested objects were exposed before so I could have complex nested systems.

Just in case, it’s true for classes generated through openfl process as well as generate="true"


#5

In case if anyone needs to use openfl process SWF_NAME.swf, here’s my solution:

Basically you can use project.xml's <library/> tag, but it often breaks auto-completion for FlashDevelop and you generally have to compile once first to generate the files in the binary output folder.

So use something like openfl process path/to/project/root/_generated to create a _generated folder within your project’s root folder. Then add the generated source path in your project.xml file with following command:

<source path="_generated"/>

You can add it right below your original source, so it might looks something like this:

<?xml version="1.0" encoding="utf-8"?>
<project>
	<!-- NMML reference: https://gist.github.com/1763850 -->
	
	<!-- metadata, make sure 'package' is at least 3 segments (ie. com.mycompany.myproject) -->
	<meta title="Generated Code" package="GeneratedCode" version="1.0.0" company="Creative Magic" />
	
	
	<!-- output -->
	<app main="Main" file="GeneratedCode" path="bin" />
	
	<window background="#000000" fps="60" />
	<window width="800" height="480" unless="mobile" />
	<window orientation="landscape" vsync="false" antialiasing="0" if="cpp" />
	
	<!-- classpath, haxe libs -->
	<source path="src" />
	<source path="_generated"/>
	
	
	<haxelib name="openfl" />
	
	<!-- assets -->
	<icon path="assets/openfl.svg" />
	
	
	<!-- optimize output
	<haxeflag name="-dce full" /> -->
	
</project>

This will allow you to use auto-completion within your project, but it won’t compile, because the processed files aren’t being pre-loaded.

To fix this, just create a copy of the project.xml file and call it something like build.xml. Remove the added <source path="_generated"/> line add instead define your SWF as a library with a line like this: <library path="assets/SWF_FILE.swf" preload="true" generate="true"/>.

Your build.xml file might look something like this:

<?xml version="1.0" encoding="utf-8"?>
<project>
	<!-- NMML reference: https://gist.github.com/1763850 -->
	
	<!-- metadata, make sure 'package' is at least 3 segments (ie. com.mycompany.myproject) -->
	<meta title="Generated Code" package="GeneratedCode" version="1.0.0" company="Creative Magic" />
	
	
	<!-- output -->
	<app main="Main" file="GeneratedCode" path="bin" />
	
	<window background="#000000" fps="60" />
	<window width="800" height="480" unless="mobile" />
	<window orientation="landscape" vsync="false" antialiasing="0" if="cpp" />
	
	<!-- classpath, haxe libs -->
	<source path="src" />
	
	<haxelib name="openfl" />
	
	<!-- assets -->
	<icon path="assets/openfl.svg" />
	
	<library path="assets/obj.swf" preload="true" generate="true"/>
	
	<!-- optimize output
	<haxeflag name="-dce full" /> -->
	
</project>

When you want to develop your app, just use your project.xml for references to the generated classes. When building, use command line to build. Your command might looks something like this:

lime build build.xml android

That fixed my problem.
Happy coding!


#6

You shouldn’t need to make two separate project files for this. Instead, use if and unless tags:

<source path="_generated" if="display" />
<library path="assets/SWF_FILE.swf" preload="true" generate="true" unless="display" />

#7

Thanks! That’s awesome!

A quick question - how did you know this? I did look for info on project.xml and I didn’t necessary find this info…


#8

if and unless tags are discussed here, but it doesn’t mention all of the things they can and can’t do. There are a few examples of unless="display" on these forums, but they’re in totally unrelated threads, so there’s no way you could have found them. (And apparently both were posted by me. Huh.)

The easiest way to figure this out for yourself would have been to look at OpenFL’s include.xml file, which uses unless="display" a couple times. (This is how I figured it out those previous two times.)

This time, I forgot about the easy answer and instead dug through the source code. Don’t try this at home unless you already know your way around Lime, or you have lots of time to kill.