Index: binaries/data/mods/public/gui/common/functions_utility.js =================================================================== --- binaries/data/mods/public/gui/common/functions_utility.js +++ binaries/data/mods/public/gui/common/functions_utility.js @@ -282,3 +282,25 @@ "revision": Engine.GetBuildRevision() }); } + +/** + * Openes a page. If that page completes with an object with a `nextPage` + * property that page is opened with the `args` property of that object. That + * continues untill there is no `nextPage` property in the completion value. + * If there is no `nextPage` in the completion value the `continuation` is + * called with the completion value. + * @param {String} page - The page first opened. + * @param args - passed to the first page opened. + * @param continuation {function | undefined} - Completion callback, called when + * there is no `nextPage` property in the completion value. + */ +function pageLoop(page, args, continuation) +{ + (function recursiveFunction(completionValue) + { + if (completionValue?.nextPage != null) + Engine.PushGuiPage(completionValue.nextPage, completionValue.args, recursiveFunction); + else + continuation?.(completionValue); + })({ "nextPage": page, "args": args }); +} Index: binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/Panels/Buttons/CivInfoButton.js =================================================================== --- binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/Panels/Buttons/CivInfoButton.js +++ binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/Panels/Buttons/CivInfoButton.js @@ -3,7 +3,6 @@ constructor() { this.civInfo = { - "civ": "", "page": "page_civinfo.xml" }; @@ -26,21 +25,7 @@ openPage(page) { - Engine.PushGuiPage( - page, - { "civ": this.civInfo.civ }, - this.storeCivInfoPage.bind(this)); - } - - storeCivInfoPage(data) - { - if (data.nextPage) - Engine.PushGuiPage( - data.nextPage, - { "civ": data.civ }, - this.storeCivInfoPage.bind(this)); - else - this.civInfo = data; + pageLoop(page, this.civInfo.args, data => this.civInfo = data); } } Index: binaries/data/mods/public/gui/pregame/MainMenuItems.js =================================================================== --- binaries/data/mods/public/gui/pregame/MainMenuItems.js +++ binaries/data/mods/public/gui/pregame/MainMenuItems.js @@ -36,25 +36,13 @@ "caption": translate("Structure Tree"), "tooltip": colorizeHotkey(translate("%(hotkey)s: View the structure tree of civilizations featured in 0 A.D."), "structree"), "hotkey": "structree", - "onPress": () => { - let callback = data => { - if (data.nextPage) - Engine.PushGuiPage(data.nextPage, { "civ": data.civ }, callback); - }; - Engine.PushGuiPage("page_structree.xml", {}, callback); - }, + "onPress": pageLoop.bind(null, "page_structree.xml") }, { "caption": translate("Civilization Overview"), "tooltip": colorizeHotkey(translate("%(hotkey)s: Learn about the civilizations featured in 0 A.D."), "civinfo"), "hotkey": "civinfo", - "onPress": () => { - let callback = data => { - if (data.nextPage) - Engine.PushGuiPage(data.nextPage, { "civ": data.civ }, callback); - }; - Engine.PushGuiPage("page_civinfo.xml", {}, callback); - } + "onPress": pageLoop.bind(null, "page_civinfo.xml") }, { "caption": translate("Catafalque Overview"), Index: binaries/data/mods/public/gui/reference/civinfo/CivInfoPage.js =================================================================== --- binaries/data/mods/public/gui/reference/civinfo/CivInfoPage.js +++ binaries/data/mods/public/gui/reference/civinfo/CivInfoPage.js @@ -17,12 +17,22 @@ switchToStructreePage() { - Engine.PopGuiPage({ "civ": this.activeCiv, "nextPage": "page_structree.xml" }); + Engine.PopGuiPage({ + "nextPage": "page_structree.xml", + "args": { + "civ": this.activeCiv + } + }); } closePage() { - Engine.PopGuiPage({ "civ": this.activeCiv, "page": "page_civinfo.xml" }); + Engine.PopGuiPage({ + "page": "page_civinfo.xml", + "args": { + "civ": this.activeCiv + } + }); } /** Index: binaries/data/mods/public/gui/reference/common/Buttons/CivInfoButton.js =================================================================== --- binaries/data/mods/public/gui/reference/common/Buttons/CivInfoButton.js +++ binaries/data/mods/public/gui/reference/common/Buttons/CivInfoButton.js @@ -12,7 +12,12 @@ onPress() { - Engine.PopGuiPage({ "civ": this.parentPage.activeCiv, "nextPage": "page_civinfo.xml" }); + Engine.PopGuiPage({ + "nextPage": "page_civinfo.xml", + "args": { + "civ": this.parentPage.activeCiv + } + }); } } Index: binaries/data/mods/public/gui/reference/common/Buttons/StructreeButton.js =================================================================== --- binaries/data/mods/public/gui/reference/common/Buttons/StructreeButton.js +++ binaries/data/mods/public/gui/reference/common/Buttons/StructreeButton.js @@ -12,7 +12,12 @@ onPress() { - Engine.PopGuiPage({ "civ": this.parentPage.activeCiv, "nextPage": "page_structree.xml" }); + Engine.PopGuiPage({ + "nextPage": "page_structree.xml", + "args": { + "civ": this.parentPage.activeCiv + } + }); } } Index: binaries/data/mods/public/gui/reference/structree/StructreePage.js =================================================================== --- binaries/data/mods/public/gui/reference/structree/StructreePage.js +++ binaries/data/mods/public/gui/reference/structree/StructreePage.js @@ -39,7 +39,12 @@ closePage() { - Engine.PopGuiPage({ "civ": this.activeCiv, "page": "page_structree.xml" }); + Engine.PopGuiPage({ + "page": "page_structree.xml", + "args": { + "civ": this.activeCiv + } + }); } selectCiv(civCode) Index: binaries/data/mods/public/gui/session/top_panel/CivIcon.js =================================================================== --- binaries/data/mods/public/gui/session/top_panel/CivIcon.js +++ binaries/data/mods/public/gui/session/top_panel/CivIcon.js @@ -7,7 +7,6 @@ constructor(playerViewControl) { this.dialogSelection = { - "civ": "", "page": "page_structree.xml" }; @@ -32,30 +31,20 @@ closeOpenDialogs(); g_PauseControl.implicitPause(); - Engine.PushGuiPage( + pageLoop( page, - { + this.dialogSelection.args ?? { // If an Observer triggers `openPage()` via hotkey, g_ViewedPlayer could be -1 or 0 // (depending on whether they're "viewing" no-one or gaia respectively) - "civ": this.dialogSelection.civ || g_Players[Math.max(g_ViewedPlayer, 1)].civ, + "civ": g_Players[Math.max(g_ViewedPlayer, 1)].civ, // TODO add info about researched techs and unlocked entities }, - this.storePageSelection.bind(this)); - } - - storePageSelection(data) - { - if (data.nextPage) - Engine.PushGuiPage( - data.nextPage, - { "civ": data.civ }, - this.storePageSelection.bind(this)); - else - { - this.dialogSelection = data; - resumeGame(); - } + data => + { + this.dialogSelection = data; + resumeGame(); + }); } rebuild()