Objects and SetTimeout

February 25th, 2007

I got an interesting question from Chris Coggins regarding the use of objects and setTimeout. Oftentimes, we want state associated with each invocation of the timeout handler. The challenge comes from the fact that when our setTimeout code fires, it runs as if it were defined in the global scope. This means we only have access to what’s available in that scope: global properties.

Ideally, setTimeout could fire a function as if it were a method. That would make “this” inside the function’s body refer to the particular instance firing the function. That in turn would give us something to which we could attach state for each setTimeout invocation. Unfortunately, that’s not an option with today’s implementation of setTimeout, so we need a workaround.

In the past, I would enqueue the object containing my state, call setTimeout, and then dequeue the object in the timer handler. This gets a bit ugly since you have to maintain arrays (still somewhat globally) and it’s fairly easy to imagine a situation where two setTimeouts can interfere with one another if they share the same array. We get around these issues via a JavaScript closure.

The first important point is that setTimeout implementations allow the first parameter to be a function reference as opposed to a string. The second important point is that we can make a closure by creating a function literal. The closure allows our function literal to access variables that were in its scope when it was defined. To make this a bit clearer, let’s create a Person object that counts down at a regular interval.

function Person(name, count) {
    this.name = name;
    this.count = count;
}

Person.prototype.countDown = function() {
    var self = this;
    var process = function() {
        println(self.name + “: ” + self.count);

        self.count–;

        if (self.count > 0) {
            self.countDown();
        }
    }

    setTimeout(process, 500);
}

When the “process” function is called via setTimeout() “this” would refer to global instead of our Person instance. We create a “self” local variable as a sibling to the function literal. This makes “self” visible to the function literal’s body regardless of where it actually executes. This is one of the beauties of closures. We have effectively glued the active Person instance to the “process” function, so when it fires, it can access that instance.

To make sure we really have multiple contexts, we can test with something like the following:

function init() {
    var john = new Person(”John”, 3);

    john.countDown();

    // delay the other counter
    setTimeout(init2, 250);
}

function init2() {
    var sarah = new Person(”Sarah”, 5);

    sarah.countDown();
}

You can see a sample at:

/tutorials/javascript/inheritance/count-down.htm

Enjoy.

Faster SVG Game of Life

September 3rd, 2006

I recently had the honor of having an image of my black and white Game of Life published in Architectural Design’s “Programming Cultures: Art and Architecture in the Age of Software.” Honestly, I’m not quite sure why I’m in there, but I was flattered nonetheless. I found the content quite interesting and I recommend that issue to you if you’re inspired by the possibilities of computer-generated architecture.

Liz and I moved back to Texas last week, so I had three days to ponder everything you can imagine as we drove through the Southwest in separate vehicles. (As an aside, it is amazingly beautiful from roughly Yuma to El Paso right now due to all the rain they’ve been getting. It’s a nice roadtrip this time of year.) Of course, I got to thinking about the Game of Life and an interesting article I read years ago about a very fast hardware approach to image convolutions. I’ve never been particularly happy with the speed of my SVG Life implementation, but, as is typical for many developers, I never really had the time to explore how to speed things up…until today. The good news is that with a minor tweak of my Bitmap object and an adaptation of the hardware technique, my implementation is about ten times faster. Even better, Opera and Firefox run about twice as fast as IE 6.

http://www.kevlindev.com/alife/life/life_2_0_bw.svg

And here’s the old version for reference:

 http://www.kevlindev.com/alife/life/life_bw.svg

The code is still in a little bit of a rough state right now, but I’m happy with the results. I’m pretty sure I could squeeze out a bit more speed, but I guess that will have to wait for another weekend…and hopefully before the next roadtrip.

Enjoy!

Aptana IDE - Milestone 4

August 13th, 2006

We just released milestone 4 of the Aptana IDE last week. This was mostly a bug fix release. (We’re going to try odd number releases for new features and even number releases for bug fixes and optimizations). However, we did squeeze in a few new features: snippets and improved XHTML support.

If you write HTML, CSS, and JavaScript then you should give Aptana a try. You can see the IDE in action with a number of screencasts we’ve put up on Aptana.tv. Oh, and this is all open source and free.