From 046e7035bccc632269c10d869837ead3b8695305 Mon Sep 17 00:00:00 2001 From: Holden Rohrer Date: Mon, 20 Jan 2020 16:05:16 -0500 Subject: added a land claim system --- examples/jarvis.js | 40 +++++++++++++++------------------------- tools/claim.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 25 deletions(-) create mode 100644 tools/claim.js diff --git a/examples/jarvis.js b/examples/jarvis.js index 3e18e85..9f4e529 100644 --- a/examples/jarvis.js +++ b/examples/jarvis.js @@ -11,10 +11,12 @@ const ri = require('../utils/rectintersect'); const id = require('../utils/ident'); const maketiles = require('../utils/maketiles'); const wwrap = require('../utils/writewrap'); +const Claims = require('../tools/claim'); //// The queue of all writes to be sent to the server @ 200chars/1000ms var writes = new sched.Queue(1000, 200, (elems) => main.write(elems)); var main = new Socket(); +var claims = new Claims(detectPrompt); // See ident.js for further documentation, but this basically sets up init functions id(main, initOnce, init, deinit); @@ -43,14 +45,10 @@ function initOnce(){ function tileHandler(send, source, tiles){ if (send == sender) return; let tiledata = maketiles(tiles); - funcs.forEach(func => { - func(send, tiledata.tilespaces, tiledata.locs); - }); + claims.handle(send, tiledata.tilespaces, tiledata.locs); } //// "userspace" functions for responses, like to tileUpdates -var funcs = [protectArea, detectPrompt]; - var command = 'jarvis' var sig = 'feynmansfedora' var notifsrc = '\ @@ -63,7 +61,7 @@ var notifsrc = '\ notifsrc = notifsrc.replace('COMMAND', command).replace('SIGNATURE', sig); var minsUp = 0; var callct = 0; -var ctrl; +var notifClaim; function genNotif(){ let newnotif = new Space(); @@ -79,34 +77,26 @@ function notifRefresh(){ let newnotif = genNotif(); let diff = newnotif.copy(); if (typeof notif !== 'undefined') diff.comb(notif, comb.sub); - notif = diff; - ctrl = ms(notif); + notif = newnotif; + claims.unclaim(notifClaim); + notifClaim = claims.claim(newnotif, protectArea); return (diff.towrite()); } function timect(){ - writes.enqueue(notifRefresh()); minsUp++; + writes.enqueue(notifRefresh()); setTimeout(timect, 60*1000); } -function protectArea(send, tiles, locs){ - let tilesize = [8, 16]; // This may be exportable to an external util/tool - for (loc of locs){ +function protectArea(send, tiles, locs, id, space, ctrl){ + for (let loc of locs){ let tile = tiles[loc]; - let origloc = loc; - loc = vec.tileToChar(loc); - if (ri(ctrl, [loc, vec.add(loc, tilesize)])){ - // Write diffs from the tile - let diff = notif.copy(); // Acts as a window for tile (only see relevant data) - diff.comb(tile, comb.flip(comb.unmask)); - diff.comb(tile, comb.sub); - writes.enqueue(diff.towrite()) - // Mask the tile - let newtile = notif.copy(); - newtile.comb(tile, comb.mask); - tiles[origloc] = newtile; - } + // Write diffs from the tile + let diff = space.copy(); // Acts as a window for tile (only see relevant data) + diff.comb(tile, comb.flip(comb.unmask)); + diff.comb(tile, comb.sub); + writes.enqueue(diff.towrite()) } } diff --git a/tools/claim.js b/tools/claim.js new file mode 100644 index 0000000..2e568f2 --- /dev/null +++ b/tools/claim.js @@ -0,0 +1,50 @@ +// A tool to manage land claims (i.e. a certain Space is delegated to only call a specific `call()` if a tileUpdate occurs differing from that Space) + +const ms = require('../utils/measurespace'); +const ri = require('../utils/rectintersect'); +const vec = require('../utils/vec'); +const comb = require('../utils/comb'); + +module.exports = function(catchall){ + // socket is a Socket() object to declare the hook on. + // catchall is called if tileUpdate occurs w/ no relevant claim on a part. + let claims = {}; + let claimId = 0; + this.claim = function(space, call, excl=true){ + // `space` is Space obj; `call` is callback function + // `exclusive` sets whether this callback will prevent other (incl. catchall) functions from seeing the space. Cannot be used with an exclusive callback, and does not guarantee order. + // If exclusive claim intersects another claim, behavior undefined. + claimId++; + claims[claimId] = {'space':space, 'call':call, 'excl':excl, 'area':ms(space)} + return claimId; + } + + this.unclaim = function(id){ + delete claims[id]; + } + + this.handle = function(send, tilespaces, locs){ + // Because usually tilespaces is small, the inefficiency of an O(nk) rect match is acceptable + for (let id in claims){ + claim = claims[id]; + diffspace = {}; + rellocs = []; + for (let loc of locs){ + let tile = tilespaces[loc]; + if (ri(claim.area, [vec.tileToChar(loc), vec.tileToChar(vec.add(loc, [1,1]))])){ + let diff = claim.space.copy(); + diff.comb(tile, comb.unmask); + rellocs.push(loc); + diffspace[loc] = diff; + if (claim.excl){ + let newtile = claim.space.copy(); + newtile.comb(tile, comb.mask); + tilespaces[loc] = newtile; + } + } + } + claim.call(send, diffspace, rellocs, id, claim.space, claim.area); // claim.space should not be modified by the function. it is only present to make functions easier to write + } + catchall(send, tilespaces, locs); + } +} -- cgit