diff --git a/cockatrice/src/client.cpp b/cockatrice/src/client.cpp index 76278a56..f470160f 100644 --- a/cockatrice/src/client.cpp +++ b/cockatrice/src/client.cpp @@ -74,12 +74,6 @@ void PendingCommand::responseReceived(ServerResponse resp) deleteLater(); } -void PendingCommand::checkTimeout() -{ - if (++time > 5) - emit timeout(); -} - void PendingCommand_ListPlayers::responseReceived(ServerResponse resp) { if (resp == RespOk) @@ -138,12 +132,6 @@ Client::~Client() disconnectFromServer(); } -void Client::timeout() -{ - emit serverTimeout(); - disconnectFromServer(); -} - void Client::slotSocketError(QAbstractSocket::SocketError /*error*/) { emit logSocketError(socket->errorString()); @@ -376,8 +364,6 @@ PendingCommand *Client::cmd(const QString &s, PendingCommand *_pc) pc = new PendingCommand(MsgId); pendingCommands.insert(MsgId, pc); connect(pc, SIGNAL(finished(ServerResponse)), this, SLOT(removePendingCommand())); - connect(pc, SIGNAL(timeout()), this, SLOT(timeout())); - connect(timer, SIGNAL(timeout()), pc, SLOT(checkTimeout())); return pc; } @@ -406,7 +392,19 @@ void Client::disconnectFromServer() void Client::ping() { - cmd("ping"); + int maxTime = 0; + QMapIterator i(pendingCommands); + while (i.hasNext()) { + int time = i.next().value()->tick(); + if (time > maxTime) + maxTime = time; + } + emit maxPingTime(maxTime, maxTimeout); + if (maxTime >= maxTimeout) { + emit serverTimeout(); + disconnectFromServer(); + } else + cmd("ping"); } PendingCommand *Client::chatListChannels() diff --git a/cockatrice/src/client.h b/cockatrice/src/client.h index 6d3d434f..853dc2a2 100644 --- a/cockatrice/src/client.h +++ b/cockatrice/src/client.h @@ -201,12 +201,11 @@ private: int time; signals: void finished(ServerResponse resp); - void timeout(); public slots: virtual void responseReceived(ServerResponse resp); - void checkTimeout(); public: PendingCommand(int _msgid = -1); + int tick() { return ++time; } int getMsgId() const { return msgid; } void setMsgId(int _msgId) { msgid = _msgId; } }; @@ -310,6 +309,7 @@ signals: void playerIdReceived(int id, QString name); void gameEvent(const ServerEventData &msg); void chatEvent(const ChatEventData &msg); + void maxPingTime(int seconds, int maxSeconds); void serverTimeout(); void logSocketError(const QString &errorString); void serverError(ServerResponse resp); @@ -318,7 +318,6 @@ signals: private slots: void slotConnected(); void readLine(); - void timeout(); void slotSocketError(QAbstractSocket::SocketError error); void ping(); void removePendingCommand(); @@ -327,6 +326,8 @@ private slots: void leaveGameResponse(ServerResponse response); private: static const int protocolVersion = 1; + static const int maxTimeout = 10; + QTimer *timer; QMap pendingCommands; QTcpSocket *socket; diff --git a/cockatrice/src/window_main.cpp b/cockatrice/src/window_main.cpp index b691790c..a92f440e 100644 --- a/cockatrice/src/window_main.cpp +++ b/cockatrice/src/window_main.cpp @@ -38,6 +38,31 @@ #include "zoneviewlayout.h" #include "chatwidget.h" +PingWidget::PingWidget(QWidget *parent) + : QWidget(parent), color(Qt::black) +{ +} + +QSize PingWidget::sizeHint() const +{ + return QSize(10, 10); +} + +void PingWidget::paintEvent(QPaintEvent */*event*/) +{ + QPainter painter(this); + painter.fillRect(0, 0, width(), height(), color); +} + +void PingWidget::setPercentage(int value, int max) +{ + if (max == -1) + color = Qt::black; + else + color.setHsv(120 * (1.0 - ((double) value / max)), 255, 255); + update(); +} + void MainWindow::playerAdded(Player *player) { menuBar()->addMenu(player->getPlayerMenu()); @@ -57,6 +82,8 @@ void MainWindow::statusChanged(ProtocolStatus _status) delete game; game = 0; } + pingWidget->setPercentage(0, -1); + aConnect->setEnabled(true); aDisconnect->setEnabled(false); aRestartGame->setEnabled(false); aLeaveGame->setEnabled(false); @@ -67,6 +94,7 @@ void MainWindow::statusChanged(ProtocolStatus _status) emit logDisconnected(); break; case StatusLoggingIn: + aConnect->setEnabled(false); aDisconnect->setEnabled(true); break; case StatusIdle: { @@ -267,6 +295,7 @@ MainWindow::MainWindow(QTranslator *_translator, QWidget *parent) sayLabel = new QLabel; sayEdit = new QLineEdit; sayLabel->setBuddy(sayEdit); + pingWidget = new PingWidget; client = new Client(this); gameSelector = new GameSelector(client); @@ -277,6 +306,7 @@ MainWindow::MainWindow(QTranslator *_translator, QWidget *parent) QHBoxLayout *hLayout = new QHBoxLayout; hLayout->addWidget(sayLabel); hLayout->addWidget(sayEdit); + hLayout->addWidget(pingWidget); QVBoxLayout *verticalLayout = new QVBoxLayout; verticalLayout->addWidget(cardInfo); @@ -302,6 +332,7 @@ MainWindow::MainWindow(QTranslator *_translator, QWidget *parent) connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(actSay())); + connect(client, SIGNAL(maxPingTime(int, int)), pingWidget, SLOT(setPercentage(int, int))); connect(client, SIGNAL(serverTimeout()), this, SLOT(serverTimeout())); connect(client, SIGNAL(statusChanged(ProtocolStatus)), this, SLOT(statusChanged(ProtocolStatus))); diff --git a/cockatrice/src/window_main.h b/cockatrice/src/window_main.h index 693e4905..612992d3 100644 --- a/cockatrice/src/window_main.h +++ b/cockatrice/src/window_main.h @@ -43,6 +43,19 @@ class PhasesToolbar; class GameSelector; class ChatWidget; +class PingWidget : public QWidget { + Q_OBJECT +private: + QColor color; +protected: + void paintEvent(QPaintEvent *event); +public: + PingWidget(QWidget *parent = 0); + QSize sizeHint() const; +public slots: + void setPercentage(int value, int max); +}; + class MainWindow : public QMainWindow { Q_OBJECT private slots: @@ -72,6 +85,7 @@ private: QAction *aCloseMostRecentZoneView; QVBoxLayout *viewLayout; + PingWidget *pingWidget; CardInfoWidget *cardInfo; MessageLogWidget *messageLog; QLabel *sayLabel;