mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Fix UI when connecting to a server fails
When the connection fails, it wasn't possible to close the progress window. Now `PollNetworkClient` also resolves the previous promise.
This commit is contained in:
parent
32e5520507
commit
a95579a046
8 changed files with 49 additions and 24 deletions
|
|
@ -32,6 +32,8 @@ class NetMessages
|
|||
while (true)
|
||||
{
|
||||
const message = await Engine.PollNetworkClient();
|
||||
if (!message)
|
||||
return;
|
||||
|
||||
log("Net message: " + uneval(message));
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,11 @@ function init(initData, hotloadData)
|
|||
return Promise.race([new Promise(closePageCallback =>
|
||||
{
|
||||
g_SetupWindow = new SetupWindow(initData, hotloadData, closePageCallback);
|
||||
}), ...(g_IsNetworked ? [g_SetupWindow.controls.netMessages.pollPendingMessages()] : [])]);
|
||||
}), new Promise((_, reject) =>
|
||||
{
|
||||
if (g_IsNetworked)
|
||||
g_SetupWindow.controls.netMessages.pollPendingMessages().catch(reject);
|
||||
})]);
|
||||
}
|
||||
|
||||
function getHotloadData()
|
||||
|
|
|
|||
|
|
@ -72,7 +72,9 @@ async function waitOnEvent(loadSavedGame, joinFromLobby)
|
|||
}));
|
||||
if (tickResult === cancelTag)
|
||||
break;
|
||||
const result = await onTick(loadSavedGame);
|
||||
const result = await cancelOr(onTick(loadSavedGame));
|
||||
if (result === cancelTag)
|
||||
break;
|
||||
if (typeof result === "object")
|
||||
return result;
|
||||
if (result)
|
||||
|
|
@ -240,7 +242,7 @@ function getConnectionFailReason(reason)
|
|||
|
||||
function reportConnectionFail(reason)
|
||||
{
|
||||
messageBox(
|
||||
return messageBox(
|
||||
400, 200,
|
||||
(translate("Failed to connect to the server.")
|
||||
) + "\n\n" + getConnectionFailReason(reason),
|
||||
|
|
@ -253,6 +255,8 @@ async function pollAndHandleNetworkClient(loadSavedGame)
|
|||
while (true)
|
||||
{
|
||||
const message = await Engine.PollNetworkClient();
|
||||
if (!message)
|
||||
return true;
|
||||
if (!g_IsConnecting)
|
||||
continue;
|
||||
|
||||
|
|
@ -268,7 +272,7 @@ async function pollAndHandleNetworkClient(loadSavedGame)
|
|||
switch (message.status)
|
||||
{
|
||||
case "failed":
|
||||
reportConnectionFail(message.reason, false);
|
||||
await reportConnectionFail(message.reason, false);
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
|
@ -326,7 +330,7 @@ async function pollAndHandleNetworkClient(loadSavedGame)
|
|||
switch (message.status)
|
||||
{
|
||||
case "failed":
|
||||
reportConnectionFail(message.reason, false);
|
||||
await reportConnectionFail(message.reason, false);
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -425,6 +425,8 @@ async function handleNetMessages()
|
|||
while (true)
|
||||
{
|
||||
const msg = await Engine.PollNetworkClient();
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
log("Net message: " + uneval(msg));
|
||||
|
||||
|
|
|
|||
|
|
@ -331,20 +331,23 @@ async function init(initData, hotloadData)
|
|||
resumeGame();
|
||||
});
|
||||
|
||||
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);
|
||||
})]);
|
||||
const promise = Promise.race([new Promise((_, reject) =>
|
||||
{
|
||||
if (g_IsNetworked)
|
||||
handleNetMessages().catch(reject);
|
||||
}), 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();
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ CGUI::CGUI(ScriptContext& context)
|
|||
CGUI::~CGUI()
|
||||
{
|
||||
if (g_NetClient)
|
||||
g_NetClient->Unregister(*m_ScriptInterface);
|
||||
g_NetClient->Unregister(m_ScriptInterface.get());
|
||||
}
|
||||
|
||||
InReaction CGUI::HandleEvent(const SDL_Event_* ev)
|
||||
|
|
|
|||
|
|
@ -159,6 +159,8 @@ CNetClient::CNetClient(CGame* game, const CStrW& username, const CStr& hostJID,
|
|||
|
||||
CNetClient::~CNetClient()
|
||||
{
|
||||
Unregister(nullptr);
|
||||
|
||||
// Try to flush messages before dying (probably fails).
|
||||
if (m_ClientTurnManager)
|
||||
m_ClientTurnManager->OnDestroyConnection();
|
||||
|
|
@ -364,6 +366,7 @@ void CNetClient::CheckServerConnection()
|
|||
|
||||
JSObject* CNetClient::GetNextGUIMessage(const ScriptInterface& guiInterface)
|
||||
{
|
||||
Unregister(nullptr);
|
||||
const ScriptRequest rq{guiInterface};
|
||||
m_GuiMessagePoll.emplace(GuiPollData{guiInterface, {rq.cx, JS::NewPromiseObject(rq.cx, nullptr)}});
|
||||
|
||||
|
|
@ -371,10 +374,17 @@ JSObject* CNetClient::GetNextGUIMessage(const ScriptInterface& guiInterface)
|
|||
return m_GuiMessagePoll.value().promise;
|
||||
}
|
||||
|
||||
void CNetClient::Unregister(const ScriptInterface& guiInterface)
|
||||
void CNetClient::Unregister(const ScriptInterface* guiInterface)
|
||||
{
|
||||
if (m_GuiMessagePoll.has_value() && &m_GuiMessagePoll.value().interface == &guiInterface)
|
||||
m_GuiMessagePoll.reset();
|
||||
if (!m_GuiMessagePoll.has_value() ||
|
||||
(guiInterface && &m_GuiMessagePoll.value().interface != guiInterface))
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto& [interface, promise] = m_GuiMessagePoll.value();
|
||||
const ScriptRequest oldRq{interface};
|
||||
JS::ResolvePromise(oldRq.cx, promise, JS::UndefinedHandleValue);
|
||||
m_GuiMessagePoll.reset();
|
||||
}
|
||||
|
||||
void CNetClient::FetchMessage()
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ public:
|
|||
* Has to be called bevore the @c ScriptInterface gets destroied so that
|
||||
* no future messages are sent to it.
|
||||
*/
|
||||
void Unregister(const ScriptInterface& guiInterface);
|
||||
void Unregister(const ScriptInterface* guiInterface);
|
||||
|
||||
/**
|
||||
* Add a message to the queue, to be read by GuiPoll.
|
||||
|
|
|
|||
Loading…
Reference in a new issue