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