Da Fish in Sea

These are the voyages of Captain Observant

STOP Programming in Javascript

| Comments

You may be wondering about the title of this post… well, it isn’t the advice my grandfather gave me but I never heeded :) STOP is a reference to the concept of State and Transition Oriented Programming. I found out about this concept from Troy Gardner at the 360Flex conference a couple of years ago. The video of this presentation is well worth watching.

To summarize, in case you’re not done watching it yet.. States are a very important aspect of programming interactive systems, but they are often neglected and as a result can lead to nasty bugs. By dealing with states carefully and consciously it becomes a lot easier to develop more complex systems. Troy developed a framework in ActionScript to provide readymade support for state management and transitions.

It would be possible to port the framework to JavaScript, but the basic idea is so simple that it does not require a framework to implement and benefit from using it. This post is my attempt to describe how to do that.

Usually, from what I’ve seen, states are defined as constants, or enums or something like that, and assigned to some global variable…

1
2
3
4
if (isHoliday)
    STATE = "happy";
else
    STATE = "sad";

Then later on, there will be forks in the code to do different things depending on the state:

1
2
3
4
if (STATE === "happy")
    smile();
else if (STATE === "sad")
    frown();

While this works fine most of the time, you can quickly end up with a mess of duplciated conditional logic all over the place, as every time you need to do something, you have to check which State is active to decide if and how you’re going to do it.

It’s worth considering the difference between lowercase ‘state’ and uppercase State. The former is simply the values of variables that your application contains. This is vague and generalized and not what I’m referring to here. The uppercase State refers to a global condition which usually corresponds to a phase of activity of the application. For example a video player component might be ‘loading’ or ‘playing’ or ‘paused’. The State of the application fundamentally changes its behaviour, and how it will respond to events. Having said this, I’m not going to consistently capitalize ‘State’, but I’m always referring to the this more specific meaning of the word.

Events are things that happen in your application, whether it is user input or a result of processing or time passing. A collision between two objects is an example of a typical event in a game for example. Depending on which State the application is in, events will be handled differently. When events occur, we can send ‘messages’ or ‘signals’ to the currently active State, which can decide how to respond.

The idea that I’ve borrowed/stolen from Troy Gardner is to implement States as functions. Since they are essentially global constants, they are capitalized. This also indicates their special significance, and differentiates them from reqular functions. Here is how the two states of a light switch might be implemented (if we visualize the switch as having two buttons, ‘off’ and ‘on’):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var state = OFF;

offBtn.onClick = function () {
    state("turn_off");
}

onBtn.onClick = function () {
    state("turn_on");
}

function OFF(msg) {
    if(msg === "turn_on") {
        turnLightOn();
        state = ON;
    }
}

function ON(msg) {
    if(msg === "turn_off") {
        turnLightOff();
        state = OFF;
    }
}

Notice how the event handlers did not have to know about the different States of the application, but simply sent a message to the currently active State function, which is dynamically assigned when the state is set. Assigning the State function to the ‘state’ variable effectively sets the State, and alters the behaviour of the system… Note how the OFF State does not respond to the ‘turn_off’ message, and the ON State does not respond to the ‘turn_on’ message. There is no switching on the state value - rather the State function will handle the messages it is sent, ignoring any it is not interested in.

Transitions

It is often necessary to perform actions when changing from one State to another. But it can be easily done by using ‘enter’ and ‘exit’ messages which are passed to every State when they are made active or deactivated. The way to make this happen is to use a ‘changeState()’ function to change from one state to another:

1
2
3
4
5
function changeState(newState) {
    this.state('exit');
    this.state = newState;
    this.state('enter');
}

Then you can manage your transitions by listening for these messages in your State functions:

1
2
3
4
5
6
7
8
9
10
function DAY(msg) {
    if (msg === "enter") {
        wakeUp();
    } else if(msg = "exit") {
        turnLightsOn();
    }
}

changeState(DAY);
changeState(NIGHT);//lights get turned on

Hierarchical States

If you want to nest States, eg. LUNCH within DAY, this can be done by passing on any unknown messages to the super-state:

1
2
3
4
5
6
7
function LUNCH (msg) {
    if(msg === "eat") {
        eatLunch();
    } else {
        DAY(msg);//eg "check_email" msg would be handled by DAY
    }
}

If you have events which need to be handled at any time, they can be put in a BASE state, and other states can pass on messages to it. For example, if the user resizes the browser window, there could be a ‘resize’ message which would be handled by the BASE State:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function BASE (msg) {
    if (msg === "resize") {
        resizeGame();
    }
}

function PLAYING (msg) {

    if (msg === "scored") {
        increaseScore();
    }

    //always pass on messages to BASE
    BASE(msg);//resize will be handled

}

As you can see by comparing these two examples, you have the option of passing all messages to the super-state, or only passing on unknown messages.

This method of handling events by sending messages to State functions is very flexible and dynamic, and makes adding new States easy. It adds some abstraction between events and the response to them, which reduces coupling within your application. It also reduces duplication and conditional branching, and I think it also makes the code easier to read, as behaviours are grouped by State and message, which should be self-descriptive.

Finally, STOP programming is not opposed in any way to OOP, but is orthogonal to it. I have found it to be particularly useful in developing games, which tend to have many different states with different behaviours.

For a more complex example of this pattern in action, see the Asteroids game.

A Is for Asteroids

| Comments

A while back I decided to have a go at making a Javascript + Canvas version of Asteroids. I was able to get a basic version of the game working in a weekend, but I wasn’t happy about the code being in one huge file, so I set about refactoring it using ExtJS 4 for OO support (but not the whole library). This turned out to be quite addictive and after a while I had a small library of code on my hands. The initial title of the game was ‘CanvAsteroids’, but as I shifted to working on the supporting library I started to think of it as ‘CanvaSteroids’ : Canvas on Steroids. And so I have named the library this awkward name and renamed the game itself to just be Asteroids. The plan is to work my way through the alphabet, making a game for each letter. Next is Breakout. It’s good to have goals ;)

I want to write some more posts about some of the techniques I used to get the game working, especially the collision detection. I found a way to do this using the Canvas ‘isPointInPath’ method, which seems to perform quite well. The game uses keyboard for controls (left-right arrows for turning, spacebar to fire) and I also added some mouse/touch control inspired by Seb Deslisle’s JSTouchController. I don’t think the game is really well suited to touch, but at least I learned how to handle the touch events. If anyone has an iPad I’d be interested to know how it works.. unfortunately I heard the performance of Canvas is not great on iOS. However I’m really not into targeting one platform, and I’d like the games to be playable on any desktop or mobile device which has a decent browser (ie supports Canvas). For the IE < 9 users, I added Chrome Frame. For sound I used SoundManager2. The actual sounds were recorded off my Atari 2600 during gameplay, and edited in Audacity.

Anyways, enough nerdy banter.. here’s the game (warning LOUD sound effects!).

Play Asteroids

I used GitHub’s nifty new pages feature (plus a domain) to host a site here:

canvasteroids.com

And for all your source-y needs, the Github repo

Modular Javascript Development With RequireJS

| Comments

RequireJS is a micro-library focused on defining and loading Javascript ‘modules’ so that they can easily be loaded in your own or other peoples projects. Since Javascript has no compiler, the <script> tag has traditionally been the equivalent of the ‘import’ statement in compiled languages. But it has been hard to combine multiple JS libraries which may end up clobbering each others prototypes, leading to mysterious bugs. The module pattern is a well accepted pattern for preventing exposing global variables, although you still have a global variable for the module itself. With RequireJS you can reduce the number of globals even further, since modules are not assigned to global variables but are require() ‘d inside other modules.

Another benefit is performance.. loading scripts should be asynchonous for best usage of the network. Traditional <script> tags are synchronous and blocking, even if the code is not immediately required. Other approaches to loading code use XHR & eval() which makes debugging hard, and restrict to same origin (though there are workarounds). So RequireJS creates script tags dynamically, and appends them to the head of the document.

OK, how do you use it ? If you simply want to include an external script (whatever it may be), you can do this:

1
2
3
require(["some/script.js"], function () {
    //do stuff once it is loaded
});

So what is going one here is that the first argument to ‘require()’ is an array of dependencies, which are paths to Javascript files. The callback function is executed once the file has been loaded. Pretty simple. However the real power of RequireJS comes about when you also define your modules with a special define() function, which in turn declare their dependencies.. and so on, and so on, recursively. Usually, the Module Pattern is implemented with a closure function:

1
2
3
4
5
6
7
8
MyModule = (function () {
    function boo() {
        alert("boo!");
    }
    return {
        frighten: boo
    }
})();

With RequireJS you use the define() function instead of the anonymous closure:

1
2
3
4
5
6
7
8
9
10
define(['dependency/first', 'deependency/second'] , function (d1, d2) {
    //when this gets called, the dependencies are loaded and available as d1, d2
    function boo() {
        alert("boo!");
    }
    //you must return the module explicitly:
    return {
        frighten: boo
    }
});

If this was in a file called /scripts/scary.js, you could obtain an instance of the module as follows (in /index.html):

1
  <script type="text/javascript"><!--mce:0--></script>

Notice that there is no .js on the end of the filename. RequireJS will see that and look for a define() function in the file to get the module with. Note that if you omit the .js on the path, the module must be defined using the define(). Another option, which avoids using any inline script in your HTML, is to use a <script> tag with require.js as the ‘src’, and give a data-main attribute to indicate the entry point of your app.

1
 <script src="scripts/require.js"><!--mce:1--></script>

This would work if we had a script called ‘main.js’ in the scripts folder with something like this in it:

1
2
3
define(['scary'], function (scary)) {
    scary.boo();
};

Notice how the dependency is passed as an argument to the callback function. If there are more than one dependency, they will be passed as additional arguments, in the same order as the dependencies.

If you need to interact with the DOM, you should be aware that your dependencies may be loaded before the document itself is loaded, so you can use the require.ready() function which fires when the document is ready AND all dependencies have loaded…

1
2
3
4
5
6
7
define(['scary'], function (scary)) {
    require.ready(function () {
        //start app
        scary.boo();
        //do DOM stuff...
    });
};

Note that the module name is relative to the directory containing the ‘data-main’ module. Also note, require.ready() uses window.onload for browsers (mostly IE) which do not support the DOMContentLoaded event. This may be slow if you have a lot of stuff on your page.

An example of more advanced usage is that an object literal can be passed in as the first argument to the require() function, to add some additional customization, eg, setting a baseURL, or some paths which will be expanded in the names of the dependencies.

Advanced Usage: CommonJS Compatibility

CommonJS is a JS package standard, used by, eg. NPM (Node Package Manager – see previous post). Therefore it is desirable that RequireJS would grok CommonJS packages. However, you need to specify some additional configuration in you package.json for this to work, eg.

1
2
lib: 'some/dir', //the dir containing the modules, (default = lib)
main: 'script/app' //the name of the module in the lib dir which will be used when someone require() 's the packageName (default = lib/main))

NB: for the package’s modules to be loaded they must be wrapped in a define () function as below .. this can be done manually or with a script (RequireJS provides some scripts for mass conversion).

1
2
3
4
5
define(function(require, exports, module) {
    exports.boo = function () {
        alert("boo!");
    }
});

This must be exactly specified as above! (ie the parameters of the function must be ‘require’, ‘exports’, ‘module’ in that order). This seems a bit weird … how do you declare dependencies, if you must stick to this exact function signature? Well, the answer is that there is some magic at work… RequireJS looks for any ‘require()’ function calls in your module, and makes sure they are all loaded before the function is called! This is done because CommonJS has its own require() function, which is synchronous, so RequireJS essentially overrides it with its own asynchronous version. It is the ‘require’ parameter which triggers this behaviour. But what about the ‘exports’ and ‘module’ parameters ? Well, the exports argument is what will be returned when require() is called for this module. It is not necessary to return anything from the define() function, the value of ‘exports’ will be automatically returned. I’m not quite sure what the ‘module’ argument is for, as I haven’t seen it used anywhere, so its probably best to leave it alone.. perhaps it just provides backwards compatibility with CommonJS syntax? In fact, it is possible to leave out the ‘exports’ and ‘module’ arguments if you return the module explicitly from the function given to define() .. exactly as in normal non-CommonJS usage. See here.

Optimization

RequireJS provides an optimization tool, which uses UglifyJS as its compressor.

TO use it, clone or download the RequireJS source code as a sibling of your project and run the following command from the scripts (or lib, if in a CommonJS package) dir:

1
   ../../requirejs/build/build.sh name=main out=main-built.js baseUrl=.

And you will have a compressed main-built.js file with all your dependencies in it, so they can be required with a single HTTP request. Eg., you could change the script tag above to:

1
  <script src="scripts/require.js"><!--mce:2--></script>;

The RequireJS docs are excellent, and even nice to look at, so I recommend checking them out for more info, or if this becomes out of date…

API Docs

http://requirejs.org/docs/api.html

NodeJS and Friends

| Comments

Javascript Dev Tools: NodeJS, NPM, CommonJS, Teleport

I’ve recently discovered some neat tools which help make Javascript development easier. Everyone is excited about HTML5, which Brendan Eich (the inventor of Javascript) describes as ‘The unicorn which craps skittles from its rear end’. The Javascript language awaits a much needed update with ES5 Harmony, but in the meantime it has access to some cool new APIs in the form of HTML5 features such as Canvas, Local Storage, etc.

But what about outside of the browser? There have been some attempts to use Javascript on the server, but they don’t seem to have gained much widespread adoption. Then came NodeJS. If you haven’t heard about NodeJS I recommend you checkout this video by Ryan Dahl, the creator of NodeJS:

NodeJS is revolutionary in that it give Javascript access to the filesystem and network, with a performance oriented event-based approach that solves concurrency elegantly without the pain of multithreading. In itself this might only be interesting to hardcore server geeks, but NodeJS is being used as the infrastructure for a lot of other projects. Some of them are deployed by NPM, the Node Package Manager, which (surprise!) is a package management system for NodeJS applications. So once you have installed NodeJS and NPM, you can easily install other libraries on the command line. And you can create your own projects, using the CommonJS package format. This is made easy by the ‘npm init’ command, which creates a package.json configuration file for you automatically (I will give an example later).

But what if you’re more interested in client-side applications which run in a web-browser? No problem! Teleport comes to the rescue. This is itself a NodeJS package which you can install using NPM. Now once you have created a basic NPM / Common JS app, you just include the teleport library as a dependency. Then you can write your Javascript just as you usually would for a web-app. To test the app in a browser you run ‘teleport activate’ and Teleported will spawn a nodeJS webserver with your app running in it.

Once you have an awesome app ready, you can publish it to the NPM repository library with a single command (npm publish), so that other people can install it. No fussing about with web servers or downloading code. I’m really excited about the possibilities this creates for sharing client-server applications where the server is your own machine. Suddenly Javascript becomes a viable language for serious desktop applications with access to the filesystem and the network, as well as all the new HTML5 GUI goodness. Because the app runs on your own system, you can run it offline, and performance is going to be way better than over the internet.

In order to demonstrate just how easy this all is I will break it down for you, assuming you have nothing installed. Here we go:

Prerequisites:

sudo npm install teleport

Create a NPM app (I called mine frappuccino) using the command line:

mkdir frappucino
cd frappucino
npm init

At this point, you will go through a wizard to generate the package.conf file. It is just to provide metadata for your app, don’t worry too much about the answers, most of them are fine as they are. You can always edit it afterwards. For the ‘module entry point’ question I left it as default, and for the ‘where do your modules live’ I said ‘lib’ (this is standard, but not default). It actually guessed I was using a Git repo which I have in my home directory, which is not the repo I want to use, so I had to remove that reference afterwards. If you run it in a git repo, it will figure it out and use the info from that for the repository info. So if you want to do that, you should create the git repo first. After removing the incorrect repo info, my package.conf file looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
    "name": "frappucino",
    "description": "Frothy App",
    "version": "0.0.0",
    "author": "David Wilhelm ",
    "directories": {
        "lib": "lib"
    },
    "engines": {
        "node": "*"
    },
    "dependencies": {
        "teleport": "&lt;=0.2.2"
    }
}

The other change I made was to add the “dependencies” config, which will ensure that Teleport is installed as a dependency. OK, there are now a couple of other files you need to create:

The index.html page. Mine looks like this:

1
2
<script src="support/teleport/teleport.js" type="text/javascript"></script>
<script type="text/javascript"></script>

Note the included teleport file (which npm will supply), and the application js file (which we will create next). Now create the /lib folder in the frappucino folder, and in it create a file called app.js. In it I have the following, as a test.

alert("Frappucino is the best!");

Ok, now you should have the following file structure:

frappucino/
    index.html
    package.json
    lib/
        app.js

Finally, to get npm to supply the dependencies, and register the app locally, type this within the ‘frappucino’ directory:

sudo npm link

I get some nice pink and green output with ‘npm ok’ at the end to let me know it worked.

Now, to run the app, do:

teleport activate

If all goes, well, it should say something like:

Teleport is activated: http://localhost:4747/frappucino

Now you can open another terminal window and type:

open http://localhost:4747/frappucino

And you will see your app in all its glory (or lack thereof, such as in this case.. just an alert window. But its a start :).

My 10KApart Entry Is Live !

| Comments

My entry to the 10KApart Javascript competition is a lightweight version of the Turtle Graphics explorer I’ve been working on. Aside from leaving out the the procedures browser, and doing some compression (I used YUICompressor) I did not have to change the code, and I didn’t remove any of the turtle’s abilities. In fact there are a couple of new features, notably the showing of the turtle itself on screen.

So check it out, and rate it ! It turns out that community voting is no longer considered for the Community Prize, but it will make me feel better :)

I posted the source code on github also.