Enable buttons for current game when receiving server response (#4737)
* Enable buttons for current game when receiving server response Previously, upon joining a game, we were unconditionally re-enabling the "Join" button in the lobby, even if it was not enabled in the first place, causing #4698. This could also lead to issues where if the user selects a different game after joining (which they can do in case of e.g. network connectivity issues), the "Join as spectator" button could get incorrectly disabled. This fixes #4698 by re-enabling the buttons based on the state of the currently selected game at the time the response is received. This also avoids inconsistencies if a different game has been selected in between joining and receiving a response from the server. * Typo: enable gameButton in enableButtons The "create game" button was incorrectly being disabled in enableButtons whereas (as the name indicates) it should have been enabled * Remove misleading comment about race conditions
This commit is contained in:
parent
44d1ab348b
commit
00c9efe541
2 changed files with 44 additions and 14 deletions
|
@ -198,9 +198,19 @@ void GameSelector::actCreate()
|
||||||
|
|
||||||
void GameSelector::checkResponse(const Response &response)
|
void GameSelector::checkResponse(const Response &response)
|
||||||
{
|
{
|
||||||
if (createButton)
|
// NB: We re-enable buttons for the currently selected game, which may not
|
||||||
createButton->setEnabled(true);
|
// be the same game as the one for which we are processing a response.
|
||||||
joinButton->setEnabled(true);
|
// This could lead to situations where we join a game, select a different
|
||||||
|
// game, join the new game, then receive the response for the original
|
||||||
|
// join, which would re-activate the buttons for the second game too soon.
|
||||||
|
// However, that is better than doing things the other ways, because then
|
||||||
|
// the response to the first game could lock us out of join/join as
|
||||||
|
// spectator for the second game!
|
||||||
|
//
|
||||||
|
// Ideally we should have a way to figure out if the current game is the
|
||||||
|
// same as the one we are getting a response for, but it's probably not
|
||||||
|
// worth the trouble.
|
||||||
|
enableButtons();
|
||||||
|
|
||||||
switch (response.response_code()) {
|
switch (response.response_code()) {
|
||||||
case Response::RespNotInRoom:
|
case Response::RespNotInRoom:
|
||||||
|
@ -229,9 +239,6 @@ void GameSelector::checkResponse(const Response &response)
|
||||||
break;
|
break;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.response_code() != Response::RespSpectatorsNotAllowed)
|
|
||||||
spectateButton->setEnabled(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameSelector::actJoin()
|
void GameSelector::actJoin()
|
||||||
|
@ -270,12 +277,39 @@ void GameSelector::actJoin()
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(checkResponse(Response)));
|
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(checkResponse(Response)));
|
||||||
r->sendRoomCommand(pend);
|
r->sendRoomCommand(pend);
|
||||||
|
|
||||||
|
disableButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameSelector::disableButtons()
|
||||||
|
{
|
||||||
if (createButton)
|
if (createButton)
|
||||||
createButton->setEnabled(false);
|
createButton->setEnabled(false);
|
||||||
|
|
||||||
joinButton->setEnabled(false);
|
joinButton->setEnabled(false);
|
||||||
spectateButton->setEnabled(false);
|
spectateButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameSelector::enableButtons()
|
||||||
|
{
|
||||||
|
if (createButton)
|
||||||
|
createButton->setEnabled(true);
|
||||||
|
|
||||||
|
// Enable buttons for the currently selected game
|
||||||
|
enableButtonsForIndex(gameListView->currentIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameSelector::enableButtonsForIndex(const QModelIndex ¤t)
|
||||||
|
{
|
||||||
|
if (!current.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const ServerInfo_Game &game = gameListModel->getGame(current.data(Qt::UserRole).toInt());
|
||||||
|
bool overrideRestrictions = !tabSupervisor->getAdminLocked();
|
||||||
|
|
||||||
|
spectateButton->setEnabled(game.spectators_allowed() || overrideRestrictions);
|
||||||
|
joinButton->setEnabled(game.player_count() < game.max_players() || overrideRestrictions);
|
||||||
|
}
|
||||||
|
|
||||||
void GameSelector::retranslateUi()
|
void GameSelector::retranslateUi()
|
||||||
{
|
{
|
||||||
filterButton->setText(tr("&Filter games"));
|
filterButton->setText(tr("&Filter games"));
|
||||||
|
@ -296,14 +330,7 @@ void GameSelector::processGameInfo(const ServerInfo_Game &info)
|
||||||
|
|
||||||
void GameSelector::actSelectedGameChanged(const QModelIndex ¤t, const QModelIndex & /* previous */)
|
void GameSelector::actSelectedGameChanged(const QModelIndex ¤t, const QModelIndex & /* previous */)
|
||||||
{
|
{
|
||||||
if (!current.isValid())
|
enableButtonsForIndex(current);
|
||||||
return;
|
|
||||||
|
|
||||||
const ServerInfo_Game &game = gameListModel->getGame(current.data(Qt::UserRole).toInt());
|
|
||||||
bool overrideRestrictions = !tabSupervisor->getAdminLocked();
|
|
||||||
|
|
||||||
spectateButton->setEnabled(game.spectators_allowed() || overrideRestrictions);
|
|
||||||
joinButton->setEnabled(game.player_count() < game.max_players() || overrideRestrictions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameSelector::updateTitle()
|
void GameSelector::updateTitle()
|
||||||
|
|
|
@ -49,6 +49,9 @@ private:
|
||||||
GameTypeMap gameTypeMap;
|
GameTypeMap gameTypeMap;
|
||||||
|
|
||||||
void updateTitle();
|
void updateTitle();
|
||||||
|
void disableButtons();
|
||||||
|
void enableButtons();
|
||||||
|
void enableButtonsForIndex(const QModelIndex ¤t);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GameSelector(AbstractClient *_client,
|
GameSelector(AbstractClient *_client,
|
||||||
|
|
Loading…
Reference in a new issue