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!
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.
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.
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
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.
“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.
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
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.
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.
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.
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.
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.