# HG changeset patch # User John "Elwin" Edwards # Date 1421767025 18000 # Node ID bbfda4a4eb7fdfc6a1ea9e176d7c122b2449918c # Parent ecedc6f7e4ac90d0824a31786f0db987a53a07e1 Finish moving DglSession methods into the prototype. diff -r ecedc6f7e4ac -r bbfda4a4eb7f rlgwebd.js --- a/rlgwebd.js Mon Jan 19 14:44:27 2015 -0500 +++ b/rlgwebd.js Tue Jan 20 10:17:05 2015 -0500 @@ -270,12 +270,11 @@ }; function DglSession(filename) { - var ss = this; BaseGame.call(this); var pathcoms = filename.split('/'); this.gname = pathcoms[pathcoms.length - 2]; if (!(this.gname in games)) { - ss.emit('open', false); + this.emit('open', false); return; } var basename = pathcoms[pathcoms.length - 1]; @@ -287,96 +286,106 @@ * getting into a race. */ this.reading = false; this.rpos = 0; - this.readchunk = function () { - if (this.reading) - return; - this.reading = true; - var header = new Buffer(12); - fs.read(ss.fd, header, 0, 12, ss.rpos, function (err, n, buf) { - /* Stop recursion if end of file has been reached. */ - if (err || n < 12) { - if (!err && n > 0) { - tslog("DGL %s: expected 12-byte header, got %d", ss.tag(), n); - } - ss.reading = false; - return; - } - ss.rpos += 12; - /* Update timestamp, to within 1 second. */ - ss.lasttime = new Date(1000 * buf.readUInt32LE(0)); - var datalen = buf.readUInt32LE(8); - if (datalen > 16384) { - // Something is probably wrong... - tslog("DGL %s: looking for %d bytes", ss.tag(), datalen); - } - var databuf = new Buffer(datalen); - fs.read(ss.fd, databuf, 0, datalen, ss.rpos, function (err, n, buf) { - if (err || n < datalen) { - /* Next time, read the header again. */ - ss.rpos -= 12; - ss.reading = false; - tslog("DGL %s: expected %d bytes, got %d", ss.tag(), datalen, n); - return; - } - ss.rpos += n; - ss.reading = false; - /* Process the data */ - ss.framepush(buf); - var wmsg = JSON.stringify({"t": "d", "d": buf.toString("hex")}); - for (var i = 0; i < ss.watchers.length; i++) { - if (ss.watchers[i].connected) - ss.watchers[i].sendUTF(wmsg); - } - ss.emit("data", buf); - //tslog("DGL %s: %d bytes", ss.tag(), buf.length); - /* Recurse. */ - ss.readchunk(); - }); - }); - }; - fs.readFile(filename, {encoding: "utf8"}, function (err, data) { + fs.readFile(filename, {encoding: "utf8"}, (function (err, data) { if (err) { - ss.emit('open', false); + this.emit('open', false); return; } var lines = data.split('\n'); - ss.h = Number(lines[1]); - ss.w = Number(lines[2]); - fs.open(ss.ttyrec, "r", function(err, fd) { + this.h = Number(lines[1]); + this.w = Number(lines[2]); + fs.open(this.ttyrec, "r", (function (err, fd) { if (err) { - ss.emit('open', false); + this.emit('open', false); } else { - ss.fd = fd; - ss.emit('open', true); - tslog("DGL %s: open", ss.tag()); - gamemux.emit('begin', ss.gname, ss.pname, 'dgl'); - ss.readchunk(); - ss.recwatcher = fs.watch(ss.ttyrec, function (ev, finame) { - if (ev == "change") - ss.readchunk(); - }); + this.fd = fd; + this.emit('open', true); + tslog("DGL %s: open", this.tag()); + gamemux.emit('begin', this.gname, this.pname, 'dgl'); + this.startchunk(); + this.recwatcher = fs.watch(this.ttyrec, this.notifier.bind(this)); } - }); - }); - this.close = function () { - this.recwatcher.close() - /* Ensure all data is handled before quitting. */ - this.readchunk(); - var connlist = this.watchers; - this.watchers = []; - for (var i = 0; i < connlist.length; i++) { - if (connlist[i].connected) - connlist[i].close(); - } - fs.close(this.fd); - this.emit("close"); - gamemux.emit('end', this.gname, this.pname); - tslog("DGL %s: closed", ss.tag()); - }; + }).bind(this)); + }).bind(this)); } DglSession.prototype = new BaseGame(); +/* 3 functions to get data from the ttyrec file. */ +DglSession.prototype.startchunk = function () { + if (this.reading) + return; + this.reading = true; + var header = new Buffer(12); + fs.read(this.fd, header, 0, 12, this.rpos, this.datachunk.bind(this)); +}; + +DglSession.prototype.datachunk = function (err, n, buf) { + /* Stop recursion if end of file has been reached. */ + if (err || n < 12) { + if (!err && n > 0) { + tslog("DGL %s: expected 12-byte header, got %d", this.tag(), n); + } + this.reading = false; + return; + } + this.rpos += 12; + /* Update timestamp, to within 1 second. */ + this.lasttime = new Date(1000 * buf.readUInt32LE(0)); + var datalen = buf.readUInt32LE(8); + if (datalen > 16384) { + // Something is probably wrong... + tslog("DGL %s: looking for %d bytes", this.tag(), datalen); + } + var databuf = new Buffer(datalen); + fs.read(this.fd, databuf, 0, datalen, this.rpos, this.handledata.bind(this)); +}; + +DglSession.prototype.handledata = function (err, n, buf) { + if (err || n < buf.length) { + /* Next time, read the header again. */ + this.rpos -= 12; + this.reading = false; + tslog("DGL %s: expected %d bytes, got %d", this.tag(), buf.length, n); + return; + } + this.rpos += n; + this.reading = false; + /* Process the data */ + this.framepush(buf); + var wmsg = JSON.stringify({"t": "d", "d": buf.toString("hex")}); + for (var i = 0; i < this.watchers.length; i++) { + if (this.watchers[i].connected) + this.watchers[i].sendUTF(wmsg); + } + this.emit("data", buf); + /* Recurse. */ + this.startchunk(); +}; + +/* Handles events from the ttyrec file watcher. */ +DglSession.prototype.notifier = function (ev, finame) { + if (ev == "change") + this.startchunk(); + /* If another kind of event appears, something strange happened. */ +}; + +DglSession.prototype.close = function () { + this.recwatcher.close(); + /* Ensure all data is handled before quitting. */ + this.startchunk(); + var connlist = this.watchers; + this.watchers = []; + for (var i = 0; i < connlist.length; i++) { + if (connlist[i].connected) + connlist[i].close(); + } + fs.close(this.fd); + this.emit("close"); + gamemux.emit('end', this.gname, this.pname); + tslog("DGL %s: closed", this.tag()); +}; + function wsStartGame(wsReq) { var playmatch = wsReq.resourceURL.pathname.match(/^\/play\/([^\/]*)$/); if (!playmatch[1] || !(playmatch[1] in games)) {