Compiled Code Libraries

Instructions on creating your own SWC libraries

Concepts

On the most basic level, SWC libraries are just compiled ActionScript classes. You need to include the necessary classes and the code will be included in your compiled SWC.

Libraries can also declare components that can be used in MXML files by referencing a namespace.

In this example, we’re going to assume that you have both code and components to include.

We’re also going to use asconfigc to build the library.

Building blocks

There are several files you will likely use for creating libraries.

  1. manifest.xml
  2. MyLibrary.as
  3. defaults.css
  4. compile-config.xml
  5. js-compile-config.xml
  6. asconfig.json

Of these files, manifest.xml and defaults.css are optional. compile-config.xml and js-compile-config.xml are technically not needed either, but using them makes it easier to compile your library.

The Manifest

The manifest file (in our example named manifest.xml) is the file where you declare the components you want to make available to MXML using your namespace.

A manifest file is a very simple xml file with the following structure:

<?xml version="1.0"?>
<componentPackage>
    <component id="MyComponent1" class="com.somesite.MyComponent1"/>
    <component id="MyComponent2" class="com.somesite.MyComponent2"/>
</componentPackage>

Where the id of each component is the qualified name you declare in MXML and the class is the fully qualified class path of your class.

The namespace for your manifest is declared in compile-config.xml and js-compile-config.xml below.

The main class file

In order for classes to be included in your SWC, you need to actually use them somewhere. Any classes which are declared in your manifest are considered “used”, and they along with all their dependencies will be included. However, there will likely be other classes and utility functions which are not in the manifest that you want to include. The simplest solution for this is to have a Class which references all the classes you want included. To do this, you include MyLibrary.as at the root of your src folder and it should look like this:

package {
	
	internal class MyLibrary {
		import com.somesite.ClassA;ClassA;
		import com.somesite.ClassB;ClassB;
		import com.somesite.ClassC;ClassC;
		import com.somesite.ClassD;ClassD;
	}
}

Just referencing the classes like that is enough to have them included.

The CSS file

defaults.css is where you declare any HTML or Royale CSS that’s needed for your library. This is where you declare default beads and the like. Make sure you declare your namespace that’s used for the MXML declarations of you components.

@namespace "library://ns.somesite.com/kapow";
@namespace js "library://ns.apache.org/royale/basic";

MyComponent1
{
	IBeadModel: ClassReference("com.somesite.ComponentModel");
	IBeadView:  ClassReference("com.somesite.ComponentView");			
	IBeadController: ClassReference("com.somesite.ComponentController");	
}

Config XML file

The config file is a convenience file for loading compiler options. It’s very helpful for libraries where you need to declare quite a bit of information. You need one config for the SWF build and another one for the JS build. The two files are quite similar.

The notable difference between the two files:

  1. compile-config.xml has playerglobal.swc referenced in the external-library-path.
  2. compile-config.xml has COMPILE::SWF as true while js-compile-config.xml has COMPILE::JS as true.
  3. If you have a lib/Foo.swc JS typedef (sometimes also called externs) dependency that you want to include, you should add the following to the js-compile-config.xml:
        <js-external-library-path append="true">
            <path-element>lib/Foo.swc</path-element>
        </js-external-library-path>

Note the important pieces in the config:

  1. In the namespaces section, you need to list all the namespaces you are using. Each namespace has to have a uri and a reference to the manifest file that is associated with that uri. In our case, the components will be used with the namespace library://ns.somesite.com/kapow.
  2. You need to include your css file using the include-file section. Any other accompanying files you want to include should be added there.
  3. You need to reference your main class using include-classes.
  4. You need to include the namespace(s) used with include-namespaces.

compile-config.xml:

<royale-config>
    <compiler>
        <accessible>false</accessible>
        
        <external-library-path>
            <path-element>playerglobal.swc</path-element>
        </external-library-path>
        <allow-subclass-overrides>true</allow-subclass-overrides>
        
		<mxml>
			<children-as-data>true</children-as-data>
		</mxml>
		<binding-value-change-event>org.apache.royale.events.ValueChangeEvent</binding-value-change-event>
		<binding-value-change-event-kind>org.apache.royale.events.ValueChangeEvent</binding-value-change-event-kind>
		<binding-value-change-event-type>valueChange</binding-value-change-event-type>

        <define>
            <name>COMPILE::SWF</name>
            <value>true</value>
        </define>
        <define>
            <name>COMPILE::JS</name>
            <value>false</value>
        </define>

        <keep-as3-metadata>
          <name>Bindable</name>
          <name>Managed</name>
          <name>ChangeEvent</name>
          <name>NonCommittingChangeEvent</name>
          <name>Transient</name>
        </keep-as3-metadata>
	  
        <locale/>
        
        <library-path/>

        <namespaces>
            <namespace>
                <uri>library://ns.somesite.com/kapow</uri>
                <manifest>manifest.xml</manifest>
            </namespace>
        </namespaces>
        
        <source-path>
            <path-element>src</path-element>
        </source-path>
        
        <warn-no-constructor>false</warn-no-constructor>
    </compiler>
    <include-file>
        <name>defaults.css</name>
        <path>defaults.css</path>
    </include-file>
    
    <include-classes>
        <class>MyLibrary</class>
    </include-classes>

    <include-namespaces>
        <uri>library://ns.somesite.com/kapow</uri>
    </include-namespaces>

</royale-config>

js-compile-config.xml:

<royale-config>

    <compiler>
        <accessible>false</accessible>
        
        <js-external-library-path append="true">
            <path-element>lib/Foo.swc</path-element>
        </js-external-library-path>
        <allow-subclass-overrides>true</allow-subclass-overrides>
        
		<mxml>
			<children-as-data>true</children-as-data>
		</mxml>
		<binding-value-change-event>org.apache.royale.events.ValueChangeEvent</binding-value-change-event>
		<binding-value-change-event-kind>org.apache.royale.events.ValueChangeEvent</binding-value-change-event-kind>
		<binding-value-change-event-type>valueChange</binding-value-change-event-type>

        <define>
            <name>COMPILE::SWF</name>
            <value>false</value>
        </define>
        <define>
            <name>COMPILE::JS</name>
            <value>true</value>
        </define>

        <keep-as3-metadata>
          <name>Bindable</name>
          <name>Managed</name>
          <name>ChangeEvent</name>
          <name>NonCommittingChangeEvent</name>
          <name>Transient</name>
        </keep-as3-metadata>
	  
        <locale/>
        
        <library-path/>

        <namespaces>
            <namespace>
                <uri>library://ns.somesite.com/kapow</uri>
                <manifest>manifest.xml</manifest>
            </namespace>
        </namespaces>
        
        <source-path>
            <path-element>src</path-element>
        </source-path>
        
        <warn-no-constructor>false</warn-no-constructor>
    </compiler>
    <include-file>
        <name>defaults.css</name>
        <path>defaults.css</path>
    </include-file>
    
    <include-classes>
        <class>MyLibrary</class>
    </include-classes>

    <include-namespaces>
        <uri>library://ns.somesite.com/kapow</uri>
    </include-namespaces>

</royale-config>

Building the library

Your asconfig.json file should look like this the file below. You can use any standard compiler options you need and you can also include SWF in the targets section, but if you are only targeting Javascript, it’s not necessary.

{
    "config": "royale",
    "type": "lib",
    "compilerOptions": {
        "targets": [
            "JSRoyale"
        ],
        "external-library-path": [
            "${royalelib}/libs",
            "${royalelib}/../js/libs",
            "libs"
        ],
        "js-external-library-path": [
            "${royalelib}/js/libs",
            "${royalelib}/../js/libs",
            "libs"
        ],
        "load-config": [
            "compile-config.xml"
        ],
        "js-load-config": [
            "js-compile-config.xml"
        ],
        "include-classes": [
            "MyLibrary"
        ],
        "include-sources": [
            "src"
        ],
        "source-path": [
            "src"
        ],
        "output": "target/MyLibrary.swc"
    },
    "additionalOptions":[
			//include any options you want here
    ]
}