Sunday, May 30, 2010

Cleaning Up After the Clean-Up

‹prev | My Chain | next›

Up tonight, cleaning up a bit of the mess I have left myself in my (fab) game. Over the past two nights I have refactored the fab.js code initializing a new player in the game. The refactoring was driven entirely by testing (yay!), which means that things got much simpler. It also means I left a few things out.

In this case, there are three things that I omitted: adding the new player to the players known by the backend, broadcasting the new player to players already in the game, and telling the new player about all the existing players in the room. Previously, my app chain looked like:
  ( /^\/comet_view/ )
( init_comet )
( player_from_querystring )
The init_comet is the fab app that has gotten the love (and lost features), so I need to work around it. Adding the player to the fab.js is the easiest part, I can add another (fab) app to accomplish what I need:
  ( /^\/comet_view/ )
( init_comet )
( add_player )
( player_from_querystring )
At some point I'll drive the add_player app via a test (or, at the very least, test it after the fact). For now, I just move the code from the old init_comet app that did not make the refactored cut into add_player:
function add_player (app) {
return function () {
var out = this;

return app.call( function listener(obj) {
out(obj);
if (obj && obj.body) {
var new_id = obj.body.id;
puts("adding: " + new_id);
players[new_id] = {status: obj.body, listener: out};

idle_watch(new_id);
}
return listener;
});
};
}
Nothing too fancy in this binary fab.js app: the listener pulls the player back from upstream (player_from_querystring in this case), adds it to the players list and establishes an idle player watch. I can verify that all is well so far by running the game, adding a flew players and watching for the "adding: " + new_id output:
cstrom@whitefall:~/repos/my_fab_game$ node game.js
adding: foo
...
Now comes the slightly trickier part: broadcasting to all players in the players list. Ignoring, for the time being the content of the app, I would like another middleware (binary in fab.js parlance) app that sits in the stack broadcasting the news of the new player. Something like:
  ( /^\/comet_view/ )
( broadcast_new )
( init_comet )
( add_player )
( player_from_querystring )
Unfortunately, that will not work. The broadcast_new app no longer has access to the player data—init_comet does not return player data, just comet data for the browser. Putting the broadcast_new app further upstream won't help either—broadcasting to all clients before all comet sessions are established is a good way to break things.

At this point, I have to call it a night. Hopefully a fresh perspective tomorrow will provide an answer on how to best approach.

Day #119

No comments:

Post a Comment