1
0

State loading is working

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-01-27 14:15:40 -08:00
parent 72d3dcd157
commit 7885c094e1
2 changed files with 107 additions and 72 deletions

View File

@ -44,6 +44,7 @@ const base = process.env.PUBLIC_URL;
const assetsPath = `${base}/assets`; const assetsPath = `${base}/assets`;
const gamesPath = `${base}/games`; const gamesPath = `${base}/games`;
const images = {};
const useStyles = makeStyles((theme) => ({ const useStyles = makeStyles((theme) => ({
root: { root: {
@ -87,12 +88,29 @@ const hexagonRatio = 1.1547005,
angle: 0 angle: 0
} ]; } ];
const loadImage = (board, file) => {
if (file in images) {
return images[file];
}
const image = new Image();
images[file] = image;
image.addEventListener("load", board.imageLoaded);
image.addEventListener("error", board.imageLoadError);
image.src = `${assetsPath}/gfx/${file}`;
return image;
}
const Tiles = (board) => { const Tiles = (board) => {
const tiles = board.game.tiles; const tiles = board.game.tiles;
[ "robber", "brick", "wood", "sheep", "stone", "wheat" ].forEach((type) => { [ "robber", "brick", "wood", "sheep", "stone", "wheat" ].forEach((type) => {
const image = new Image(), const file = "tiles-" + type + ".png",
file = "tiles-" + type + ".png"; image = loadImage(board, file);
tiles.forEach((tile) => { tiles.forEach((tile) => {
if (tile.type === type) { if (tile.type === type) {
tile.image = image; tile.image = image;
@ -101,31 +119,14 @@ const Tiles = (board) => {
} }
tile.jitter = 0; tile.jitter = 0;
}); });
image.addEventListener("load", (event) => {
console.log(`Done loading ${file}`);
window.requestAnimationFrame(board.drawFrame);
});
image.addEventListener("error", (event) => {
this.setState({message: `Error loading ${file}`});
});
image.src = `${assetsPath}/gfx/${file}`;
}); });
return tiles; return tiles;
}; };
const Pips = (board) => { const Pips = (board) => {
const image = new Image(), const file = 'pip-numbers.png',
file = 'pip-numbers.png'; image = loadImage(board, file);
image.addEventListener("load", (event) => {
console.log(`Done loading ${file}`);
window.requestAnimationFrame(board.drawFrame);
});
image.addEventListener("error", (event) => {
this.setState({message: `Error loading ${file}`});
});
image.src = `${assetsPath}/gfx/${file}`;
return { return {
image: image, image: image,
@ -134,29 +135,17 @@ const Pips = (board) => {
}; };
const Border = (board, border) => { const Border = (board, border) => {
const image = new Image(), file = border.file const file = border.file,
image = loadImage(board, file);
border.image = image; border.image = image;
image.addEventListener("load", (event) => {
console.log(`Done loading ${file}`);
window.requestAnimationFrame(board.drawFrame);
});
image.addEventListener("error", (event) => {
board.setState({ message: `Error loading ${file}` });
});
image.src = `${assetsPath}/gfx/${file}`;
return border; return border;
}; };
const Table = (board) => { const Table = (board) => {
const image = new Image(), file = "table.png"; const file = "table.png",
image.addEventListener("load", (event) => { image = loadImage(board, file);
console.log(`Done loading ${file}`);
window.requestAnimationFrame(board.drawFrame);
});
image.addEventListener("error", (event) => {
board.setState({ message: `Error loading ${file}` });
});
image.src = `${assetsPath}/gfx/${file}`;
return image; return image;
}; };
@ -418,6 +407,9 @@ class Board extends React.Component {
this.rollDice = this.rollDice.bind(this); this.rollDice = this.rollDice.bind(this);
this.setGameState = this.setGameState.bind(this); this.setGameState = this.setGameState.bind(this);
this.shuffleBoard = this.shuffleBoard.bind(this); this.shuffleBoard = this.shuffleBoard.bind(this);
this.updateGame = this.updateGame.bind(this);
this.imageLoadError = this.imageLoadError.bind(this);
this.imageLoaded = this.imageLoaded.bind(this);
this.mouse = { x: 0, y: 0 }; this.mouse = { x: 0, y: 0 };
this.radius = 0.317; this.radius = 0.317;
@ -440,6 +432,15 @@ class Board extends React.Component {
this.id = (props.router && props.router.params.id) ? props.router.params.id : 0; this.id = (props.router && props.router.params.id) ? props.router.params.id : 0;
} }
imageLoaded(event) {
console.log(`Done loading ${event.target.src}`);
window.requestAnimationFrame(this.drawFrame);
}
imageLoadError(event) {
this.setState({message: `Error loading ${event.target.src}`});
}
shuffleBoard() { shuffleBoard() {
if (this.loadTimer) { if (this.loadTimer) {
window.clearTimeout(this.loadTimer); window.clearTimeout(this.loadTimer);
@ -460,15 +461,8 @@ class Board extends React.Component {
return res.json(); return res.json();
}).then((game) => { }).then((game) => {
console.log (`Board shuffled!`); console.log (`Board shuffled!`);
this.game = game; this.updateGame(game);
this.setState({ game: game, message: "" }); this.setState({ game: game, message: "Board shuffled!" });
this.pips = Pips(this);
this.tiles = Tiles(this);
this.table = Table(this);
this.borders = this.game.borders.map((file) => {
return Border(this, file);
});
}).catch((error) => { }).catch((error) => {
console.error(error); console.error(error);
this.setState({message: error.message}); this.setState({message: error.message});
@ -500,8 +494,8 @@ class Board extends React.Component {
}).then((game) => { }).then((game) => {
console.log (`Dice rolled!`); console.log (`Dice rolled!`);
console.log(game.dice); console.log(game.dice);
this.game = game; this.updateGame(game);
this.setState({ game: { ...this.state.game, dice: game.dice }, message: ""} ); this.setState({ game: { ...this.state.game, dice: game.dice }, message: "Dice rolled!"} );
}).catch((error) => { }).catch((error) => {
console.error(error); console.error(error);
this.setState({message: error.message}); this.setState({message: error.message});
@ -537,7 +531,7 @@ class Board extends React.Component {
return res.json(); return res.json();
}).then((game) => { }).then((game) => {
console.log (`Game ${game.id} loaded ${moment().format()}.`); console.log (`Game ${game.id} loaded ${moment().format()}.`);
this.game = game; this.updateGame(game);
this.setState({ game: game, message: "" }); this.setState({ game: game, message: "" });
}).catch((error) => { }).catch((error) => {
console.error(error); console.error(error);
@ -579,7 +573,7 @@ class Board extends React.Component {
return res.json(); return res.json();
}).then((game) => { }).then((game) => {
console.log (`Game state changed.`); console.log (`Game state changed.`);
this.game = game; this.updateGame(game);
this.setState({ game: game, message: "" }); this.setState({ game: game, message: "" });
}).catch((error) => { }).catch((error) => {
console.error(error); console.error(error);
@ -613,8 +607,8 @@ class Board extends React.Component {
return res.json(); return res.json();
}).then((game) => { }).then((game) => {
console.log (`Game state set to ${game.state}!`); console.log (`Game state set to ${game.state}!`);
this.game = game; this.updateGame(game);
this.setState({ game: { ...this.state.game, state: game.state }, message: ""} ); this.setState({ game: { ...this.state.game, state: game.state }, message: `Game state now ${game.state}.` });
}).catch((error) => { }).catch((error) => {
console.error(error); console.error(error);
this.setState({message: error.message}); this.setState({message: error.message});
@ -1144,6 +1138,20 @@ class Board extends React.Component {
}); });
} }
updateGame(game) {
this.game = game;
this.pips = Pips(this);
this.tiles = Tiles(this);
this.table = Table(this);
this.borders = this.game.borders.map((file) => {
return Border(this, file);
});
window.requestAnimationFrame(this.drawFrame);
}
componentDidMount() { componentDidMount() {
this.start = new Date(); this.start = new Date();
@ -1159,7 +1167,7 @@ class Board extends React.Component {
params.method = "GET" params.method = "GET"
} else { } else {
console.log("Requesting new game."); console.log("Requesting new game.");
params.url = `${base}/api/v1/games`; params.url = `${base}/api/v1/games/`;
params.method = "POST"; params.method = "POST";
} }
@ -1185,7 +1193,7 @@ class Board extends React.Component {
console.log(message); console.log(message);
this.setState({ message: message }); this.setState({ message: message });
params.url = `${base}/api/v1/games`; params.url = `${base}/api/v1/games/${this.id}`;
params.method = "POST"; params.method = "POST";
return window.fetch(params.url, { return window.fetch(params.url, {
@ -1205,16 +1213,8 @@ class Board extends React.Component {
history.push(`${gamesPath}/${game.id}`); history.push(`${gamesPath}/${game.id}`);
} }
this.game = game; this.updateGame(game);
this.setState({ game: game, message: "" }); this.setState({ game: game, message: "" });
this.pips = Pips(this);
this.tiles = Tiles(this);
this.table = Table(this);
this.borders = this.game.borders.map((file) => {
return Border(this, file);
});
}).catch((error) => { }).catch((error) => {
console.error(error); console.error(error);
this.setState({message: error.message}); this.setState({message: error.message});
@ -1233,6 +1233,13 @@ class Board extends React.Component {
clearTimeout(this.updateSizeTimer); clearTimeout(this.updateSizeTimer);
this.updateSizeTimer = 0; this.updateSizeTimer = 0;
} }
for (let image in images) {
image.removeEventListener("load", this.imageLoaded);
image.removeEventListener("error", this.imageLoadError);
delete images[image];
}
document.removeEventListener("keyup", this.keyUp); document.removeEventListener("keyup", this.keyUp);
window.removeEventListener("mousemove", this.mouseMove); window.removeEventListener("mousemove", this.mouseMove);
window.removeEventListener("touchmove", this.mouseMove); window.removeEventListener("touchmove", this.mouseMove);

View File

@ -5,7 +5,8 @@ const express = require("express"),
moment = require("moment"), moment = require("moment"),
crypto = require("crypto"), crypto = require("crypto"),
util = require("util"), util = require("util"),
Promise = require("bluebird"); Promise = require("bluebird"),
{ readFile, writeFile } = require("fs").promises;
let gameDB; let gameDB;
@ -164,14 +165,28 @@ router.put("/:id/:action/:value?", (req, res) => {
return sendGame(res, req, game); return sendGame(res, req, game);
}) })
router.get("/:id", (req, res/*, next*/) => { router.get("/:id", async (req, res/*, next*/) => {
console.log("GET games/" + req.params.id); console.log("GET games/" + req.params.id);
let error;
if (req.params.id in games) { if (req.params.id in games) {
const game = games[req.params.id]; const game = games[req.params.id];
return sendGame(res, req, game) return sendGame(res, req, game)
}
if (/^.|\//.exec(req.params.id)) {
error = `Requested game ID is invalid`;
return res.status(400).send(error);
}
const game = await readFile(`games/${req.params.id}`)
.catch(() => {
return null;
});
if (!game) {
error = `Unable to load game: ${req.params.id}`;
res.status(404).send(error);
} else { } else {
const error = `Game not found: ${req.params.id}`; games[req.params.id] = game;
return res.status(404).send(error); return sendGame(game);
} }
}); });
@ -222,7 +237,13 @@ router.put("/:id", (req, res/*, next*/) => {
} }
}); });
const sendGame = (res, req, game) => { const sendGame = async (res, req, game) => {
await writeFile(`games/${game.id}`, JSON.stringify(game, null, 2))
.catch((error) => {
console.error(`Unable to write to games/${games.id}`);
console.error(error);
});
return res.status(200).send(Object.assign({}, game, { return res.status(200).send(Object.assign({}, game, {
timestamp: Date.now(), timestamp: Date.now(),
activePlayer: (req.session && req.session.activePlayer) ? activePlayer: (req.session && req.session.activePlayer) ?
@ -230,8 +251,15 @@ const sendGame = (res, req, game) => {
})); }));
} }
router.post("/", (req, res/*, next*/) => { router.post("/:id?", (req, res/*, next*/) => {
console.log("POST games/"); console.log("POST games/");
const id = req.params.id;
if (id && id in games) {
const error = `Can not create new game for ${id} -- it already exists.`
console.error(error);
return res.status(400).send(error);
}
const game = { const game = {
startTime: Date.now(), startTime: Date.now(),
state: "lobby", /* lobby, in-game, finished */ state: "lobby", /* lobby, in-game, finished */
@ -255,7 +283,7 @@ router.post("/", (req, res/*, next*/) => {
longestRoad: null, longestRoad: null,
largestArmy: null, largestArmy: null,
chat: [ { from: "R", date: Date.now(), message: "Server initialized!" } ], chat: [ { from: "R", date: Date.now(), message: "Server initialized!" } ],
id: crypto.randomBytes(8).toString('hex') id: id ? id : crypto.randomBytes(8).toString('hex')
}; };
games[game.id] = game; games[game.id] = game;