From 1b405b8701e6c76df6ea87d4dc15d72cc726823b Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Tue, 2 Jan 2018 17:00:50 +0100 Subject: [PATCH] Refactored chunkStore to use linvodb3, broke mapping (ofc) --- lib/chunkStore.js | 115 +++++++++---------------------- lib/chunkStore.spec.js | 41 ++++++----- sharedPlugins/remoteMap/index.js | 10 +-- 3 files changed, 62 insertions(+), 104 deletions(-) diff --git a/lib/chunkStore.js b/lib/chunkStore.js index d53eae87..177e5d35 100644 --- a/lib/chunkStore.js +++ b/lib/chunkStore.js @@ -3,6 +3,10 @@ var mkdirpSync = require("mkdirp").sync; var fs = require("fs"); var objectOps = require("./objectOps"); +var LinvoDB = require("linvodb3"); +LinvoDB.dbPath = "./database/linvodb/"; + + let allowLogging = true; let log = string => (allowLogging)? console.log(string):"" @@ -13,98 +17,51 @@ module.exports = class chunkStore { this.path = (path[path.length] == "/") ? path : path+"/"; mkdirpSync(path+name); - this.entityWriteQueue = []; - this.chunkWritesInProgress = {}; - this.entityWriteInProgress = false; - } - checkChunkWrite(x, y){ - if(!this.chunkWritesInProgress[x]) this.chunkWritesInProgress[x] = {}; - if(!this.chunkWritesInProgress[x][y]){ - return false - } else { - return true - } - } - setChunkWrite(x,y, bool){ - if(!this.chunkWritesInProgress[x]) this.chunkWritesInProgress[x] = {}; - if(!this.chunkWritesInProgress[x][y]) this.chunkWritesInProgress[x][y] = bool; + this.db = new LinvoDB(name, {}, {}); } setEntity(x/**{number}*/, y/**{number}*/, newEntity/**{object}*/){ return new Promise((resolve, reject) => { - var localX = x > 0 ? Math.round(x % this.chunkSize) : Math.round(x % this.chunkSize)+64; - x = Math.floor(Math.round(x)/this.chunkSize); - var localY = y > 0 ? Math.round(y % this.chunkSize) : Math.round(y % this.chunkSize)+64; - y = Math.floor(Math.round(y)/this.chunkSize); - console.log("localX"+localX) - console.log("localY"+localY) - console.log(x+ " "+y) - this.entityWriteQueue.push({x, y, localX, localY, newEntity}); - if(this.checkChunkWrite(x,y)){ - // we don't need to initiate another request for a chunk because there is one running already which should take care of it - } else { - this.setChunkWrite(x, y, true); - this.getChunk(x,y).then(chunk => { - log("Setting "+this.entityWriteQueue.length+" entities in chunk X: "+x+" Y: "+y); - - // add each queued entity to the chunk - this.entityWriteQueue.forEach(queuedEntity => { - if(queuedEntity.x == x && queuedEntity.y == y){ - let localX = queuedEntity.localX; - let localY = queuedEntity.localY; - let newEntity = queuedEntity.newEntity; - - if(!chunk.dataObject[localX]) chunk.dataObject[localX] = {}; - if(!chunk.dataObject[localX][localY]) chunk.dataObject[localX][localY] = {}; - - if(newEntity && typeof newEntity == "object"){ - log("Overwriting with new entity at "+localX+", "+localY); - chunk.dataObject[localX][localY] = newEntity; - } else { - log("Deleting entry at "+localX+", "+localY); - chunk.dataObject[localX][localY] = undefined; - } - } + x = Math.floor(x); + y = Math.floor(y); + this.db.find({x, y}, (err, docs) => { + if(typeof newEntity == "object"){ + if(err) reject(err); + let entityDoc = {x, y, entity: newEntity}; + if(docs && docs[0] && docs[0]._id){ + entityDoc._id = docs[0]._id; + } + this.db.save(entityDoc, (err,docs) => { + if(err) reject(err); + resolve(docs); }); - // clear the now processed queue - this.entityWriteQueue = this.entityWriteQueue.filter(entity => { - if(entity.x != x && entity.y != y) return true + } else { + docs.forEach(doc => { + doc.remove(()=>{ + // removed :) + resolve(); + }); }); - // save the chunk and resolve the promise - this.setChunk(x, y, chunk).then(()=>{ - log("Successfully saved chunk!"); - //this.entityWriteInProgress = false; - this.setChunkWrite(x,y,false); - resolve(chunk); - }); - }); - } + } + }); }); } - setChunk(x, y, chunk){ + getEntity(x, y){ return new Promise((resolve, reject) => { - mkdirp(this.path+this.name+"/"+x).then(() => { - fs.writeFile(this.path+this.name+"/"+x+"/"+y, JSON.stringify(chunk, null, 4), function(err){ - if(err) { - reject(err); - } else resolve(); - }); + this.db.find({x:Math.floor(x), y:Math.floor(y)}, (err, docs) => { + if(err) reject(err); + resolve(docs); }); }); } getChunk(x, y){ return new Promise((resolve, reject) => { + + /* // make new chunk in case we can't find an existing one let chunk = { dataObject: {}, position:{x,y}, // fancy ES6 feature that generates to {x:x, y:y} - chunkSize:this.chunkSize, - /*get: function(x, y){ - if(this.dataObject[Math.round(x)] && this.dataObject[Math.round(x)][Math.round(y)]){ - return this.dataObject[Math.round(x)][Math.round(y)]; - } else { - return undefined; - } - },*/ + chunkSize:this.chunkSize }; fs.readFile(this.path+this.name+"/"+x+"/"+y, (err, chunkFile) => { @@ -115,13 +72,6 @@ module.exports = class chunkStore { if(objectOps.isJSON(chunkFile)) { log("returned from file") let chunk = JSON.parse(chunkFile); - /*chunk.get = function(x, y){ - if(this.dataObject[Math.round(x)] && this.dataObject[Math.round(x)][Math.round(y)]){ - return this.dataObject[Math.round(x)][Math.round(y)]; - } else { - return undefined; - } - }*/ resolve(chunk); } else { log("file failed") @@ -129,6 +79,7 @@ module.exports = class chunkStore { } } }); // add x and y values as well and we are done? + */ }); } } \ No newline at end of file diff --git a/lib/chunkStore.spec.js b/lib/chunkStore.spec.js index 00747b8c..c53fdc95 100644 --- a/lib/chunkStore.spec.js +++ b/lib/chunkStore.spec.js @@ -15,28 +15,33 @@ describe("chunkStore.js", () => { store = new chunkStore("910239"/* instanceID, use defaults for the rest */); assert.equal(store.name, "910239"); }); - it("allows you to store the locations of entities in a chunk divided database", () => { - return store.setEntity(inserterX, inserterY, {name:inserterName}).then(() => { + it("allows you to store the locations of entities", done => { + store.setEntity(inserterX, inserterY, {name:inserterName, otherData:"can be arbitrary"}).then(() => { + done(); // nothing to do here really }); }); - it("returns items located in a chunk", (done) => { - // We return the promise to mocha as it supports promises natively, works a lot better than calling done() manually. - let x = 0; - let y = -1 - store.getChunk(x,y).then(chunkData => { - console.log(chunkData); - assert.equal(typeof chunkData, "object"); - assert.equal(chunkData.dataObject[15][47].name, inserterName); - assert.equal(chunkData.position.x, x); - assert.equal(chunkData.position.y, y); - done(); - }); + it("returns entities at positions you query for", done => { + setTimeout(()=>{ + store.getEntity(inserterX, inserterY).then(entities => { + entity = entities[0] + // console.log(entity) + assert.equal(entity.x, 14); + assert.equal(entity.y, -18); + assert.equal(entity.entity.name, "inserter"); + assert.equal(entity.entity.otherData, "can be arbitrary"); + done(); + }); + },500) }); it("deletes entities when not provided with an object as 3rd arg", done => { - store.setEntity(inserterX, inserterY).then((chunk)=>{ - assert(!chunk.dataObject(15, 47)); - done(); + store.setEntity(inserterX, inserterY).then(entity => { + assert(entity === undefined); + store.getEntity(inserterX, inserterY).then(entities => { + // console.log(entities) + assert.equal(entities.length, 0, "Why are we getting results, it should be empty?"); + done(); + }); }); }); -}); \ No newline at end of file +}); diff --git a/sharedPlugins/remoteMap/index.js b/sharedPlugins/remoteMap/index.js index f9233659..36d7e411 100644 --- a/sharedPlugins/remoteMap/index.js +++ b/sharedPlugins/remoteMap/index.js @@ -36,7 +36,6 @@ class remoteMap { data = data.split(" "); if(data && data[0] == undefined){ - // this position is now empty, delete whatever was there from DB console.log("empty: "); console.log(data); return @@ -46,12 +45,15 @@ class remoteMap { let yPos = data[2]; if(xPos && yPos && name){ if(name == "deleted"){ - this.chunkMap.setEntity(xPos, yPos, "delete this entity").then(data => { - this.messageInterface("Deleted data "+data.position.x+", "+data.position.y); + // this position is now empty, delete whatever was there from DB + this.chunkMap.setEntity(xPos, yPos, "delete this entity").then(() => { + this.messageInterface("Deleted data "+xPos+", "+yPos); }).catch((err)=>this.messageInterface(err)); } else { + // save this entity in the database this.chunkMap.setEntity(xPos, yPos, {name}).then(data => { - this.messageInterface("Added "+name+" to data "+data.position.x+", "+data.position.y); + data = data[0]; + this.messageInterface("Added "+name+" to data "+data.x+", "+data.y); }).catch((err)=>this.messageInterface(err)); } }