Flex Feature Request: Creating Packaged Classes with [Embed]

by Josh Tynjala

The [Embed] metadata tag in the Flex SDK compiler is one my favorites. Its magical allure comes from the fact that you can take any image, SWF, or even a specific symbol from a SWF’s library and turn each of them into a class that you can use almost like any other within your ActionScript code. There’s something satisfying about this:

[Embed(source="up_icon.png")]
private static const UpIcon:Class;

private function doSomething():void
{
    var icon:DisplayObject = new UpIcon();
    this.addChild(icon);
}

That said, I think it could be improved. What if you could give your new class a fully-qualified path as well? Rather than just being placed in a variable or a constant, what if you could instantly import it anywhere like any other class in your project? Let me show you some code for what I’d like to see:

[Embed(source="up_icon.png",className="com.example.projectName.assets.UpIcon"]

Then, in any of your files, you can easily import it and use it:

import com.example.projectName.assets.UpIcon;

public class MyClass
{
    private function doSomething():void
    {
        var icon:UpIcon = new UpIcon();
        this.addChild(icon);
    }
}

Sure, I can already do something similar by creating a class with a lot of public static constants, but it feels kind of like a hack. Here’s the official feature request I made in the Flex Bug system. Do you think you’d like to see this enhanced [Embed] in a future version of the Flex SDK? If yes, please vote!

About the Author

Josh Tynjala is an indie game developer, entrepreneur, Flash and Flex mercenary, and bowler hat enthusiast.

Discussion
  1. ahh, the good old: “new Assets.ButtonUpSkin();”, I know that one well. I think this feature would be great, but one thing to consider is the issue with file size. Obviously, the way embed works is embedding the bytes of the asset in the SWF file. And since the typical way to work with Embed is to use it locally in whatever class you’re going to use the embedded asset, you can be pretty confident that you’re going to be using the embedded bytes (ie you’re not going to accidentally embed stuff you forget about and then never use). The concern I see is that if you could do the kind of embedding that you propose, it would let people get sloppy. They could declare a whole series of embedded assets, and then in their app maybe they only reference a few. Or say they stop using one of the embedded assets in their classes, but since it was defined in some other class they forget to remove it. My ideal scenario would be some compile-time checking of these Embedded assets to make sure that any of them that aren’t imported in the code ever don’t actually get embedded, just like how if your code doesn’t reference certain Flex framework controls your SWF size isn’t bloated with that unused codebase.

    Anyway, I’d dig this feature.

    posted by Doug McCune on 01.13.2008
  2. A ton of embeds in an assets class could easily be forgotten too. I rarely embed things in a local class if there’s more than one or two things embedded in the entire app, so the risk is about the same for me. Good point, though.

    One thing I didn’t mention, but is worth questioning, is where are we supposed to place these sorts of Embeds? With a centralized assets class, you specifically reference it in your code so there’s nothing special about it. For embeds like this, there needs to be a specific way to make sure that the compiler knows about them, beyond adding them all to the metadata section in the main application file or something. That could get messy.

    posted by Josh Tynjala on 01.14.2008
  3. That would be a great feature. and save having more code bloat at the top of Classes.

    Yeah have to agree with Doug on the Compile time checking for embedding the bytes. I could see util.IconLibrary classes getting crazy bloated, ala Java styles.

    I also us the BitmapAsset for Types of imported graphics instead of DisplayObject, in my code as its a bit more descriptive. (Most images get typed to a subclass of this at compile time), but thats merely personal preference. Potato, potato stuff really.

    Will be voting once I get my account confirmation email :)

    posted by Campbell on 01.14.2008
  4. Yeah, OK, you’re definitely right about the bloat issue already if you use a static assets class. I change my previous comment and instead of citing that as a danger, that’s an additional feature request. I would love to be able to be that lazy and just define a whole slew of embedded assets, knowing that only the ones I explicitly instantiate somewhere in my code by calling new MyEmbeddedAsset(); will actually get embedded in the SWF. This would be a great feature with the current state of embedded assets too.

    As to where they would go, not sure, maybe in an additional metadata tag in the main Application? Or how about in a CSS file, which sounds kinda weird at first, but I think might make some kind of sense.

    posted by Doug McCune on 01.14.2008
  5. “Sure, I can already do something similar by creating a class with a lot of public static constants, but it feels kind of like a hack.”

    I actually don’t mind this method too much. I know all my assets will be in the one place, a little like them all being inside a Library in Flash. That said being able to specify a package would open up more options.

    I definitely for the compiler only embedding assets that are used.

    posted by Tink on 01.14.2008
  6. I might be missing something, but this feature is already present:

    package x.y
    {
       [Embed(source="myLibrary.swf", symbol="myAsset")]
       public class Asset extends MovieClip
       {
       };
    };

    To create a new Instance you can just do ‘new x.y.Asset();’.

    Greetz Erik

    posted by EECOLOR on 01.14.2008
  7. That’s interesting, Erik. I didn’t know that was possible. Personally, though, I’d prefer to be able to define many different asset classes in one file.

    posted by Josh Tynjala on 01.14.2008
  8. better anyway. It keeps things in the same structure as the rest of your code. Yeah, it creates these mini classes that are essentially empty except for the embed statement, but I think I’m OK with that.

    I assume that compile-time checking of these Embeds doesn’t happen, but seems like with that structure it wouldn’t too hard to do (hell, I dunno, maybe it does it now).Ha, I didn’t know you could do that either. I might argue that that’s

    Erik, thanks for showing us stuff we didn’t know.

    posted by Doug McCune on 01.14.2008
  9. Compile-time checks of the Embed class that Erik showed does happen. Note that if you use the parameter “-keep” to see the generated classes, you’ll see that an Embed class is generated for each Embed variable. In other words, the Embed-on-a-variable is just syntactic sugar for Embed-on-a-class.

    posted by Brian Deitte on 01.14.2008
  10. I know it’s a little ugly but I have been using swc assets from flash in FB by addling them to the build path in the properties of a flex project. I get code introspection at develop time (nice!) and I can then import the package and instantiate it like any other display object.

    I will vote for your feature request.

    posted by Randy Troppmann on 01.14.2008
  11. Ah yes, Flash SWCs are a pretty good option too. If I don’t want to use Flex, but I still need UI components, I just throw all the Flash CS3 components in a big SWC and add it to my build settings in an AS Project. I don’t think I had extended that thought to specifically targeting skin assets rather than whole components, but it makes sense. Easier than writing out all the [Embed] lines too.

    posted by Josh Tynjala on 01.14.2008
Share Your Thoughts

To display code in comments: <pre>Code here. May be multiline. Format XML with &gt; and &lt; entities.</pre>

Some HTML allowed in comments: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>