Archive for the ‘Actionscript’ Category

AS3Wrapper: Pulling Flash objects into Javascript

Monday, May 26th, 2008

I’m very excited about a new tool that I’ve written this weekend called AS3Wrapper. It’s a Javascript library, compatible with IE and Firefox, that can pull the contents of the Flash virtual machine into Javascript.

The result is that the entire Flash API becomes accessible from regular script tags. Owing to the simlarities between the two languages, coding Flash in Javascript is actually incredibly natural, and what’s more, it also seems to have pretty nice performance!

A Simple Example

Here’s a simple example at work. I suggest you take a look at the source code to see how the Javascript is constructed.

You first have to create yourself a Flash player object:

var player = new
  AS3Wrapper.Player("content",100,100,false);

This replaces the div in your html page with id ‘content’ to be a 100×100 Flash player instance. The false parameter prevents transparency. The player might take a few moments to load, so assign a callback to setup your Flash scene:

player.onload = function(){
  // Do the meat of your Flash work here
}

Once the player has loaded, it’s javascript object will contain the complete class hierarchy of the internal Flash API. For example, player.flash.display.Sprite will be the constructor for the flash class flash.display.Sprite inside player ‘player’. Here’s a screenshot from Firebug:

To write Javascript for a particular player, use with. With blocks are also the equivalent of the ActionScript import statements. Apart from this, there is pretty much a direct correspondance between the two languages. For example:

with(playerInstance)
with(flash.display)
with(flash.net){
	var image = new Loader();
	image.load(new URLRequest(url));
	addChild(image);
}

is the Javascript equivalent of

import flash.display.*;
import flash.net.*;
... {
	var image:Loader = new Loader();
	image.load(new URLRequest(url));
	addChild(image);
}

Pretty similar, huh?

Some things to note: Javascript doesn’t have type annotations (obviously), and because IE doesn’t support getters and setters, I’ve created methods instead - getWidth() for getting a Flash ‘width’ property and setWidth(v) for setting it.

What next?

One impact of this might be that it opens up Flash programming to a wider audience. Even though Flash compilers are free, having the code right there in HTML eliminates the extra step of installing extra tools. What’s more, any code generated in this way is naturally open.

By using the Papervision3d module (see this example), you can now program quick-rendered 3d in Javascript. You can also use a Javascript console for interactive Flash programming and debugging. Maybe one day Flash grease-monkey scripts will exist? Who knows.

There are, of course, also many disadvantages: losing a richer programming environment, type checking and performance. But still, hopefully you’ll find playing with it a little bit of fun!

Download

You can download AS3Wrapper here.

Emulating Nested Classes in ActionScript

Tuesday, March 4th, 2008

Although nested classes are not supported by ActionScript 3.0, I’m going to describe a rather deviant means to achieve pretty much the same effect. The syntax doesn’t work out too great, but hopefully you might still get some use out of it!

What is a nested class?

A nested (or inner) class is a class inside a class, which has access to the members of its parent, even if they are declared private. In Java, they are declared by literally nesting the class definitions:

class OuterClass {
    ...
    class NestedClass {
        ...
    }
}

Nested classes are useful because they allow a way of logically grouping classes that are only used in one place. For instance, if only a class is used by only a single other, then the class can be declared as a nested (helper) class, and furthermore, declared private.

Another use is the case where only one class needs to access the member variables of another. By nesting the class, the member variables can be kept private, increasing encapsulation.

Closures as Objects

Nested classes cannot be declared directly in ActionScript. However, as Ely Greenfield pointed out to me earlier, it turns out that closures for function calls in ActionScript are quite a lot like objects:

"...parameters, local variables, even member
references of ‘this’ are all accessible in the
closure, whenever it’s called, however often
it’s called, for as long as the closure exists."

As a result, it must be that the local variables of function definitions are quite a lot like the member variables of classes.

What’s the Hack?

So, we can define a nested class by defining a function (it’s constructor) with local variables and functions corresponding to the members of the class. By default, each of these is private, but we can selectively expose them by returning an appropriate object.

An Example

First the class as a top-level class:

class A {
   private var x;

   public function A(a){x = a;}

   public function inc(){x++;print();}
   private function print(){trace(x);}
}

var c = new A(4);

and now the class as a nested class:

public function new_A(a){  // constructor
  var x;                     // members

  x = a;

  function inc(){x++;print();}
  function print(){trace(x);}

  // public members
  return {inc:inc};
}

var c = new_A(4);

As you can see, the syntax actually ends up looking quite similar in both cases, the same encapsulation rules exist for both and the usage rules are the same. What’s more, the methods in the ‘nested class’ can still access the member variables of its enclosing class, just like in Java.

Of course, this isnt going to work so well if you need to use more advanced techniques (like inheritance, type-checking…etc!). You might still find it useful.

A Hole in ActionScript, and a Way Around It

Friday, February 29th, 2008

In my previous post, I put forward several reasons why functional programmers might feel at home with Adobe’s rather terrific ActionScript 3.0 programming language that’s the basis of Flash, Flex and AIR. Today I’m going to describe one reason why they just might not want to. Some people will call this behaviour a stylistic feature. Others will call it a semantic irregularity. Personally, I think it’s a bug, and suspect that those coming from functional programming will feel the same.

What!? Closures take references?

The problem concerns ActionScript’s behaviour when local variables are used in function definitions. Let’s take a look at an example:

// Create an empty array to hold our functions
var functions:Array = [];

// Add functions to array that print out x
for(var x:Number = 0;x<10;x++)
  functions.push( function(){ trace(x); } )

// Execute functions
for each(var f:Function in functions)
  f();

First we create an empty array (or list). Then we add 10 functions that print out x for a range from 0 to 9. Finally, we iterate through the array and execute each function. The result?

10 10 10 10 10 10 10 10 10 10

So what went wrong? Well. I feel that many programmers would expect the functions to display the value that x held during the definition of the function. However, in fact what was used was the value of x during the execution of the function.

Style?…or Bug?

On the face of it, whether x should be determined at function definition or function execution sounds like it might be a language design choice. Maybe this is just the way they chose it to be?

But dig a little deeper and you realise that things seem a bit wrong. For starters, in our example, is the variable x even defined at the time of function execution? Is it right that a fuction’s local variables should still be accessible after the function has completed execution?

Ways Around It

For anonymous classes in Java, the same problem is dealt with by enforcing variables to be declared final (unassignable) before they can be used within a delayed piece of code. I think it’s a shame that the ActionScript compiler doesn’t require a similar convention.

Still, I have found a stylistic way to hack around the problem, and I suggest that all ActionScript users do the same. The method involves allocating a fresh persistent reference on the stack for any local variables that you would like to use inside a function definition. You can do this by wrapping your function in yet another anonymous function. Here’s the modification in place for the code above:

// Add functions to array that print out x
for(var x:Number = 0;x<10;x++)
    functions.push( (function(x){
      return function(){ trace(x); }
     })(x) )

And now, success!

0 1 2 3 4 5 6 7 8 9

It works because the outer x is evaluated at the same time as the function definition. As a rather interesting aside, it demonstrates that

E    is not   (function(x){return E})(x)

Surely not the best of features? Or am I molded by the over-use of functional programming?

The Pass-by-Reference Hack

Things get much stranger than that. It turns out that not only can you read variables that have seemingly ceased to exist, but you can also write to them. This can lead to some usages that seem really odd coming from a Java background. For example, here’s an example I created of emulated integer pass-by-reference call:

// Receives reference to x, and doubles x
function twice(xRef){
  xRef(xRef()*2);
}

function test() {
  var x = 1;

  // Create reference to x
  var xRef = function(value=null){
    if(value!=null)
      x=value;
    return x;
  };

  // Call-by-reference
  twice(xRef);
  twice(xRef);

  trace(x);
  // result is 4
}

Sweet. Did I really call ActionScript terrific at the start of the article? Actually, I still think it rather kicks arse, just needs a little tweak. Afterall, I just made this.

ActionScript for Functional Programmers

Wednesday, February 27th, 2008

or ‘Why Haskell Users Should Consider….ActionScript !?’

If you’re a Haskell programmer, you’re probably a little worried about the title of this article. “ActionScript?,” you say, puzzled, “Isn’t that that messy scripting language that glues together Flash animations?” Well yes. And no. As it turns out, ActionScript originated as a bit of an ugly duckling, and as, rather aptly, a way to script actions. But now it’s blossomed, it really is a rather lovely little swan, and it’s especially handy if you’re a functional programmer.

Functions as first class values

Actionscript has them. And uses them. Extensively. Which means you’ll feel very at home writing equivalent of the lambda expression \x.E, which is

function(x){ return E; }

Admittedly not quite as brief as in Haskell, but also, debatably, not quite as cryptic. There’s no form of type inference, so you’ll have to add types manually:

function(x:Number):Number{ return x+1; }

Of course, functional application is also there, and

(function(x){ return x; }) (1)

evaluates to 1. The two basic ingredients for some pretty nifty functional programming ownage.

Arrays (Lists)

What are termed Array in ActionScript programming are, to most extents and purposes, equivalent to lists in functional programming. Literals like [] and [0,2,3] are accepted, and map and filter are native higher-order functions with implementations built into the Flash Player.

Language Warming

To get your ActionScript environment to an even nicer plane of purity, here are some extra nice bits that I normally define in a utility class before starting on a project. These are roughly based on the Haskell prelude.

// identity
function id(x:*):* {return x;}

// curry
function curry(f:Function):Function{
  return function(x):Function{
    return function(y) {
      return f(x,y);
    }
  }
}

// uncurry
function uncurry(f:Function):Function {
  return function(x,y){return f(x)(y);}
}

// constant function
function const(x){ return function(y){return x;} };

// procedural style foldl - uncurried
function foldl(f:Function, e:*, xs:Array):*{
  for each(var x in xs)
    e = f(e,x);
  return e;
}

// functional composition - uncurried
function o(f1:Function,f2:Function):Function {
  return function(a:*):*{
    return f1(f2(a));
  }
}

// summation - uncurried
function sum(x:Number,y:Number):Number { return x+y; }

Now you can write code that looks and feels quite a bit like Haskell. For example, you can now sum the array xs simply with:

foldl(sum,0,xs)

Usage in Practice

Of course, ActionScript isn’t really a functional language, being much more heavily based on OOP principles (a mix a bit like Scala). This does cause some pain. For example, notice that I tend to use uncurried definitions quite a lot of the time because there are no short hands for defining higher-order functions. Alas, there’s also no pattern matching and all functions get lumped under the Function type.

However, on the flip slide, you can use it to develop scalable applications with amazing potential. The Flash Player is a pretty much ubiquitous VM, and now that AIR (being slow, I only just noticed that it’s RIA backwards) is out, you can deploy to the desktop if you like too. Everything is JIT compiled, and the VM is opening up and rapidly converging with the HTML/javascript world. XML types are native, and the e4x access syntax is an incredibly nice way to access tree data. The unusual Flash event model also allows for Tcl/Tk-style variable binding, so that building GUIs in Flex/MXML is a breeze.

Some of the other opportunities are amazing. For instance, I’ve recently build The Effect Generator - an online app for creating Flash movies from templates. Part of the code dynamically loads and executes foreign bytecode from external web sources, but Adobe’s great security features allow’s you to keep things under control. Using the heirarchical security model, you can load remote classes and execute methods without the loaded code having access to your own classes. Scope for runtime disaster: huge. Scope for fun: priceless.

But…Scripting?

Nevertheless, something tells me ActionScript hasn’t quite been getting the attention it deserves, and that maybe it’s something related to how some folk react to the the name. Script…..scripting….informal….script kiddies…..kiddies? If you’re thinking like this, be aware that ActionScript is a seriously powerful programming language, and your reaction may well just be a defense mechanism to avoid picking up something new, fresh, and amazing. When was the last time you saw something like a stunning online photo editor written in Haskell?