1
votes

In my project i use swfs bundled with resources. These bundles are created from another utility application. Application creates an Package.as file with [Embed] tags puts all resources to the the same directory and runs mxmlc to compile bundle swf.

Bundled swf works like a charm. I can instantiate assets.

However i want to implement another utility to edit these bundles ( to add and remove resources) Here is the problem. Since this bundle.swf is not created from Flash i cannot use:

[Embed ( source="oldbundle.swf", symbol="Package_res1" ) ]  // ( "Package_res1" is class name of resource in bundle")

in creating new swf. mxmlc returns symbol not found errors.

For bytearray assets i found a solution. I write bytearrays to disk, then use those files for embed. However i cannot do the same thing for vector graphics that were added as symbol from Flash swf into the original bundle. If i write bitmapdatas on disk i would lose vectorness ( Not sure if it is a word :) ). SVG is not a complete option to substute flash symbol.

Using as3swf, i inspected the bundle swf and saw SymbolClass tag. All of the assets are defined there. I don't know why embed tag cannot find the symbol. Difference with bundled.swf symbol and Flash swf symbol is, one extends SpriteAsset( an flex framework object) other extends sprite

What can i do to use older swf as embed source for new swf?

2

2 Answers

0
votes

Your symbols need to be public.

Here's an example. First, the original SWF, let's call it Bundle.swf.

// Bundle.as
package
{

import flash.display.*;

public class Bundle extends Sprite
{
    public function Bundle()
    {
        var image:DisplayObject = new Image();
        addChild(image);
    }
}

}

This is where Image is defined:

// Image.as
package
{

import flash.display.*;

[Embed(source='image.jpg')]
public class Image extends Bitmap
{
}

}   

Now if you compile Bundle.as and open Bundle.swf, you'll see your image.

Next, we want to reuse it in a new SWF, let's call it Application.swf.

// Application.as
package
{

import flash.display.*;

public class Application extends Sprite
{
    [Embed(source='Bundle.swf', symbol='Image')]
    private var imageClass:Class;

    public function Application()
    {
        var image:DisplayObject = new imageClass();
        addChild(image);
    }
}

}

Compile Application.as and open Application.swf. You'll see the image again.

It works because Image is public.

0
votes

You can also make it work with member variables by extracting the name of the class auto-generated by mxmlc. For example, here's the same Bundle class again:

// Bundle.as
package
{

import flash.display.*;

public class Bundle extends Sprite
{
    [Embed(source='image.jpg')]
    private var imageClass:Class;

    public function Bundle()
    {
        var image:DisplayObject = new imageClass();
        addChild(image);
    }
}

}

Now if you compile it with -keep:

mxmlc Bundle.as -keep

You can find the generated code in a file called Bundle_imageClass.as in the generated directory, with the following contents:

package 
{

import mx.core.BitmapAsset;

[ExcludeClass]
[Embed(_resolvedSource="/Users/manish/Code/test/image.jpg", _column="6", source="image.jpg", exportSymbol="Bundle_imageClass", _line="9", _file="/Users/manish/Code/test/Bundle.as")]

public class Bundle_imageClass extends mx.core.BitmapAsset 
{
    public function Bundle_imageClass() 
    { 
        super(); 
    }

}

}

Look for exportSymbol. That's your symbol name for embedding into other SWFs.

Now the Application class:

// Application.as
package
{

import flash.display.*;

public class Application extends Sprite
{
    [Embed(source='Bundle.swf', symbol='Bundle_imageClass')]
    private var imageClass:Class;

    public function Application()
    {
        var image:DisplayObject = new imageClass();
        addChild(image);
    }
}

}

Use the exact value you find in exportSymbol in the generated code (in this case, Bundle_imageClass), and you should be good.