mirror of
https://github.com/lovasoa/whitebophir
synced 2024-11-14 16:27:13 +00:00
Fix bug where a board would be used without being ready
This commit is contained in:
parent
22981f4e87
commit
b9aca0b00d
2 changed files with 55 additions and 77 deletions
|
@ -26,9 +26,7 @@
|
|||
*/
|
||||
|
||||
var fs = require('fs'),
|
||||
path = require("path"),
|
||||
util = require("util"),
|
||||
events = require("events");
|
||||
path = require("path");
|
||||
|
||||
/** @constant
|
||||
@type {string}
|
||||
|
@ -55,17 +53,11 @@ var MAX_BOARD_SIZE = 65536; // Maximum value for any x or y on the board
|
|||
var BoardData = function (name) {
|
||||
this.name = name;
|
||||
this.board = {};
|
||||
this.ready = false;
|
||||
this.file = path.join(HISTORY_DIR, "board-" + encodeURIComponent(name) + ".json");
|
||||
this.lastSaveDate = Date.now();
|
||||
|
||||
//Loads the file. This will emit the "ready" event
|
||||
this.load(this.file);
|
||||
this.users = new Set();
|
||||
};
|
||||
|
||||
//Allows to use BoardData.emit() and BoardData.on()
|
||||
util.inherits(BoardData, events.EventEmitter);
|
||||
|
||||
/** Adds data to the board */
|
||||
BoardData.prototype.set = function (id, data) {
|
||||
//KISS
|
||||
|
@ -218,21 +210,22 @@ BoardData.prototype.validate = function validate(item, parent) {
|
|||
/** Load the data in the board from a file.
|
||||
* @param {string} file - Path to the file where the board data will be read.
|
||||
*/
|
||||
BoardData.prototype.load = function (file) {
|
||||
var that = this;
|
||||
fs.readFile(file, function (err, data) {
|
||||
try {
|
||||
if (err) throw err;
|
||||
that.board = JSON.parse(data);
|
||||
for (id in that.board) that.validate(that.board[id]);
|
||||
console.log(that.name + " loaded from file.");
|
||||
} catch (e) {
|
||||
console.error("Unable to read history from " + file + ". The following error occured: " + e);
|
||||
console.log("Creating an empty board.");
|
||||
that.board = {}
|
||||
}
|
||||
that.ready = true;
|
||||
that.emit("ready");
|
||||
BoardData.load = function loadBoard(name) {
|
||||
var boardData = new BoardData(name);
|
||||
return new Promise((accept) => {
|
||||
fs.readFile(boardData.file, function (err, data) {
|
||||
try {
|
||||
if (err) throw err;
|
||||
boardData.board = JSON.parse(data);
|
||||
for (id in boardData.board) boardData.validate(boardData.board[id]);
|
||||
console.log(boardData.name + " loaded from file.");
|
||||
} catch (e) {
|
||||
console.error("Unable to read history from " + boardData.file + ". The following error occured: " + e);
|
||||
console.log("Creating an empty board.");
|
||||
boardData.board = {}
|
||||
}
|
||||
accept(boardData);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
var iolib = require('socket.io')
|
||||
, path = require("path")
|
||||
, fs = require('fs')
|
||||
, BoardData = require("./boardData.js").BoardData;
|
||||
|
||||
var MAX_EMIT_COUNT = 64; // Maximum number of draw operations before getting banned
|
||||
var MAX_EMIT_COUNT_PERIOD = 5000; // Duration (in ms) after which the emit count is reset
|
||||
|
||||
function Board(name) {
|
||||
this.name = name;
|
||||
this.data = new BoardData(name);
|
||||
this.users = new Set();
|
||||
}
|
||||
|
||||
var boards = {
|
||||
"anonymous": new Board("anonymous")
|
||||
};
|
||||
// Map from name to *promises* of BoardData
|
||||
var boards = {};
|
||||
|
||||
function noFail(fn) {
|
||||
return function noFailWrapped(arg) {
|
||||
|
@ -32,11 +23,12 @@ function startIO(app) {
|
|||
return io;
|
||||
}
|
||||
|
||||
/** Returns a promise to a BoardData with the given name*/
|
||||
function getBoard(name) {
|
||||
if (boards.hasOwnProperty(name)) {
|
||||
return boards[name];
|
||||
} else {
|
||||
var board = new Board(name);
|
||||
var board = BoardData.load(name);
|
||||
boards[name] = board;
|
||||
return board;
|
||||
}
|
||||
|
@ -48,21 +40,15 @@ function socketConnection(socket) {
|
|||
// Default to the public board
|
||||
if (!name) name = "anonymous";
|
||||
|
||||
var board = getBoard(name);
|
||||
var board_data = board.data;
|
||||
|
||||
// Join the board
|
||||
socket.join(name);
|
||||
board.users.add(socket.id);
|
||||
console.log(board.users.size + " users in " + board.name);
|
||||
|
||||
//Send all the board's data as soon as it's loaded
|
||||
var sendIt = function () {
|
||||
socket.emit("broadcast", { _children: board_data.getAll() });
|
||||
};
|
||||
|
||||
if (board_data.ready) sendIt();
|
||||
else board_data.once("ready", sendIt);
|
||||
getBoard(name).then(board => {
|
||||
board.users.add(socket.id);
|
||||
console.log(board.users.size + " users in " + board.name);
|
||||
//Send all the board's data as soon as it's loaded
|
||||
socket.emit("broadcast", { _children: board.getAll() });
|
||||
});
|
||||
}));
|
||||
|
||||
var lastEmitSecond = Date.now() / MAX_EMIT_COUNT_PERIOD | 0;
|
||||
|
@ -105,13 +91,15 @@ function socketConnection(socket) {
|
|||
socket.on('disconnecting', function onDisconnecting(reason) {
|
||||
Object.keys(socket.rooms).forEach(function disconnectFrom(room) {
|
||||
if (boards.hasOwnProperty(room)) {
|
||||
boards[room].users.delete(socket.id);
|
||||
var userCount = boards[room].users.size;
|
||||
console.log(userCount + " users in " + room);
|
||||
if (userCount === 0) {
|
||||
boards[room].data.save();
|
||||
delete boards[room];
|
||||
}
|
||||
boards[room].then(board => {
|
||||
board.users.delete(socket.id);
|
||||
var userCount = board.users.size;
|
||||
console.log(userCount + " users in " + room);
|
||||
if (userCount === 0) {
|
||||
board.save();
|
||||
delete boards[room];
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -119,22 +107,23 @@ function socketConnection(socket) {
|
|||
|
||||
function saveHistory(boardName, message) {
|
||||
var id = message.id;
|
||||
var boardData = getBoard(boardName).data;
|
||||
switch (message.type) {
|
||||
case "delete":
|
||||
if (id) boardData.delete(id);
|
||||
break;
|
||||
case "update":
|
||||
delete message.type;
|
||||
if (id) boardData.update(id, message);
|
||||
break;
|
||||
case "child":
|
||||
boardData.addChild(message.parent, message);
|
||||
break;
|
||||
default: //Add data
|
||||
if (!id) throw new Error("Invalid message: ", message);
|
||||
boardData.set(id, message);
|
||||
}
|
||||
getBoard(boardName).then(board => {
|
||||
switch (message.type) {
|
||||
case "delete":
|
||||
if (id) board.delete(id);
|
||||
break;
|
||||
case "update":
|
||||
delete message.type;
|
||||
if (id) board.update(id, message);
|
||||
break;
|
||||
case "child":
|
||||
board.addChild(message.parent, message);
|
||||
break;
|
||||
default: //Add data
|
||||
if (!id) throw new Error("Invalid message: ", message);
|
||||
board.set(id, message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function generateUID(prefix, suffix) {
|
||||
|
@ -146,9 +135,5 @@ function generateUID(prefix, suffix) {
|
|||
}
|
||||
|
||||
if (exports) {
|
||||
exports.start = function (app) {
|
||||
getBoard("anonymous").data.on("ready", function () {
|
||||
startIO(app);
|
||||
});
|
||||
};
|
||||
exports.start = startIO;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue