diff --git a/binaries/data/mods/public/gui/session/Menu.js b/binaries/data/mods/public/gui/session/Menu.js index 628fcc6a60..47c58d4fe4 100644 --- a/binaries/data/mods/public/gui/session/Menu.js +++ b/binaries/data/mods/public/gui/session/Menu.js @@ -3,7 +3,7 @@ */ class Menu { - constructor(pauseControl, playerViewControl, chat) + constructor(pauseControl, playerViewControl, chat, closePageCallback) { this.menuButton = Engine.GetGUIObjectByName("menuButton"); this.menuButton.onPress = this.toggle.bind(this); @@ -26,7 +26,7 @@ class Menu this.buttons = handlerNames.map((handlerName, i) => { const handler = new MenuButtons.prototype[handlerName](menuButtons[i], pauseControl, playerViewControl, chat); - this.initButton(handler, menuButtons[i], i); + this.initButton(handler, menuButtons[i], i, closePageCallback); return handler; }); @@ -62,12 +62,12 @@ class Menu this.startAnimation(); } - initButton(handler, button, i) + initButton(handler, button, i, closePageCallback) { button.onPress = () => { this.close(); - handler.onPress(); + handler.onPress(closePageCallback); }; button.size.top = this.buttonHeight * (i + 1) + this.margin; button.size.bottom = this.buttonHeight * (i + 2); diff --git a/binaries/data/mods/public/gui/session/MenuButtons.js b/binaries/data/mods/public/gui/session/MenuButtons.js index 731ac8aff2..c792a405c3 100644 --- a/binaries/data/mods/public/gui/session/MenuButtons.js +++ b/binaries/data/mods/public/gui/session/MenuButtons.js @@ -256,13 +256,13 @@ MenuButtons.prototype.Exit = class this.pauseControl = pauseControl; } - onPress() + onPress(closePageCallback) { for (const name in QuitConfirmationMenu.prototype) { const quitConfirmation = new QuitConfirmationMenu.prototype[name](); if (quitConfirmation.enabled()) - quitConfirmation.display(); + quitConfirmation.display(closePageCallback); } } }; diff --git a/binaries/data/mods/public/gui/session/NetworkStatusOverlay.js b/binaries/data/mods/public/gui/session/NetworkStatusOverlay.js index c0c930d7f3..223d0660e7 100644 --- a/binaries/data/mods/public/gui/session/NetworkStatusOverlay.js +++ b/binaries/data/mods/public/gui/session/NetworkStatusOverlay.js @@ -4,12 +4,15 @@ */ class NetworkStatusOverlay { - constructor() + constructor(closePageCallback) { this.netStatus = Engine.GetGUIObjectByName("netStatus"); this.loadingClientsText = Engine.GetGUIObjectByName("loadingClientsText"); - Engine.GetGUIObjectByName("disconnectedExitButton").onPress = () => { endGame(true); }; + Engine.GetGUIObjectByName("disconnectedExitButton").onPress = () => + { + closePageCallback({ [Engine.openRequest]: endGame(true) }); + }; registerNetworkStatusChangeHandler(this.onNetStatusMessage.bind(this)); registerClientsLoadingHandler(this.onClientsLoadingMessage.bind(this)); diff --git a/binaries/data/mods/public/gui/session/SessionMessageBox.js b/binaries/data/mods/public/gui/session/SessionMessageBox.js index 9d17a80632..c39689868e 100644 --- a/binaries/data/mods/public/gui/session/SessionMessageBox.js +++ b/binaries/data/mods/public/gui/session/SessionMessageBox.js @@ -4,7 +4,7 @@ */ class SessionMessageBox { - async display() + async display(closePageCallback) { closeOpenDialogs(); g_PauseControl.implicitPause(); @@ -20,7 +20,11 @@ class SessionMessageBox }); if (this.Buttons && this.Buttons[buttonId].onPress) - this.Buttons[buttonId].onPress.call(this); + { + const ret = this.Buttons[buttonId].onPress.call(this); + if (ret !== undefined) + closePageCallback({ [Engine.openRequest]: ret }); + } if (this.ResumeOnClose) resumeGame(); diff --git a/binaries/data/mods/public/gui/session/message_box/QuitConfirmation.js b/binaries/data/mods/public/gui/session/message_box/QuitConfirmation.js index 0879b175f5..9b0e60acc0 100644 --- a/binaries/data/mods/public/gui/session/message_box/QuitConfirmation.js +++ b/binaries/data/mods/public/gui/session/message_box/QuitConfirmation.js @@ -18,12 +18,12 @@ QuitConfirmation.prototype.Buttons = { // Translation: Shown in the Dialog that shows up when the game finishes "caption": translate("Quit and View Summary"), - "onPress": () => { endGame(true); } + "onPress": () => endGame(true) }, { // Translation: Shown in the Dialog that shows up when the game finishes "caption": translate("Quit"), - "onPress": () => { endGame(false); } + "onPress": () => endGame(false) } ]; @@ -31,3 +31,4 @@ QuitConfirmation.prototype.Width = 600; QuitConfirmation.prototype.Height = 200; QuitConfirmation.prototype.ResumeOnClose = false; + diff --git a/binaries/data/mods/public/gui/session/message_box/QuitConfirmationDefeat.js b/binaries/data/mods/public/gui/session/message_box/QuitConfirmationDefeat.js index 40713a9614..afb9ed9145 100644 --- a/binaries/data/mods/public/gui/session/message_box/QuitConfirmationDefeat.js +++ b/binaries/data/mods/public/gui/session/message_box/QuitConfirmationDefeat.js @@ -3,7 +3,7 @@ */ class QuitConfirmationDefeat extends QuitConfirmation { - constructor() + constructor(closePageCallback) { super(); @@ -11,10 +11,10 @@ class QuitConfirmationDefeat extends QuitConfirmation return; this.confirmHandler = undefined; - registerPlayersFinishedHandler(this.onPlayersFinished.bind(this)); + registerPlayersFinishedHandler(this.onPlayersFinished.bind(this, closePageCallback)); } - onPlayersFinished(players, won) + onPlayersFinished(closePageCallback, players, won) { if (players.indexOf(Engine.GetPlayerID()) == -1) return; @@ -22,11 +22,11 @@ class QuitConfirmationDefeat extends QuitConfirmation // Defer simulation result until // 1. the loading screen finished for all networked clients (g_IsNetworkedActive) // 2. all messages modifying g_Players victory state were processed (next turn) - this.confirmHandler = this.confirmExit.bind(this, won); + this.confirmHandler = this.confirmExit.bind(this, won, closePageCallback); registerSimulationUpdateHandler(this.confirmHandler); } - confirmExit(won) + confirmExit(won, closePageCallback) { if (g_IsNetworked && !g_IsNetworkedActive) return; @@ -47,7 +47,7 @@ class QuitConfirmationDefeat extends QuitConfirmation this.Buttons = askExit ? super.Buttons : undefined; - this.display(); + this.display(closePageCallback); } } diff --git a/binaries/data/mods/public/gui/session/message_box/QuitConfirmationMenu.js b/binaries/data/mods/public/gui/session/message_box/QuitConfirmationMenu.js index 9be8307cc1..92efb80c44 100644 --- a/binaries/data/mods/public/gui/session/message_box/QuitConfirmationMenu.js +++ b/binaries/data/mods/public/gui/session/message_box/QuitConfirmationMenu.js @@ -6,7 +6,7 @@ ReturnQuestion.prototype.Caption = translate("Do you want to resign or will you ReturnQuestion.prototype.Buttons = [ { "caption": translate("I will return"), - "onPress": () => { endGame(false); } + "onPress": () => endGame(false) }, { "caption": translate("I resign"), @@ -74,9 +74,9 @@ QuitConfirmationMenu.prototype.MultiplayerClient.prototype.Buttons = }, { "caption": translate("Yes"), - "onPress": () => + "onPress": closePageCallback => { - (new ReturnQuestion()).display(); + (new ReturnQuestion()).display(closePageCallback); } } ]; diff --git a/binaries/data/mods/public/gui/session/message_box/QuitConfirmationReplay.js b/binaries/data/mods/public/gui/session/message_box/QuitConfirmationReplay.js index 189555539d..b629a8857b 100644 --- a/binaries/data/mods/public/gui/session/message_box/QuitConfirmationReplay.js +++ b/binaries/data/mods/public/gui/session/message_box/QuitConfirmationReplay.js @@ -3,10 +3,10 @@ */ class QuitConfirmationReplay extends QuitConfirmation { - constructor() + constructor(closePageCallback) { super(); - Engine.GetGUIObjectByName("session").onReplayFinished = this.display.bind(this); + Engine.GetGUIObjectByName("session").onReplayFinished = this.display.bind(this, closePageCallback); } } @@ -26,11 +26,11 @@ QuitConfirmationReplay.prototype.Buttons = { // Translation: Shown in the Dialog that shows up when a replay finishes "caption": translate("Quit and View Summary"), - "onPress": () => { endGame(true); } + "onPress": () => endGame(true) }, { // Translation: Shown in the Dialog that shows up when a replay finishes "caption": translate("Quit"), - "onPress": () => { endGame(false); } + "onPress": () => endGame(false) } ]; diff --git a/binaries/data/mods/public/gui/session/messages.js b/binaries/data/mods/public/gui/session/messages.js index 6c1a3bffb3..7e23066702 100644 --- a/binaries/data/mods/public/gui/session/messages.js +++ b/binaries/data/mods/public/gui/session/messages.js @@ -335,7 +335,7 @@ function findGuidForPlayerID(playerID) /** * Processes all pending notifications sent from the GUIInterface simulation component. */ -function handleNotifications() +function handleNotifications(closePageCallback) { for (const notification of Engine.GuiInterfaceCall("GetNotifications")) { @@ -346,7 +346,7 @@ function handleNotifications() } for (const player of notification.players) - g_NotificationsTypes[notification.type](notification, player); + g_NotificationsTypes[notification.type](notification, player, closePageCallback); } } @@ -374,7 +374,7 @@ function toggleTutorial() /** * Updates the tutorial panel when a new goal. */ -function updateTutorial(notification) +function updateTutorial(notification, closePageCallback) { // Show the tutorial panel if not yet done Engine.GetGUIObjectByName("tutorialPanel").hidden = false; @@ -400,7 +400,11 @@ function updateTutorial(notification) { Engine.GetGUIObjectByName("tutorialWarning").caption = translate("Click to quit this tutorial."); Engine.GetGUIObjectByName("tutorialReady").caption = translate("Quit"); - Engine.GetGUIObjectByName("tutorialReady").onPress = () => { endGame(true); }; + + Engine.GetGUIObjectByName("tutorialReady").onPress = () => + { + closePageCallback({ [Engine.openRequest]: endGame(true) }); + }; } else Engine.GetGUIObjectByName("tutorialWarning").caption = translate("Click when ready."); diff --git a/binaries/data/mods/public/gui/session/session.js b/binaries/data/mods/public/gui/session/session.js index afb7491080..bb55f305f7 100644 --- a/binaries/data/mods/public/gui/session/session.js +++ b/binaries/data/mods/public/gui/session/session.js @@ -252,13 +252,12 @@ function GetTechnologyData(technologyName, civ) return g_TechnologyData[civ][technologyName]; } -function init(initData, hotloadData) +async function init(initData, hotloadData) { if (!g_Settings) { Engine.EndGame(); - Engine.SwitchGuiPage("page_pregame.xml"); - return undefined; + return { [Engine.openRequest]: { "page": "page_pregame.xml" } }; } // Fallback used by atlas @@ -289,8 +288,6 @@ function init(initData, hotloadData) g_DiplomacyColors.registerDiplomacyColorsChangeHandler(updateGUIObjects); g_PauseControl = new PauseControl(); g_PlayerViewControl.registerPreViewedPlayerChangeHandler(removeStatusBarDisplay); - g_PlayerViewControl.registerViewedPlayerChangeHandler(resetTemplates); - g_Ambient = new Ambient(); g_AutoFormation = new AutoFormation(); g_Chat = new Chat(g_PlayerViewControl, g_Cheats); @@ -299,16 +296,12 @@ function init(initData, hotloadData) g_DiplomacyDialog = new DiplomacyDialog(g_PlayerViewControl, g_DiplomacyColors); g_GameSpeedControl = new GameSpeedControl(g_PlayerViewControl); g_MatchSettingsDialog = new MatchSettingsDialog(g_PlayerViewControl, mapCache); - g_Menu = new Menu(g_PauseControl, g_PlayerViewControl, g_Chat); g_MiniMapPanel = new MiniMapPanel(g_PlayerViewControl, g_DiplomacyColors, g_WorkerTypes); - g_NetworkStatusOverlay = new NetworkStatusOverlay(); g_NetworkDelayOverlay = new NetworkDelayOverlay(); g_OutOfSyncNetwork = new OutOfSyncNetwork(); g_OutOfSyncReplay = new OutOfSyncReplay(); g_PanelEntityManager = new PanelEntityManager(g_PlayerViewControl, g_Selection, g_PanelEntityOrder); g_PauseOverlay = new PauseOverlay(g_PauseControl); - g_QuitConfirmationDefeat = new QuitConfirmationDefeat(); - g_QuitConfirmationReplay = new QuitConfirmationReplay(); g_RangeOverlayManager = new RangeOverlayManager(g_Selection); g_ResearchProgress = new ResearchProgress(g_PlayerViewControl, g_Selection); g_TradeDialog = new TradeDialog(g_PlayerViewControl); @@ -324,6 +317,21 @@ function init(initData, hotloadData) initializeMusic(); // before changing the perspective Engine.SetBoundingBoxDebugOverlay(false); + const promise = Promise.race([g_IsNetworked ? handleNetMessages() : new Promise(() => {}), + new Promise(closePageCallback => + { + g_PlayerViewControl.registerViewedPlayerChangeHandler(resetTemplates.bind(undefined, + closePageCallback)); + g_Menu = new Menu(g_PauseControl, g_PlayerViewControl, g_Chat, closePageCallback); + g_NetworkStatusOverlay = new NetworkStatusOverlay(closePageCallback); + g_QuitConfirmationDefeat = new QuitConfirmationDefeat(closePageCallback); + g_QuitConfirmationReplay = new QuitConfirmationReplay(closePageCallback); + // TODO: use event instead + onSimulationUpdate(closePageCallback); + Engine.GetGUIObjectByName("session").onSimulationUpdate = + onSimulationUpdate.bind(undefined, closePageCallback); + })]); + for (const handler of g_PlayersInitHandlers) handler(); @@ -337,12 +345,9 @@ function init(initData, hotloadData) g_Players = hotloadData.player; } - // TODO: use event instead - onSimulationUpdate(); - setTimeout(displayGamestateNotifications, 1000); - return g_IsNetworked ? handleNetMessages() : new Promise(() => {}); + return promise; } function registerPlayersInitHandler(handler) @@ -448,14 +453,14 @@ function initializeMusic() global.music.setState(global.music.states.PEACE); } -function resetTemplates() +function resetTemplates(closePageCallback) { // Update GUI and clear player-dependent cache g_TemplateData = {}; Engine.GuiInterfaceCall("ResetTemplateModified"); // TODO: do this more selectively - onSimulationUpdate(); + onSimulationUpdate(closePageCallback); } /** @@ -560,23 +565,22 @@ function endGame(showSummary) const menu = g_CampaignSession.getMenu(); if (g_InitAttributes.campaignData.skipSummary) { - Engine.SwitchGuiPage(menu); - return; + return { "page": menu }; } summaryData.campaignData = { "filename": g_InitAttributes.campaignData.run }; summaryData.nextPage = menu; } if (showSummary) - Engine.SwitchGuiPage("page_summary.xml", summaryData); - else if (g_InitAttributes.campaignData) - Engine.SwitchGuiPage(summaryData.nextPage, summaryData.campaignData); - else if (Engine.HasXmppClient()) - Engine.SwitchGuiPage("page_lobby.xml", { "dialog": false }); - else if (g_IsReplay) - Engine.SwitchGuiPage("page_replaymenu.xml"); - else - Engine.SwitchGuiPage("page_pregame.xml"); + return { "page": "page_summary.xml", "argument": summaryData }; + if (g_InitAttributes.campaignData) + return { "page": summaryData.nextPage, "argument": summaryData.campaignData }; + if (Engine.HasXmppClient()) + return { "page": "page_lobby.xml", "argument": { "dialog": false } }; + if (g_IsReplay) + return { "page": "page_replaymenu.xml" }; + + return { "page": "page_pregame.xml" }; } // Return some data that we'll use when hotloading this file after changes @@ -654,7 +658,7 @@ function onTick() Engine.GuiInterfaceCall("ClearRenamedEntities"); } -function onSimulationUpdate() +function onSimulationUpdate(closePageCallback) { // Templates change depending on technologies and auras, so they have to be reloaded after such a change. // g_TechnologyData data never changes, so it shouldn't be deleted. @@ -682,7 +686,7 @@ function onSimulationUpdate() handler(); // TODO: Move to handlers - handleNotifications(); + handleNotifications(closePageCallback); updateGUIObjects(); } diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml index 14c829fdfb..9187560b50 100644 --- a/binaries/data/mods/public/gui/session/session.xml +++ b/binaries/data/mods/public/gui/session/session.xml @@ -31,10 +31,6 @@ restoreSavedGameData(arguments[0]); - - onSimulationUpdate(); - -