Entries tagged ‘dojo’
On Saturday, May 22nd the first ever dojo.beer(“Copenhagen”) will take place. We’ll start as an open space meeting in the afternoon, discussing any subject related to JavaScript development. At some point we’ll progress into the “beer” part of the program.
Special guest is Dylan Schiemann, co-founder of the Dojo Toolkit project and CEO of SitePen.
I’m on the lookout for a good location to host the event. Suggestions are most welcome. Actual time and location will be announced here later.
MOCH A/S has graciously offered to host us. We’ll start around 15:00 at Toldbodgade 51 D.
So, are you a JavaScript hacker? Let us know you’re coming by signing up here.
Being a Dojo hacker I’ve been wanting to use Dojo in combination with Node for a while now. So on a recent flight to London I added support for the Node environment to Dojo. I cleaned it up yesterday and – after figuring out Git – the code is now available on my Dojo fork.
Dojo is available for other environments than browsers, although the pre-compiled Dojo Base code you might have downloaded will only work in a browser. Other supported environments are Firefox extensions, the Rhino JavaScript engine and the Spidermonkey JavaScript engine. And now, Node.
Dojo is able to support multiple environments by dynamically bootstrapping itself for the given environment. In the non-compiled code, the dojo.js file detects its environment and loads the appropriate hostenv_*.js file. The biggest task of the various hostenv files is to fix the loader code to ensure dojo.require() works. Depending on the environment the file might also add some other features, for example the Rhino environment adds an implementation for setTimeout.
Right now I’m detecting the Node environment by seeing if the process object exists in the global scope. This object provides various utility methods to Node and is, as far as I know, unique to just the Node environment.
We briefly need to interrupt this explanation by discussing how we invoke Dojo within Node. As far as I can tell Dojo needs to exist in the global scope, and the only way to accomplish this is by loading the Dojo code when Node starts. Therefore you’d run node dojo.js to kick things off.
Based on this invocation we can use the path to dojo.js to calculate the root location of the Dojo files. I use process.ARGV[1].replace(/[^\/]+\.js$/, "") to do this. The primary reason for calculating the root is because the Dojo bootstrapping code uses the root location to load the host environment file. Technically I could have left it empty but that’s a bit silly.
Finally we use require() to load further bootstrapping code, the loader, the host environment and Dojo Base. As a special trick for the Node environment, dojo.js invokes dojo._loadInit() to signal that the environment is ready for use. In browsers this function would be invoked on DOM ready, but of course that’s not possible in Node.
The Node host environment file (hostenv_node.js) patches the loader so we can use dojo.require() in combination with Node’s module loading support. I’ve also added support for passing djConfig properties to Dojo. Simply pass the JSON object to the --djConfig argument: node dojo.js --djConfig='{isDebug:true}'.
Because we have to start Node with the dojo.js file we need a way to load additional JavaScript code into Node. This is accomplished by passing the -s or --script argument, which should point to a JavaScript file to be loaded into Node with require().
Currently the Node environment is largely untested, and it is quite probable that there are parts of Dojo that are depending on other features that haven’t yet been ported. I did try implementing the XMLHttpRequest object however, as a wrapper around Node’s HTTP libraries, to make it easier to execute HTTP requests through dojo.xhr().
Check out the code at Github. Some examples are also available. See the documentation on usage.
Using the localStorage object, the storage event and the postMessage() API, it is possible for browser windows to discover each other and to communicate with each other.
Crosscasting is a small Dojo package that publishes Dojo PubSub events to other browser windows that are running the Crosscasting code and are active within the same domain. Crosscasting of course stands for cross-window broadcasting.
Check out the example page, which of course you should open a couple different windows. Right now this only seems to work in the latest WebKit nightly builds.
The implementation is quite straight-forward. The first part is the Window Discovery Phase. An item is set in localStorage, which triggers the storage event. The Storage Event object has a source attribute which points to the Window object that set the item. (The storage implementation in Firefox 3.5 does not support this.) This is how a window informs other windows of its existence. The other windows subsequently use the postMessage() API to send a message to the original window. The Message Event also has a source attribute, pointing at the Window object that posted the message. At this point all windows know of each other’s existence. This phase is triggered by invoking supercollider.crosscast.init()
The second part is broadcasting Dojo PubSub events. Using supercollider.crosscast.subscribe("topic") you can register topics for broadcasting. The topic and any arguments are serialized to JSON and send to all other windows through postMessage(). The other window deserializes the message back to the PubSub event and publishes it locally.
// Initialize and start discovery
supercollider.crosscast.init();
// Subscribe to a topic for crosscasting
supercollider.crosscast.subscribe('crosscast/test');
// Subscribe to the topic
dojo.subscribe('crosscast/test', function(s) { alert(s) });
// Publish a PubSub event, both locally and to other windows
dojo.publish('crosscast/test', ['hello world']);
Again, have a look at the example. You can find the source at js-collider/crosscast.
P.S. I do not believe this is an original idea, but when I set about implementing this earlier today I could no longer find the site where I read this first. If you do know which site I’m talking about, let me know in the comments so I can give proper credit. Thanks!
dojo.Deferred would have been part two in my single part series on Method Chaining. It’s a pretty awesome way for setting up callback hierarchies for asynchronous programming:
function async() {
var d = new dojo.Deferred();
// Start something asynchronous,
// call d.callback(response) when done.
return d;
}
async().addCallback(function(response) {
alert('Ready!');
return response;
});
I can add multiple callbacks to async() or even chain them to the result of adding a callback:
async().addCallback(function(response) {
alert('Ready!');
return response;
}).addCallback(function(response) {
alert('Double ready!');
return response;
});
Parallel to the callback hierarchy, there’s an ‘errback’ hierarchy which is invoked in case a callback throws an error. This makes it easy to handle errors within the callback chain. Unfortunately it also prevents the error from being logged in the browser’s error console.
Luckily, it isn’t hard to log these errors ourselves. Simply run the following before using any deferreds:
;(function() {
var addCallback = dojo.Deferred.prototype.addCallback;
dojo.Deferred.prototype.addCallback = function() {
var cb = addCallback.apply(this, arguments);
cb.addErrback(console.error);
return cb;
};
})();
This overwrites the original addCallback method to automatically register an ‘errback’, which logs to console.error. Then, it returns the original return value, so it doesn’t affect other code.
Happy Dojo’ing!
Three weeks ago already I participated in the Mediamatic Social RFID Hackers Camp at Picnic 08 in Amsterdam. At Hackers Camp, in about five days time, an excellent group of designers, tinkerers, builders and hackers built eight Social RFID installations to be enjoyed by the Picnic’ers.
Together with Erik Borra, Eelco Wagenaar, Martijn Pannevis and Adriaan Wormgoor I built Vbird. Vbird is a flightless bird, equipped with a wireless camera and Arduino BT powered RFID reader and accelerometer. Since Vbird can’t fly, you have to throw it to each other to make it fly! It continuously records video, and if you let it scan your Picnic RFID tag, the next video will be uploaded to your profile. In all, pretty awesome. You can see some videos here: http://www.justlol.net/vbird/.
Unfortunately Vbird did not last very long. Every piece of hardware inside the bird that could fail, failed. It worked briefly at the end of Wednesday, the first Picnic conference day. It consistently broke down on Thursday, at the end of which day we finally gave up. No more Vbird.
I primarily worked on making Vbird interface with anyMeta, the community management system created by Mediamatic Lab and used to drive the Picnic website. This involved setting up the video processing infrastructure with Martijn and some help from Robin Gareus. The video processing ran on a MacBook Pro – converted to a Ubuntu machine – hooked up to a analogue to MPEG video converter. (We had it working on an EEE PC, and figured it’d be faster to install Ubuntu on the MacBook than figuring out how to do the video processing on OS X.) We used ffserver to set up a Flash video stream we could display live, and used ffmpeg to make video segments encoded in Flash video. This then was controlled using OSC messages from a second MacBook Pro, which did the main anyMeta interactions, handled Arduino communication, and drove the UI.
The second MacBook Pro did all this using Physical.js, which is an open source library, by yours truly, for doing physical computing in JavaScript. It runs inside Rhino, which is a JavaScript-interpreter written in Java. The big advantage of Rhino is that you can use the Java libraries, and still write lovely JavaScript.
Physical.js builds upon Dojo, which makes it easy to separate the code into modules, has a fantastic event system, and even a Twisted-like Deferred implementation. Now, Dojo hasn’t really focused on its Rhino support, but that’s something I hope to change going forward, by contributing code from Physical.js back to Dojo.
In any case, Dojo’s event system leads to some interesting “Action Oriented” code. For example, the code reading the output from the Arduino BT is encapsulated in a ArduinoReader class:
dojo.require('picnic.ArduinoReader');
reader = new picnic.ArduinoReader('/dev/tty.Arduino_bt121-Bluetooth-1');
Then, we simply hook up a few events:
reader.onOpenComplete = function() {
// …
};
reader.onOpenError = function(e) {
// …
};
reader.onAcceleration = function() {
// …
};
reader.onDeceleration = function() {
// …
};
reader.onTagEnter = function(evt) {
// …
};
(Admittedly, perhaps I should have used dojo.connect() instead of directly overwriting the event callbacks, but hey.)
From a programming perspective, it’s quite awesome that you can simplify the input stream to a few events, to which you can hook up other actions. Having such a framework available, and being able to clearly express the actions, helped a lot in creating Vbird.
And, when the onboard RFID reader died, it was easy to hook up a physically connected RFID reader:
dojo.require('picnic.OSCReader');
reader2 = new picnic.OSCReader(7007);
dojo.connect(reader2, 'onTagEnter', reader, 'onTagEnter');
Here picnic.OSCReader implements the ph.rfid.Reader interface, just like picnic.ArduinoReader. It receives OSC messages from the Tikitag reader we used, through the RFID-to-OSC gateway written by Mediamatic. (Ironically, we had no Java software available for the Tikitag reader.) It’s simply a matter of connecting the two onTagEnter handlers to use a second RFID input with the original code.
Another incredibly useful thing was automatically generating an API for anyMeta. A slightly older version of the code I used can be seen in the Flickr API implementation in Physical.js. It uses dojo.getObject() and the __noSuchMethod__ method to dynamically set up an API. In the Flickr API example, there’s an API declaration for people, which lets you use all people.* methods, without explicitly declaring them.
anyMeta uses OAuth to control access to API methods. The API implementation I wrote – and which has yet to be ported to Physical.js – automatically signs API calls before sending them to the server. This, then, lets us do:
dojo.require('picnic.anyMeta.anyMeta');
api = new picnic.anyMeta.anyMeta(OAUTH, ANYMETA_ENDPOINT);
profile = api.picnic.persons.get({rfid: 'urn:rfid:1AA037EF'});
Which gives us the profile corresponding to a specific RFID tag.
The API code takes care of serializing to and from JSON, as well, which made it incredibly easy to interact with anyMeta.
The UI Adriaan built for Vbird was a small Flash movie, served and updated straight from the Physical.js code. See, the Jetty web server is included in Physical.js, making it easy to serve-up static files, and register handlers for specific URLs:
dojo.require('jetty.Server');
server = new jetty.Server(8080, jettyResources);
server.register('/stream/latest.js', function(request, response) {
response.type = 'text/javascript';
response.body = dojo.toJson({
latest: 'Latest data here…'
});
});
server.start();
This then is a far more elegant solution than writing data to a file, accessed via a separate web server. Breathlyzer, created by Matt Cottam and Jasper Speicher of Tellart also used Physical.js for this purpose.
In all, using Physical.js at Picnic was great fun, and it’s definitely cool to use JavaScript for something completely different than web programming. Let me know what you think of Vbird and Physical.js!


