What would an open Flash look like?

The Flash platform today has several open source elements, but the part that remains closed is the player implementation. The player is the part of Flash that holds the features; it loads bitmaps and data, rasterizes vectors and text, composites elements on screen and dispatches timers and input events. Things such as the SWF (flash file format), RTMP, FLV/F4V, AMF, and MCD specs and (ActionScript) virtual machine are already open, but without an open-sourced player, these offerings fall flat.

The argument is that given enough open spec, a company or group could build their own player implementation. While this is true, it’s questionable that this logic would be workable in the real world. And while this thinking works for HTML, maintaining multiple variants of Flash while keeping compatibility at a maximum, all while following Adobes closed feature lead and developer tool-chain timelines would be excruciating.

Most people will agree that a multi implementation approach is an awful way to take Flash open; HTML continues to suffer because of this. If we have to have an open Flash, the only people who can make this happen are Adobe. A master implementation would allow for fast feature development and compatibility standard that Flash maintains today while allowing the community and vendors to port and contribute to the platform.

If Flash became open and was still a relevant technology, I can picture a day when Flash is no longer a browser plug-in, but something that is actually part of the HTML spec. I could easily see the canvas tag being used as a Flash context, much in the same way canvas is being used to display WebGL and SVG. You could even have plain-text ActionScript sitting in script tags. Now I’m not proposing that we expose the IP of the world, SWF files will always have to be supported. I’m just trying to paint a picture where Flash can be lightweight inside the browser, because if it’s not Flash it’ll be something else.

Adobe today is the bottleneck of Flash’s future. As computer platforms become more varied, needs become different and wider, Flash will fall behind. If Adobe is to hold onto Flash’s relevance, they need to let other people in.

Flash 11 should be a switch to JavaScript

Flash 11 should be a switch to JavaScript

Let’s press the reset button and drop ActionScript. It hold no relevance or advantage in todays world.

Over the past few months I’ve been working closely with JavaScript in different environments outside of the HTML DOM. Two of those being on the server side - Node.js and CouchDB. The other being an experimental front-end, RIA like platform. And what I’ve concluded over these past few months is that I really like using JavaScript - I’m genuinely surprised!

It was only a few years ago when I finally rid myself of ActionScript 2 and I was ecstatic about that. The ActionScript 3 way of doing things seemed to make a lot of sense to me and I’ve since written tens of thousands of lines of the strictly typed, compiler checked goddess. But is she a false idol.

At present, Adobe is recruiting people to the Flash platform via the new child, Flex. Up until people started throwing around the term RIA, the Flash user base was primarily made up of creatives & devigners who made some pretty amazing websites (lets forget about skip-intros for now) with what they had. Now the Flash base is increasing filling up with Java and C# types who expect a certain level of features, complexity and checks - Adobe continues to encourage it and the old base seems to be increasingly disillusioned.

The overwhelming message is that ActionScript 3 is necessary and better than all it’s predecessors. Now a big part of me believes this, in-fact I’d say it was pretty accurate. But I can’t help but feel that it’s hurting the essence of the platform and the web in general. It’s almost as if ActionScript (and some of it’s base) has a kind of inferiority complex and must be more like its mature peers in-order to be accepted. In-fact the power of ActionScript (and some of it’s base) was always in it’s simplicity - “less is more” so they say. And this is exactly what I’ve found out over the past few months with JavaScript.

The expressive power of JavaScript is wonderful. And so is the expressive power of AS3 once you take away the strict typing, package name-spacing, verbose eventing and the classical-OO pretense because you’re left with the stuff you care about, the stuff that actually gets things done. More importantly you’re left with something that looks just like JavaScript, no surprises there seen as they are ECMAScript cousins. Well maybe you could say AS3 is the bastard child now that ECMAScript 4 has been abandoned (- I think this post can stand without doing into depth on this subject).

But isn’t the big benefit of ActionScript 3 with strict typing the speed? - surly this is key to Flash success. This statement is utterly incorrect. First and foremost, the majority of Flash’s execution lies in the rendering of the stage. If AS3 is only doing [box.x+=1] then render is doing a hell of a lot more updating pixels on the screen. It is OK if your AS3 code is convoluted because the renderer will always be your bottleneck. The other mis-conception is that strict-typing improves execution speed. The evidence is probably running right in your face: most modern browser JavaScript engines are in-fact faster than Tamerin (the AS3 virtual machine). Additionally, Joa Ebert has really thrown egg on Adobes face this past year by showing the community just how unoptimized the AS3 compiler is.

So what was good about the introduction of ActionScript 3. Well, for me I think the bigger issue was at the API level. I think people enjoy AS3 over AS1 and AS2 because of a cleaner API into the platform and the finer-grain/cleaner control you get over the display-list. If you were to put put ActionScript 3 into the browser as a JavaScript replacement, you’d still end up with the problems of having to work with the awful HTML DOM. The language in Flash was never the issue.

Adobe Flash is increasingly being squeezed by it’s competitors who all want a bite from the RIA apple. Adobe can no longer afford to ship a niche language. Especially if they expect to draw in fresh blood into platform. A move to JavaScript (ECMAScript 5) would seem like the sensible option for the future of Flash. A grander alternative option would be a .NET type approach, enable many commonly used scripting languages (JS, Python, Ruby, Lua, etc) to becoming first class Flash languages, but maybe that’s too over the top. Simply moving to JavaScript will bring renewed expressiveness to the platform and once again it’ll be approachable by new talent, who at the end of the day, will make or break a platform.

I’ll end this with an example of expressiveness. Both these snippiest do the same thing: load an external JPEG and add it to the stage once loaded. I understand that you could encapsulate the JavaScript approach in AS3 - The point is that you shouldn’t have to.

EDIT: People have commented heavily about the following snippets. Please don’t take them as the overriding message of this article. The main message of this article is about AS3 being a niche language with too many constraints - JS could easily take it’s place.

EDIT2: I’ve started an open source project called $flash, hosted github, with the aim of creating a whole AS3 lib based on the JavaScript snip below.

// JavaScript

flash.load("lolcat.jpg", {
	success: function(bitmap) {
		gallery.addChild(bitmap);
	},
	error: function(msg) {
		trace("no lolcats found");
	}
});

// ActionScript 3

import flash.events.IOErrorEvent;
import flash.events.Event;
import flash.display.Loader;
import flash.net.URLRequest;

var url:URLRequest = new URLRequest("lolcat.jpg")
var loader:Loader = new Loader()
addListeners();
loader.load(url);

private function addListeners():void {
	loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeEvent)
	loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
}
private function removeListeners():void {
	loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, completeEvent)
	loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
}

private function completeEvent(event:Event):void {
	removeListeners();
	gallery.addChild(loader);
}
private function ioErrorHandler(event:IOErrorEvent):void {
	removeListeners();
	trace("no lolcats found");
}

Win an Adobe MAX ‘09 Pass

I’ve been given the opportunity to gift a full Adobe MAX 2009 (L.A) conference pass.

I’ve got to give it away by the end of Friday evening (PDT). So, I’m going to use a simple “random name out of a hat” technique with the help of twitter.

How to enter:

1) Be a member of twitter
2) Be following me on twitter: abustin
3) Tweet this exact message: I want to win your #adobemax pass @abustin -http://tinyurl.com/winmaxpass

I’ll announce the winner live on twitter tomorrow (Friday).

24 Predictions for Adobe MAX 2009

  • Flash Player for iPhone (announcement/demo)
    Prediction Rating: B+
  • Mobile Flash Player, Mobile AIR & SDK tools (labs release for Android, Symbian and Win Mobile)
    Prediction Rating: A+
  • Adobe AIR 2.0
    Prediction Rating: A+
  • Flex Mobile Components
    Prediction Rating: B
  • AS3 multi-touch API
    Prediction Rating: A+
  • Simple AS3 Callbacks API. (The stuff some people miss from AS2)
    Prediction Rating: D
  • New supported Flash video codecs (eg. Theora)
    Prediction Rating: D
  • AS3 Threading API
    Prediction Rating: C
  • Flash Catalyst is being rewritten to be useful
    Prediction Rating: F
  • Flash executes Pixel Bender shaders on the GPU
    Prediction Rating: B+
  • All the old built-in bitmap filters have been upgraded to use Pixel Bender
    Prediction Rating: C
  • Flash Player GPU accelerated rendering
    Prediction Rating: B+
  • Flash Player GPU accelerated video decoding
    Prediction Rating: A
  • AS3 OpenGL ES bindings that draw to pixel buffers (bitmaps)
    Prediction Rating: B
  • Additional AS3 P2P APIs. Maybe to aid in creating MMO games.
    Prediction Rating: C
  • ActionScript 3.5 (generics, method overloading, Lambda expressions, Generators, Object initializers, operator overloading, etc)
    Prediction Rating: D
  • The introduction of coding Flash in other/new languages. This might also include new micro-formats for the timeline.
    Prediction Rating: F
  • Flash Professional will be renamed to Flash Animator. The Flash platform tools will be sold in a package named Flash ABC (Animator-Builder-Catalyst).
    Prediction Rating: D
  • Flash Player in the Cloud; Thin HTML5 client.
    Prediction Rating: F
  • AIR versions of Acrobat.com apps such as Buzzword
    Prediction Rating: C
  • Brand New HTML5 IDE for creating Flash like experiences.
    Prediction Rating: C
  • Stereoscopic 3D DisplayList projection filter in Flash
    Prediction Rating: F
  • Ability to create and distribute new Tools for Flash Professional (why did we have to wait for IK and the deco tools)
    Prediction Rating: D
  • The Flash community will lose Phillip Kerman to Hollywood
    Prediction Rating: bingo!

What are your wild predictions?

HTML5 in IE6 today, thanks to Google Chrome Frame

Today Google announced Chrome Frame; their strategy for speeding up the HTML5 roadmap. Google Chrome Frame is a browser plug-in, such as Adobe Flash or MS Silverlight.

The Chrome Frame plug-in is an extraction of the rendering part of Google’s Chrome browser that will override the default HTML rendering of IE. In other words, the world will no longer need to wait for Microsoft to implement the HTML5 standard, meaning that HTML5 might become mainstream a lot faster than people have predicated.

In order to take advantage of plug-in, all the developer needs to do is add a single Meta tag to their existing HTML code. Watch the video to find out more …

Read More on Google Chrome Blog

WebGL: OpenGL in your browser without plugins

WebGL is basically an initiative to bring 3D graphics into web browsers natively, without having to download any plugins. This is achieved by adding a few things to HTML5, namely, defining a JavaScript binding to OpenGL ES 2.0 and letting you draw things into a 3D context of the canvas element.

After reading this blog posting over the weekend I knew I had to have a go myself.

Below is a recording of my first demo, I used an external camera because Quicktime X screen recording just didn’t cut it. This demo is running at a constant 100fps and I’m sure it could go higher if the ticks were increased.

This technology has the potential to change online gaming as we know and will certainly be a game changer for rich interactive experiences.

AVM1EventProxy: AS2 Style Events for AS3

Rationale

The biggest complaint you hear about ActionScript 3.0 against its predecessor is that it’s too verbose. And one of the most verbose API’s in Flash today is the Eventing API.

Eventing in a single-threaded/asynchronous environment, such as Flash, is essential. And so, creating a powerful solution is of the up most importance. Adobe certainly delivered a powerful and robust system, but in this developers opinion, they got a little carried away somewhere along the line.

It’s very easy to demonstrate the verboseness of AS3 eventing with a little code snippet. Below I shall write two implementations of the same functionally, one in the older AS2 and the other in newer AS3. The code will listen for a button being clicked and then before the listener.

AS2 Version

myBtn.onRelease = function() {
	trace("You clicked me! Now go away");
	this.onRelease = null;
}

AS3 Version

myBtn.addEventListener(MouseEvent.CLICK, btnClickHandler);

function btnClickHandler(e:MouseEvent):void {
	trace("You clicked me! Now go away");
	myBtn.removeEventListener(MouseEvent.CLICK, btnClickHandler);
}

I really am a fan of the Events API in AS3, but when it comes to simple button interactions (like the above example) I think it’s clear that something needs to be fixed.


AVM1EventProxy

In response to this need I have written a few ActionScript 3.0 files that can be used to simulate the older AS2 style will still utilizing the ActionScript 3.0 events API; the days of onEnterFrame = function() {} are back!

Usage

I have setup the files in a manner that they can be incorporated into a project in four different ways.

  1. As Base Sprite/MovieClip Classes: Extends all your display objects from one of these two classes to inherit the AS2 event functionality.

    Example:

    import bustin.display.AVM1EventSprite
    
    class MyApp extends AVM1EventSprite {
    
    	function MyApp() {
    		onEnterFrame = function() { trace("the bird is the word!")}
    	}
    
    }


  2. Class mix-in: You already use a base Sprite/MovieClip class for all your projects? Well, that’s not a problem - simply use an include statement in your base classes to inherit all the AS2 event functionality.

    Example:

    class BobsAwesomeBaseSprite extends Sprite {
    
    	include "bustin/display/_AVM1EventProxy.as";
    
    	public function whoIsAwesome():String {
    		return "bob";
    	}
    
    }
    
    class MyApp extends BobsAwesomeBaseSprite {
    
    	function MyApp() {
    		onEnterFrame = function() { trace("the bird is the word!")}
    	}
    
    }


  3. Timeline mix-in: Not a classes type of person; working in Flash Pro? - that’s cool too. Use an include statement in your frame script and code like it’s 2004 :).

    Example:

    include "bustin/display/TimelineEventHelper.as";
    
    onEnterFrame = function() { trace("the bird is the word")}
    
    stop();


  4. Proxy Object: Use a helper object to work with the AS2 style events.

    Example:

    import bustin.display.AVM1EventProxy
    
    var e:AVM1EventProxy = new AVM1EventProxy(myBtn);
    e.onRelease = function() {
    	trace("hey, what's the word?")
    }




Callback Syntax

Currently, the implementation only anonymous functions. For example, in AS2 you were simply able to write this on the timeline:

function onEnterFrame() {
	trace("fooo")
}

AVM1EventProxy only allows for this style:

onEnterFrame = function() {
	trace("fooo")
}



Event Handler Arguments

You’ll notice that unlike ActionScript 3.0 event handlers, callbacks in AVM1EventProxy do not require any function arguments in most cases.

function eventHandler(e:Event) {} // an example of an AS3 event argument
onEnterFrame = function() {} // AVM1EventProxy version

Keyboard interaction is one case where you might like to know more about the interaction. So without an Event object being passed how can we find out which key was pressed? Well, AVM1EventProxy provides snapshots of the last event that you’re able to access via the callback like so ..

onKeyUp = function() {
	trace(this.Key.charCode,"was released");
}

Notice that you can access the last Key event instance via the Key property in much the same was as you did in AS2.

Additionally, you can access mouse events via the MouseEvt property and focus events via the Focus property.


Keyboard Events

Keyboard events in ActionScript are most useful when they are being dispatched from the stage. For this reason AVM1EventProxy uses the stage for all keyboard events. You can seamlessly add keyboard callbacks with AVM1EventProxy without the display object being on the display list but they won’t start to fire until the display object has been added to the display list.



Currently Supported Callbacks

onMouseUp
onMouseDown
onMouseMove
onPress
onRelease
onClick
onEnterFrame
onKeyDown
onKeyUp
onRollOut
onRollOver
onKillFocus
onSetFocus

Disclaimer

BETA: Might contain bugs. Event behaviors might change/improve in the future.

Download

AVM1EventProxy.zip

Notes

Flash Professional will give you lots of warnings such as the one below … Ignore them.

Warning: 1090: Migration issue: The onMouseUp event handler is not triggered automatically by Flash Player at run time in ActionScript 3.0. You must first register this handler for the event using addEventListener ( ‘mouseUp’, callback_handler).

HTML5: 60 Spinning 3D Cubes in Space

After my co-worker, Charles Ying, posted his 3D CSS Snow Stack demo online a couple of weeks ago, I felt compelled to give 3D CSS in HTML5 a try myself.

Now, I haven’t created anything as complete at Charles’s demo. Instead I took the approach of seeing how much “stuff” I could get moving at once. I started with one cube spinning on its own, and then I just kept adding. I rested on 60, it seemed like a good amount of cubes; it will result in 360 images from Flickr being 3D transformed at once.

To run the demo, you will need to be using Mac OS X Leopard and running the latest WebKit nightly.

DEMO: Flick Cubes

Screenshot:

flickcubesscreenshot.jpg

Announcing: BustinLib; Helpful ActionScript

As we all do over the holidays; we tinker about. I didn’t have buckets of tinker time, but in the time I had, I either played PS3 or got down and dirty with some ActionScript. What I’m announcing today is the result of the latter.

Continue…

p.s. Happy 2009!

AS4 Wish: Shorthand Eventing with Flows

One thing I love and hate about ActionScript 3 is the eventing model. I love the departure from AS2 type callbacks. And I love the way it allows me to have loosely coupled classes. Anyway, to rephrase and refrain from stating the obvious, I think eventing is awesome.

But after the AS3 honeymoon … … I resent the number of times a day I find myself typing out object.addEventListener(…,…) and then object.removeEventListener(…,…). I resent it even more when I know that the event shall only happen once, normally for some kind of COMPLETE event; thus making the first line of my handler always be IEventDispatcher(e.target).removeEventListener(e.type,…). It’s just too verbose, especially when it’s such a core feature of ActionScript.

Now, I’m not trying to crawl onto the recent AS3 is harder and takes longer bandwagon here. I’m ecstatic that AS2 is not longer a daily thing for me; I wouldn’t even go back to it for a pay-rise. But, I feel something could be added to AS3 to make eventing less verbose and less prone to things such as memory leaks.

What makes eventing so verbose? Well, for every event we want to subscribe to, we do:

1) Add Listener
object.addEventListener(”eventtype”, eventHandler);

2) Create a function to handle that event
private function eventHandler(e:Event):void {
trace(”hello world”)
}

3) Remove Listener
object.removeEventListener(”eventtype”, eventHandler);

The creation of a handler function per event group is something that especially rubs me the wrong way, but when working in an asynchronous language, what else can you do? I propose a new concept called a “Flow”. A Flow mimics the blocking nature of synchronous languages while keeping inline with the asynchronous environment of ActionScript.

To outline my proposal, I’m only going to give a commented example, but I hope from it you’ll be able to take away the key concepts. And I stress concepts! As this probably won’t be the best syntactic solution.

class FlickrPhotoGizmo extends EventDispatcher {

	// Note that this is a "flow" and not a function.
	// Flows seem to be able to "block" until a matching event type is dispatched
	// Flows work with existing AS3 code .. ie. imageLoader.addEventListener(Event.COMPLETE, ...)

	// A flow will always dispatch a "FlowEvent" of constant type on return.
	// Flows are a one time deal; no need to keep listeners around once completed.
	// Null returns shall be detailed in the "FlowEvent" for later inspection.
	// The "->" notation is our "syntax sugar" 

	public flow loadAndFilterImage(searchTerm:String):BitmapData {

		var imageLoader:FlickrLoader = new FlickrLoader();
		var imageFilter:ImageFilter = new ImageFilter()
		var resultBitmap:BitmapData;

		imageLoader.getMostPopular(searchTerm) -> {
			Event.COMPLETE  -> resultBitmap = imageLoader.bitmapData;
			Event.NO_MATCH  -> return null;
		}

		imageFilter.filter(resultBitmap) -> {
			Event.COMPLETE -> {
				resultBitmap = imageFilter.filteredBitmapData;
				imageFilter.fooClean()
			}
			Event.ERROR -> return null;
		}

		imageFilter.filter2(resultBitmap)
			-> Event.COMPLETE
				-> resultBitmap = imageFilter.filteredBitmapData;

		return resultBitmap;
	}

}

// wrapper app

funtion init():void {

	var gizmo:FlickrPhotoGizmo = new FlickrPhotoGizmo();

	// let's load an image with happy people, then filter it...
	// ... then give the result to the "imageReady" function
	// remember: this is a one time "FlowEvent" event that results from a "flow"

	gizmo.loadAndFilterImage("happy people") -> imageReady;

	addPermEventHandlers();

}

function imageReady(e:FlowEvent):void {

	// no need to call removeEventListener as this is a one time event

	var image:BitmapData = e.yield;

	if (image) {
		addChild(new Bitmap(image))
	} else {
		var errorEvent:Event =  e.nullEvent
		switch (errorEvent.type) {
			case Event.NO_MATCH: trace("no happy people found :(")
		}
	}

	removePermEventHandlers();

}

// maybe we want this new syntax for permanent listeners too .. note: "o"
// (i know "o" might be a bad pick .. but just go with it)

function addPermEventHandlers {
	o-> MouseEvent.UP -> mouseUpHandler
	stage o-> KeyboardEvent.UP -> keyPressHandler
}

// and because we have permeant listeners, we need to be able to remove them .. note: "<"

function removePermEventHandlers {
	o<- MouseEvent.UP -> mouseUpHandler
	stage o<- KeyboardEvent.UP -> keyPressHandler
}

function mouseUpHandler(e:MouseEvent):void {
	trace("we're still loading that image for you, just wait .. blame Flickr")
	if (false && "anotherExample") {
		// this is short hand for .. this o<- MouseEvent.UP -> mouseUpHandler
		// we're able to do it because we're aware of the context
		o<-e
	}
}

function keyPressHandler(e:KeyboardEvent):void {

}

Next Page »