Up tonight, a simple enough task: restore idle timeouts in my (fab) game.
I spent the bulk of last night deleting code that provided functionality better implemented in faye. The fab.js backend is now little more than a skeleton app serving up html, javascript, CSS and a place for the faye serve to hang its hat:
with ( require( "fab" ) )Aside from that, I have a local player store:
( fab )
// Listen on the FAB port and establish the faye server
( listen_with_faye, 0xFAB )
// resource to query player status -- debugging
( /^\/status/ )
( player_status )
// serve javascript and CSS
(/^\/(javascript|stylesheets)/)
(/^\/([-_\w]+)\.(js|css)$/)
(fab.nodejs.fs)
( fab.tmpl, "<%= this[0] %>/<%= this[1] %>.<%= this[2] %>" )
( fab.capture )
(404)
// serve static HTML
(/^\/([_\w]+)$/)
(fab.nodejs.fs)
( fab.tmpl, "html/<%= this %>.html" )
( fab.capture.at, 0 )
// anything else is 404 / Not Found
( 404 );
var players = {};And several functions to interact with that local store:
function add_player(player) { ... }Lastly, I have a faye client that listens for messages and calls the appropriate player function. I had to put that client inside a 0.5 second timeout to allow the TCP/IP server establish itself at startup:
function update_player_status(status) { ... }
function idle_watch(id) { ... }
function drop_player(id) { ... }
// Ensure that the faye server has fully established by waitingWhile surveying this, I recognize that idle timeout is going to be a bit of a challenge. The actual timeout code (
// half a second before subscribing to channels
setTimeout(function(){
var client = new faye.Client('http://localhost:4011/faye');
client.subscribe("/move", function(message) {
update_player_status(message);
});
// other faye subscriptions
}, 500);
idle_watch()
) will work fine. Calling the function to drop the players (drop_player
) will also work. The problem I am facing is how to broadcast the "drop player" message to my clients.The
client
object is closed inside the setTimeout
function. There is no way for me to get access to it from inside the drop_player()
function. I could declare a global client
variable and assign it inside the the setTimeout
:var client;Am I really going to let disgust with global variables prevent me from stopping there, calling it a night and getting a decent night's sleep? Of course I am.
setTimeout(function(){
client = new faye.Client('http://localhost:4011/faye');
client.subscribe("/move", function(message) {
update_player_status(message);
});
// other faye subscriptions
}, 500);
function drop_player(id) {
client.publish("/drop", id);
}
This global variable trying to pop into existence is trying to tell me that I need an object. The functions that are interacting with the global store,
players
, ought to be methods on that object. I can then refactor the local store as:// Player local storeInside the the
var players = {
_: { },
all: function() {
return this._;
},
add_player: function(player) { ... },
update_player_status: function(status) { ... },
idle_watch: function(id) { ... },
drop_player: function(id) { ... },
init: function() { ... }
};
init()
method, I can establish my faye server and assign the client to an attribute of the player store object (nicely encapsulated, non-global):init: function() {I can then use that attribute to broadcast "drop player" messages via faye:
var self = this;
var faye = require("faye");
this.faye = new faye.Client('http://localhost:4011/faye');
this.faye.subscribe("/move", function(message) {
self.update_player_status(message);
});
// other faye interaction
}
drop_player: function(id) {I rather like that approach. Everything having to do with the player store, including pub-sub, is now nicely encapsulated in an object. Initial interaction in the game seems to indicate that it all just works.
puts("Dropping player \""+ id +"\"");
this.faye.publish("/players/drop", id);
delete this._[id];
}
I have removed much over the past few days. Tomorrow, I will play around with the game a bit to make sure that everything is still OK before moving on to investigate some speed issues that I noted yesterday.
Day #187
No comments:
Post a Comment