diff --git a/js/GUI/Screen/Game.js b/js/GUI/Screen/Game.js index f7a9b88..9fa4866 100644 --- a/js/GUI/Screen/Game.js +++ b/js/GUI/Screen/Game.js @@ -27,11 +27,11 @@ function init(gameID) { initMessageHandlers(); Async.run( Async.bind( - getSavedMessages(gameID), - function(messages) { + getSavedStates(gameID), + function(states) { return Async.sequence( startSession(), - previously(messages) + previously(states) ); } ) @@ -51,9 +51,9 @@ function fail(errorCode) { } } -function getSavedMessages(gameID) { - var messages = Save.get('games.message.Game#' + gameID); - return messages != undefined ? Async.wrap(messages) : fail('gameNotFound'); +function getSavedStates(gameID) { + var states = Save.get('games.message.Game#' + gameID); + return states != undefined ? Async.wrap(states) : fail('gameNotFound'); } function startSession() { @@ -66,21 +66,21 @@ function startSession() { } } -function previously(messages) { - if(messages.former != undefined && messages.latest.logs.length > 0) { +function previously(states) { + if(states.former != undefined && states.latest.logs.length > 0) { return Async.sequence( - setGame(messages.former), - handleGameMessage(messages.latest) + setGame(states.former), + handleGameMessage(states.latest) ); } else { - return setGame(messages.latest); + return setGame(states.latest); } } function initMessageHandlers() { window.addEventListener('focus', catchUp); Messaging.addEventListener(["Game"], function(o) { - delay(handleGameMessage(o)); + delay(handleGameMessage(o.state)); if(document.hasFocus() && getQueue().length == 1) { catchUp(); } else { @@ -89,54 +89,54 @@ function initMessageHandlers() { }); } -function handleGameMessage(o) { - if(o.state.public.coordinates.turn == 0) { - if(o.logs.length > 0) { // but still some logs, from the previous round - return Async.sequence(applyDiff(o), setGame(o)); // so play the diff, then set the new round +function handleGameMessage(state) { + if(state.public.coordinates.turn == 0) { + if(state.logs.length > 0) { // but still some logs, from the previous round + return Async.sequence(applyDiff(state), setGame(state)); // so play the diff, then set the new round } else { - return setGame(o); // directly set a whole new game + return setGame(state); // directly set a whole new game } } else { - return applyDiff(o); + return applyDiff(state); } } -function setGame(o) { +function setGame(state) { return function(f) { - setStatus(o.state); - setCaptures(o.state); + setStatus(state); + setCaptures(state); [ - [sets.river, o.state.public.river, RiverCard.make], - [sets.you.hand, o.state.playerHand, HandCard.make] + [sets.river, state.public.river, RiverCard.make], + [sets.you.hand, state.playerHand, HandCard.make] ].forEach(function(args) {setCardSet.apply(null, args)}); - setTheirCards(o.state); - handleStep(o)(f); + setTheirCards(state); + handleStep(state)(f); }; } -function handleStep(o) { +function handleStep(state) { return function(f) { - handleTurnedCard(o, f); + handleTurnedCard(state, f); if(state.step == "Scored") { if(state.playing) { - askKoikoi(o, f); + askKoikoi(state, f); } else { - theyScored(o, f); + theyScored(state, f); } } else if (state.step == "Over") { - gameEnd(o, f); + gameEnd(state, f); } else { f(); } }; } -function handleTurnedCard(o, f) { +function handleTurnedCard(state, f) { if(state.step == "Turned") { - setTurned(o.state.public.step.contents); + setTurned(state.public.step.contents); } else { - if(state.step == "ToPlay" && o.state.public.playing == o.state.public.oyake) { - rest.className = ["card", "turn" + o.state.public.coordinates.turn].join(' '); + if(state.step == "ToPlay" && state.public.playing == state.public.oyake) { + rest.className = ["card", "turn" + state.public.coordinates.turn].join(' '); } if(deck.lastChild.id != "rest") { deck.removeChild(deck.lastChild); @@ -144,7 +144,7 @@ function handleTurnedCard(o, f) { } } -function askKoikoi(o, f) { +function askKoikoi(state, f) { Screen.dialog({ text: I18n.get('youScored'), answers: [ @@ -154,21 +154,21 @@ function askKoikoi(o, f) { }); } -function theyScored(o, f) { +function theyScored(state, f) { Screen.dialog({ - text: I18n.get('theyScored')(players.get(o.state.public.playing)), + text: I18n.get('theyScored')(players.get(state.public.playing)), answers: [ {label: 'ok', action: f} ] }); } -function gameEnd(o, f) { +function gameEnd(state, f) { var winner, maxScore; - for(var key in o.state.public.scores) { - if(maxScore == undefined || o.state.public.scores[key] > maxScore) { + for(var key in state.public.scores) { + if(maxScore == undefined || state.public.scores[key] > maxScore) { winner = key; - maxScore = o.state.public.scores[key]; + maxScore = state.public.scores[key]; } } Screen.dialog({ @@ -177,11 +177,11 @@ function gameEnd(o, f) { }); } -function applyDiff(o) { +function applyDiff(state) { return Async.sequence.apply(null, - o.logs.map(animate).concat( - Async.apply(setStatus, o.state), - handleStep(o) + state.logs.map(animate).concat( + Async.apply(setStatus, state), + handleStep(state) ) ); } diff --git a/js/Games.js b/js/Games.js index bc243cc..b3b6e29 100644 --- a/js/Games.js +++ b/js/Games.js @@ -39,12 +39,43 @@ function pushMessage(gameID, message) { Save.set(latestPath, message); } +function compare(gameCoordinatesA, gameCoordinatesB) { + if(gameCoordinatesA.month < gameCoordinatesB.month) { + return -1; + } else if(gameCoordinatesA.month > gameCoordinatesB.month) { + return 1; + } else if(gameCoordinatesA.turn < gameCoordinatesB.turn) { + return -1; + } else if(gameCoordinatesA.turn > gameCoordinatesB.turn) { + return 1; + } else { + return 0; + } +} + function initMessageHandlers() { Messaging.addEventListener(["Game"], function(o) { var gameID = o.state.public.coordinates.gameID; var entry = makeEntry(o.state); - pushMessage(gameID, o); + pushMessage(gameID, o.state); Save.set("games.entry." + gameID, entry); entries.insert(gameID, entry); }); + + Messaging.addEventListener(["Relay", "Sync"], function(o) { + var gameID = o.message.latestKnown.gameID; + var latestKnownHere = Save.get("games.message." + gameID + ".latest"); + switch(compare(latestKnownHere, o.message.latestKnown)) { + case -1: Messaging.send({tag: "Yield", onGameID: gameID}); + case 1: Messaging.send({tag: "Sync", latestKnown: latestKnownHere}); + } + }); + + Messaging.addEventListener(["Relay", "Yield"], function(o) { + var gameID = o.message.latestKnown.gameID; + var latestKnownHere = Save.get("games.message." + gameID + ".latest"); + if(o.from == latestKnownHere.public.nextPlayer[Session.getKey()]) { + Messaging.send({tag: "Share", gameSave: latestKnownHere}); + } + }); }