fix for rare condition when the game screen would remain white when the game starts

This commit is contained in:
Max-Wilhelm Bruker 2012-04-01 21:15:13 +02:00
parent 40fbbc5982
commit a319ce3afb
6 changed files with 24 additions and 21 deletions

View file

@ -44,7 +44,7 @@ AbstractClient::AbstractClient(QObject *parent)
qRegisterMetaType<QList<ServerInfo_User> >("QList<ServerInfo_User>"); qRegisterMetaType<QList<ServerInfo_User> >("QList<ServerInfo_User>");
qRegisterMetaType<Event_ReplayAdded>("Event_ReplayAdded"); qRegisterMetaType<Event_ReplayAdded>("Event_ReplayAdded");
connect(this, SIGNAL(sigSendCommandContainer(CommandContainer)), this, SLOT(sendCommandContainer(CommandContainer))); connect(this, SIGNAL(sigQueuePendingCommand(PendingCommand *)), this, SLOT(queuePendingCommand(PendingCommand *)));
} }
AbstractClient::~AbstractClient() AbstractClient::~AbstractClient()
@ -58,12 +58,10 @@ void AbstractClient::processProtocolItem(const ServerMessage &item)
const Response &response = item.response(); const Response &response = item.response();
const int cmdId = response.cmd_id(); const int cmdId = response.cmd_id();
QMutexLocker locker(&clientMutex);
PendingCommand *pend = pendingCommands.value(cmdId, 0); PendingCommand *pend = pendingCommands.value(cmdId, 0);
if (!pend) if (!pend)
return; return;
pendingCommands.remove(cmdId); pendingCommands.remove(cmdId);
locker.unlock();
pend->processResponse(response); pend->processResponse(response);
pend->deleteLater(); pend->deleteLater();
@ -100,6 +98,7 @@ void AbstractClient::processProtocolItem(const ServerMessage &item)
void AbstractClient::setStatus(const ClientStatus _status) void AbstractClient::setStatus(const ClientStatus _status)
{ {
QMutexLocker locker(&clientMutex);
if (_status != status) { if (_status != status) {
status = _status; status = _status;
emit statusChanged(_status); emit statusChanged(_status);
@ -113,15 +112,19 @@ void AbstractClient::sendCommand(const CommandContainer &cont)
void AbstractClient::sendCommand(PendingCommand *pend) void AbstractClient::sendCommand(PendingCommand *pend)
{ {
pend->moveToThread(thread());
emit sigQueuePendingCommand(pend);
}
void AbstractClient::queuePendingCommand(PendingCommand *pend)
{
// This function is always called from the client thread via signal/slot.
const int cmdId = nextCmdId++; const int cmdId = nextCmdId++;
pend->getCommandContainer().set_cmd_id(cmdId); pend->getCommandContainer().set_cmd_id(cmdId);
pend->moveToThread(thread());
clientMutex.lock();
pendingCommands.insert(cmdId, pend); pendingCommands.insert(cmdId, pend);
clientMutex.unlock();
emit sigSendCommandContainer(pend->getCommandContainer()); sendCommandContainer(pend->getCommandContainer());
} }
PendingCommand *AbstractClient::prepareSessionCommand(const ::google::protobuf::Message &cmd) PendingCommand *AbstractClient::prepareSessionCommand(const ::google::protobuf::Message &cmd)

View file

@ -60,23 +60,25 @@ signals:
void ignoreListReceived(const QList<ServerInfo_User> &ignoreList); void ignoreListReceived(const QList<ServerInfo_User> &ignoreList);
void replayAddedEventReceived(const Event_ReplayAdded &event); void replayAddedEventReceived(const Event_ReplayAdded &event);
void sigSendCommandContainer(const CommandContainer &commandContainer); void sigQueuePendingCommand(PendingCommand *pend);
private: private:
int nextCmdId; int nextCmdId;
QMutex clientMutex; mutable QMutex clientMutex;
ClientStatus status;
private slots:
void queuePendingCommand(PendingCommand *pend);
protected slots: protected slots:
void processProtocolItem(const ServerMessage &item); void processProtocolItem(const ServerMessage &item);
virtual void sendCommandContainer(const CommandContainer &cont) = 0;
protected: protected:
QMap<int, PendingCommand *> pendingCommands; QMap<int, PendingCommand *> pendingCommands;
ClientStatus status;
QString userName, password; QString userName, password;
void setStatus(ClientStatus _status); void setStatus(ClientStatus _status);
virtual void sendCommandContainer(const CommandContainer &cont) = 0;
public: public:
AbstractClient(QObject *parent = 0); AbstractClient(QObject *parent = 0);
~AbstractClient(); ~AbstractClient();
ClientStatus getStatus() const { return status; } ClientStatus getStatus() const { QMutexLocker locker(&clientMutex); return status; }
void sendCommand(const CommandContainer &cont); void sendCommand(const CommandContainer &cont);
void sendCommand(PendingCommand *pend); void sendCommand(PendingCommand *pend);

View file

@ -13,11 +13,13 @@
#include <QGraphicsView> #include <QGraphicsView>
GameScene::GameScene(PhasesToolbar *_phasesToolbar, QObject *parent) GameScene::GameScene(PhasesToolbar *_phasesToolbar, QObject *parent)
: QGraphicsScene(parent), phasesToolbar(_phasesToolbar) : QGraphicsScene(parent), phasesToolbar(_phasesToolbar), viewSize(QSize())
{ {
animationTimer = new QBasicTimer; animationTimer = new QBasicTimer;
addItem(phasesToolbar); addItem(phasesToolbar);
connect(settingsCache, SIGNAL(minPlayersForMultiColumnLayoutChanged()), this, SLOT(rearrange())); connect(settingsCache, SIGNAL(minPlayersForMultiColumnLayoutChanged()), this, SLOT(rearrange()));
rearrange();
} }
GameScene::~GameScene() GameScene::~GameScene()

View file

@ -8,7 +8,7 @@ GameView::GameView(QGraphicsScene *scene, QWidget *parent)
: QGraphicsView(scene, parent), rubberBand(0) : QGraphicsView(scene, parent), rubberBand(0)
{ {
setBackgroundBrush(QBrush(QColor(0, 0, 0))); setBackgroundBrush(QBrush(QColor(0, 0, 0)));
setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing/* | QPainter::SmoothPixmapTransform*/); setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing);
setFocusPolicy(Qt::NoFocus); setFocusPolicy(Qt::NoFocus);
setViewportUpdateMode(BoundingRectViewportUpdate); setViewportUpdateMode(BoundingRectViewportUpdate);
@ -31,9 +31,9 @@ void GameView::resizeEvent(QResizeEvent *event)
QGraphicsView::resizeEvent(event); QGraphicsView::resizeEvent(event);
GameScene *s = dynamic_cast<GameScene *>(scene()); GameScene *s = dynamic_cast<GameScene *>(scene());
if (s) { if (s)
s->processViewSizeChange(event->size()); s->processViewSizeChange(event->size());
}
updateSceneRect(scene()->sceneRect()); updateSceneRect(scene()->sceneRect());
} }

View file

@ -125,7 +125,7 @@ void RemoteClient::readData()
processProtocolItem(newServerMessage); processProtocolItem(newServerMessage);
} while (!inputBuffer.isEmpty()); } while (!inputBuffer.isEmpty());
if (status == StatusDisconnecting) if (getStatus() == StatusDisconnecting) // use thread-safe getter
doDisconnectFromServer(); doDisconnectFromServer();
} }

View file

@ -271,7 +271,6 @@ TabGame::TabGame(GameReplay *_replay)
} }
phasesToolbar = new PhasesToolbar; phasesToolbar = new PhasesToolbar;
phasesToolbar->hide();
scene = new GameScene(phasesToolbar, this); scene = new GameScene(phasesToolbar, this);
gameView = new GameView(scene); gameView = new GameView(scene);
@ -399,7 +398,6 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_client
gameTimer->start(); gameTimer->start();
phasesToolbar = new PhasesToolbar; phasesToolbar = new PhasesToolbar;
phasesToolbar->hide();
connect(phasesToolbar, SIGNAL(sendGameCommand(const ::google::protobuf::Message &, int)), this, SLOT(sendGameCommand(const ::google::protobuf::Message &, int))); connect(phasesToolbar, SIGNAL(sendGameCommand(const ::google::protobuf::Message &, int)), this, SLOT(sendGameCommand(const ::google::protobuf::Message &, int)));
scene = new GameScene(phasesToolbar, this); scene = new GameScene(phasesToolbar, this);
@ -869,7 +867,6 @@ void TabGame::startGame(bool resuming)
gameInfo.set_started(true); gameInfo.set_started(true);
static_cast<GameScene *>(gameView->scene())->rearrange(); static_cast<GameScene *>(gameView->scene())->rearrange();
gameView->show(); gameView->show();
phasesToolbar->show();
} }
void TabGame::stopGame() void TabGame::stopGame()
@ -888,7 +885,6 @@ void TabGame::stopGame()
playerListWidget->setGameStarted(false, false); playerListWidget->setGameStarted(false, false);
gameInfo.set_started(false); gameInfo.set_started(false);
gameView->hide(); gameView->hide();
phasesToolbar->hide();
} }
void TabGame::closeGame() void TabGame::closeGame()