Grant Skinner

The "g" in gskinner. Also the "skinner".

@gskinner

BitmapSlice9: Scale9 for Bitmaps in Flash Pro

BitmapSlice9 is a command for Flash Pro that preps bitmaps for use with Scale9. Among other things, this makes it easy to use bitmap skins for controls, which is quite common for games and mobile apps.

In short, it slices your target bitmap into rectangles with custom bitmap fills according to the applied Scale9 grid. It also preserves your original bitmap in a guide layer (to keep it from compiling into the SWF) to make it easy to adjust and reapply the command.

Here’s a quick video showing how it works. It’s the first tutorial video I’ve ever done, and the audio is really terrible – I obviously need to get a decent microphone.

Continue reading →

Return of the Blue Lego

As some people have noticed, Apple has eliminated the blue lego icon that indicates a missing plugin on the iPad. I believe that this is a not so subtle way of shifting users from believing that the iPad browser is lacking something, to believing that the site they are viewing is broken.

In response to this, I’ve created the blueLego edition of SWFObject 2.2. It works exactly the same as regular SWFObject, except it will display the blue lego icon, with a link to Adobe’s get Flash Player page on iPhone, iPod, and iPad.

As of April 13, this page correctly displays content explaining to iPad users why Flash is unavailable on their device. This is the same content shown on the iPhone, which is described here. You’re obviously free to modify the iDevice alternate content or the code itself to suit your own needs.

It is released under the MIT license, and you can download it by clicking here. Whether it is useful for production or not, I leave to you. It was created more as a statement than anything.

The blueLego art was created from scratch and I’ve included the source FLA so you can modify it as you like.

It looks like this in use:

You can test it by pointing your iDevice browser to this url:

http://gskinner.com/playpen/bluelego/

Thanks to Rob Hall and others for helping spark the idea.


Edit: Copying my comment from below here, to clarify the purpose of this post:

This post was *not* a Flash pro/con, or Flash vs HTML5 statement.

Apple made a conscious decision to move from fairly and correctly showing users that they were unable to display a certain type of content (whether you like that content / technology or not), to making it look like the site itself is broken. It places the apparent blame not on Adobe or Apple, but on content providers. Regardless of your position on Flash or plugins, this is wrong, and it’s a dirty play by Apple.

This post, and the blueLego SWFObject library were intended as a light way to point out the issue and to help rectify it for site owners by letting them accurately convey why their content does not work on an iPad. It was not intended as some weak form of “revenge” at Apple.

Colorgasm Music Visualizer

While exploring the flash.sampler API this morning, I whipped together a quick demo to test its output when rapidly creating / deleting objects.

The demo turned out kind of cool in it’s own right, so I thought I’d post it. Nothing incredible, but you’ve gotta love what you can accidentally create in a couple hours and 1.8kb in Flash.

Note that I’m too lazy to add a preloader, so nothing will happen until it loads the 5.4MB music file.

One day maybe I’ll play with this some more, tie in proper spectrum analysis, a preloader, etc. *shrug* The Hype framework would probably work great as a starting point for that.

Continue reading →

The flash.sampler.* API and the Sample object

I recently became aware of the flash.sampler.* package, which gives you access to the same profiling data via AS3 that FlashBuilder uses for it’s profiler. It’s a very useful API for performance and memory profiling, offering enhanced introspection tools, more granular timing, method invocation counts, and method invocation sampling. It has been available in the Debug player since player 9.0r115, but I somehow remained aware of it’s existence until a few days ago.

Given that, I thought I’d write up a quick post about the API to help people get started with using it. The API is generally well documented in the Flex 4 language reference, so I’ll just focus on a few key methods and gotchas.

General information
Most of the API exists as methods within the flash.sampler package. Simply import flash.sampler.* (or the individual methods), and call the methods directly. The sampler API is only available in a debug player.

It’s also worth knowing that along with the API, the Flash player allows you to specify your own preload SWF, which will be loaded prior to other content in debug players. You can specify this in the “mm.cfg” file – the details are documented in the Flex API docs for the sampler package. This mechanism is what FlashBuilder uses to funnel sample data to the profiler. This let’s you build your own tool chain that can be invoked on any site. There’s lots of room here for building tools that run in the browser, or that connect to a companion AIR app for inspecting or profiling content.

(as an aside – jpauclair has the best write ups of mm.cfg I’ve seen – definitely worth reading if you’re interested in profiling Flash content)

Introspection
The sampler API includes a few handy introspection methods:

getSize() // returns the size in memory of the specified object in bytes
getMemberNames() // returns an iterator object containing all of the private and public members (properties / methods) on the specified object
isGetterSetter() // checks whether a proper is defined with a getter/setter

Sampling
Sampling allows you to log all of the methods that were invoked over a period of time, and determine the amount of time each method took to execute. Here are the key methods:

startSampling(); // starts collecting sample data
stopSampling(); // ends a sampling session, and clears all sample data
pauseSampling(); // stops collecting sample data, without clearing existing data
getSamples(); // returns an iterator object (see below) containing all of the samples collected since the last clear
getSampleCount(); // returns the number of samples that will be returned by getSamples()
clearSamples(); // clears current samples data - you will generally want to call this after each getSamples() call to remove the samples you have already read.

For the most part this API is pretty straightforward. Where it gets weird is when you look at the object returned by getSamples(). Initially, I simply traced the object, and got an error saying “Property toString not found on (null) and there is no default value”.

This made me think that I was doing something wrong, and that getSamples was returning null. Then I realized that null always traces as “null”. It occurred to me that the error was actually showing that the type of the offending object was outputting null. Running describeType on the object returns its type as “*::*”. Very interesting! Apparently it is using some low-level iterator object that doesn’t even have an AS3 type (I’m trying to get more info on this).

If you ignore the weird return type, and simply iterate the object with a for..each loop (which appears to provide a determinate order for this object type, also interesting), you will get a list of Sample objects, which includes a time stamp in microseconds, and an array of StackFrame objects which contain the function’s full path/name and the SWF line number associated with it.

var o:* = getSamples();
for each (var s:Sample in o) {
trace(s.time,s.stack);
}
clearSamples();

Samples may also be instances of the NewObjectSample or DeleteObjectSample subclasses, which indicate the costs of instantiating or destroying an object respectively. The former has a type property that indicates the created object’s type. The latter has a size property that indicates the object’s size in memory at the time it was deleted. Both have an id property (presently undocumented on NewObjectSample) which lets you pair the create and destroy actions together.

With this information and some analysis, you can track time spent in any method (singularly or as an aggregate) and object creation.

I’ll be playing around with this API more over the next couple of weeks. I will likely talk about it a bit at FitC in Toronto and Flash and the City in NYC. I’m hoping to incorporate some of it’s capabilities into an updated version of PerformanceTest, and might build out some other tools around it. I’ll blog more as I learn more.