From 4e4a7563db07ca31f3952de8591283a7f1aad2f7 Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Sun, 25 Mar 2012 13:19:40 +0200 Subject: [PATCH] The remote client now runs in an extra thread, fixing issue #29 --- cockatrice/src/abstractclient.cpp | 33 ++++++++++++++- cockatrice/src/abstractclient.h | 14 ++++--- cockatrice/src/dlg_creategame.cpp | 7 ++-- cockatrice/src/dlg_creategame.h | 4 +- cockatrice/src/gameselector.cpp | 7 ++-- cockatrice/src/gameselector.h | 4 +- cockatrice/src/pending_command.h | 6 +-- cockatrice/src/remoteclient.cpp | 4 +- cockatrice/src/remotedecklist_treewidget.cpp | 2 +- .../src/remotereplaylist_treewidget.cpp | 2 +- cockatrice/src/tab_deck_storage.cpp | 40 +++++++++---------- cockatrice/src/tab_deck_storage.h | 13 +++--- cockatrice/src/tab_game.cpp | 4 +- cockatrice/src/tab_message.cpp | 2 +- cockatrice/src/tab_replays.cpp | 17 ++++---- cockatrice/src/tab_replays.h | 5 ++- cockatrice/src/tab_room.cpp | 2 +- cockatrice/src/tab_server.cpp | 6 +-- cockatrice/src/tab_server.h | 3 +- cockatrice/src/tab_userlists.cpp | 2 +- cockatrice/src/userinfobox.cpp | 2 +- cockatrice/src/userlist.cpp | 8 ++-- cockatrice/src/userlist.h | 3 +- cockatrice/src/window_main.cpp | 13 +++++- cockatrice/src/window_main.h | 4 ++ cockatrice/src/zoneviewzone.cpp | 2 +- 26 files changed, 130 insertions(+), 79 deletions(-) diff --git a/cockatrice/src/abstractclient.cpp b/cockatrice/src/abstractclient.cpp index 8d27be49..1b0e3c25 100644 --- a/cockatrice/src/abstractclient.cpp +++ b/cockatrice/src/abstractclient.cpp @@ -17,10 +17,32 @@ #include "pb/event_replay_added.pb.h" #include "get_pb_extension.h" #include +#include "client_metatypes.h" AbstractClient::AbstractClient(QObject *parent) : QObject(parent), nextCmdId(0), status(StatusDisconnected) { + qRegisterMetaType("CommandContainer"); + qRegisterMetaType("Response"); + qRegisterMetaType("ClientStatus"); + qRegisterMetaType("RoomEvent"); + qRegisterMetaType("GameEventContainer"); + qRegisterMetaType("Event_ServerIdentification"); + qRegisterMetaType("Event_ConnectionClosed"); + qRegisterMetaType("Event_ServerShutdown"); + qRegisterMetaType("Event_AddToList"); + qRegisterMetaType("Event_RemoveFromList"); + qRegisterMetaType("Event_UserJoined"); + qRegisterMetaType("Event_UserLeft"); + qRegisterMetaType("Event_ServerMessage"); + qRegisterMetaType("Event_ListRooms"); + qRegisterMetaType("Event_GameJoined"); + qRegisterMetaType("Event_UserMessage"); + qRegisterMetaType("ServerInfo_User"); + qRegisterMetaType >("QList"); + qRegisterMetaType("Event_ReplayAdded"); + + connect(this, SIGNAL(sigSendCommandContainer(CommandContainer)), this, SLOT(sendCommandContainer(CommandContainer))); } AbstractClient::~AbstractClient() @@ -33,6 +55,8 @@ void AbstractClient::processProtocolItem(const ServerMessage &item) case ServerMessage::RESPONSE: { const Response &response = item.response(); const int cmdId = response.cmd_id(); + + QMutexLocker locker(&clientMutex); PendingCommand *pend = pendingCommands.value(cmdId, 0); if (!pend) return; @@ -87,9 +111,14 @@ void AbstractClient::sendCommand(const CommandContainer &cont) void AbstractClient::sendCommand(PendingCommand *pend) { const int cmdId = nextCmdId++; - pendingCommands.insert(cmdId, pend); pend->getCommandContainer().set_cmd_id(cmdId); - sendCommandContainer(pend->getCommandContainer()); + pend->moveToThread(thread()); + + clientMutex.lock(); + pendingCommands.insert(cmdId, pend); + clientMutex.unlock(); + + emit sigSendCommandContainer(pend->getCommandContainer()); } PendingCommand *AbstractClient::prepareSessionCommand(const ::google::protobuf::Message &cmd) diff --git a/cockatrice/src/abstractclient.h b/cockatrice/src/abstractclient.h index 3a1cbb9d..19135c63 100644 --- a/cockatrice/src/abstractclient.h +++ b/cockatrice/src/abstractclient.h @@ -3,6 +3,7 @@ #include #include +#include #include "pb/response.pb.h" #include "pb/serverinfo_user.pb.h" @@ -59,16 +60,19 @@ signals: void buddyListReceived(const QList &buddyList); void ignoreListReceived(const QList &ignoreList); void replayAddedEventReceived(const Event_ReplayAdded &event); + + void sigSendCommandContainer(const CommandContainer &commandContainer); private: int nextCmdId; + QMutex clientMutex; protected slots: void processProtocolItem(const ServerMessage &item); + virtual void sendCommandContainer(const CommandContainer &cont) = 0; protected: QMap pendingCommands; ClientStatus status; QString userName, password; void setStatus(ClientStatus _status); - virtual void sendCommandContainer(const CommandContainer &cont) = 0; public: AbstractClient(QObject *parent = 0); ~AbstractClient(); @@ -77,10 +81,10 @@ public: void sendCommand(const CommandContainer &cont); void sendCommand(PendingCommand *pend); - PendingCommand *prepareSessionCommand(const ::google::protobuf::Message &cmd); - PendingCommand *prepareRoomCommand(const ::google::protobuf::Message &cmd, int roomId); - PendingCommand *prepareModeratorCommand(const ::google::protobuf::Message &cmd); - PendingCommand *prepareAdminCommand(const ::google::protobuf::Message &cmd); + static PendingCommand *prepareSessionCommand(const ::google::protobuf::Message &cmd); + static PendingCommand *prepareRoomCommand(const ::google::protobuf::Message &cmd, int roomId); + static PendingCommand *prepareModeratorCommand(const ::google::protobuf::Message &cmd); + static PendingCommand *prepareAdminCommand(const ::google::protobuf::Message &cmd); }; #endif \ No newline at end of file diff --git a/cockatrice/src/dlg_creategame.cpp b/cockatrice/src/dlg_creategame.cpp index d998d6e6..b3b9f274 100644 --- a/cockatrice/src/dlg_creategame.cpp +++ b/cockatrice/src/dlg_creategame.cpp @@ -15,6 +15,7 @@ #include "pending_command.h" #include "pb/room_commands.pb.h" #include "pb/serverinfo_game.pb.h" +#include "pb/response.pb.h" void DlgCreateGame::sharedCtor() { @@ -177,19 +178,19 @@ void DlgCreateGame::actOK() } PendingCommand *pend = room->prepareRoomCommand(cmd); - connect(pend, SIGNAL(finished(Response::ResponseCode)), this, SLOT(checkResponse(Response::ResponseCode))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(checkResponse(Response))); room->sendRoomCommand(pend); okButton->setEnabled(false); cancelButton->setEnabled(false); } -void DlgCreateGame::checkResponse(Response::ResponseCode response) +void DlgCreateGame::checkResponse(const Response &response) { okButton->setEnabled(true); cancelButton->setEnabled(true); - if (response == Response::RespOk) + if (response.response_code() == Response::RespOk) accept(); else { QMessageBox::critical(this, tr("Error"), tr("Server error.")); diff --git a/cockatrice/src/dlg_creategame.h b/cockatrice/src/dlg_creategame.h index 21595563..4718e447 100644 --- a/cockatrice/src/dlg_creategame.h +++ b/cockatrice/src/dlg_creategame.h @@ -3,7 +3,6 @@ #include #include -#include "pb/response.pb.h" class QLabel; class QLineEdit; @@ -13,6 +12,7 @@ class QGroupBox; class QSpinBox; class TabRoom; +class Response; class ServerInfo_Game; class DlgCreateGame : public QDialog { @@ -22,7 +22,7 @@ public: DlgCreateGame(const ServerInfo_Game &game, const QMap &_gameTypes, QWidget *parent = 0); private slots: void actOK(); - void checkResponse(Response::ResponseCode response); + void checkResponse(const Response &response); void spectatorsAllowedChanged(int state); private: TabRoom *room; diff --git a/cockatrice/src/gameselector.cpp b/cockatrice/src/gameselector.cpp index a02ab941..2db315a2 100644 --- a/cockatrice/src/gameselector.cpp +++ b/cockatrice/src/gameselector.cpp @@ -14,6 +14,7 @@ #include "pending_command.h" #include "pb/room_commands.pb.h" #include "pb/serverinfo_game.pb.h" +#include "pb/response.pb.h" GameSelector::GameSelector(AbstractClient *_client, TabSupervisor *_tabSupervisor, TabRoom *_room, const QMap &_rooms, const QMap &_gameTypes, QWidget *parent) : QGroupBox(parent), client(_client), tabSupervisor(_tabSupervisor), room(_room) @@ -82,14 +83,14 @@ void GameSelector::actCreate() dlg.exec(); } -void GameSelector::checkResponse(Response::ResponseCode response) +void GameSelector::checkResponse(const Response &response) { if (createButton) createButton->setEnabled(true); joinButton->setEnabled(true); spectateButton->setEnabled(true); - switch (response) { + switch (response.response_code()) { case Response::RespNotInRoom: QMessageBox::critical(this, tr("Error"), tr("Please join the appropriate room first.")); break; case Response::RespWrongPassword: QMessageBox::critical(this, tr("Error"), tr("Wrong password.")); break; case Response::RespSpectatorsNotAllowed: QMessageBox::critical(this, tr("Error"), tr("Spectators are not allowed in this game.")); break; @@ -132,7 +133,7 @@ void GameSelector::actJoin() } PendingCommand *pend = r->prepareRoomCommand(cmd); - connect(pend, SIGNAL(finished(Response::ResponseCode)), this, SLOT(checkResponse(Response::ResponseCode))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(checkResponse(Response))); r->sendRoomCommand(pend); if (createButton) diff --git a/cockatrice/src/gameselector.h b/cockatrice/src/gameselector.h index c4cb4b58..0d08704a 100644 --- a/cockatrice/src/gameselector.h +++ b/cockatrice/src/gameselector.h @@ -4,7 +4,6 @@ #include //#include "tab_room.h" #include "gametypemap.h" -#include "pb/response.pb.h" class QTreeView; class GamesModel; @@ -15,6 +14,7 @@ class AbstractClient; class TabSupervisor; class TabRoom; class ServerInfo_Game; +class Response; class GameSelector : public QGroupBox { Q_OBJECT @@ -22,7 +22,7 @@ private slots: void showUnavailableGamesChanged(int state); void actCreate(); void actJoin(); - void checkResponse(Response::ResponseCode response); + void checkResponse(const Response &response); signals: void gameJoined(int gameId); private: diff --git a/cockatrice/src/pending_command.h b/cockatrice/src/pending_command.h index b582ed81..2e2a2bf2 100644 --- a/cockatrice/src/pending_command.h +++ b/cockatrice/src/pending_command.h @@ -8,8 +8,8 @@ class PendingCommand : public QObject { Q_OBJECT signals: - void finished(const Response &response); - void finished(Response::ResponseCode response); + void finished(const Response &response, const CommandContainer &commandContainer, const QVariant &extraData); + void finished(Response::ResponseCode respCode); private: CommandContainer commandContainer; QVariant extraData; @@ -22,7 +22,7 @@ public: QVariant getExtraData() const { return extraData; } void processResponse(const Response &response) { - emit finished(response); + emit finished(response, commandContainer, extraData); emit finished(response.response_code()); } int tick() { return ++ticks; } diff --git a/cockatrice/src/remoteclient.cpp b/cockatrice/src/remoteclient.cpp index 59516dd1..3914946f 100644 --- a/cockatrice/src/remoteclient.cpp +++ b/cockatrice/src/remoteclient.cpp @@ -1,4 +1,5 @@ #include +#include #include "remoteclient.h" #include "pending_command.h" @@ -28,6 +29,7 @@ RemoteClient::RemoteClient(QObject *parent) RemoteClient::~RemoteClient() { disconnectFromServer(); + thread()->quit(); } void RemoteClient::slotSocketError(QAbstractSocket::SocketError /*error*/) @@ -58,7 +60,7 @@ void RemoteClient::processServerIdentificationEvent(const Event_ServerIdentifica cmdLogin.set_password(password.toStdString()); PendingCommand *pend = prepareSessionCommand(cmdLogin); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(loginResponse(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(loginResponse(Response))); sendCommand(pend); } diff --git a/cockatrice/src/remotedecklist_treewidget.cpp b/cockatrice/src/remotedecklist_treewidget.cpp index 4cd35dfd..ae1aa294 100644 --- a/cockatrice/src/remotedecklist_treewidget.cpp +++ b/cockatrice/src/remotedecklist_treewidget.cpp @@ -249,7 +249,7 @@ void RemoteDeckList_TreeModel::removeNode(RemoteDeckList_TreeModel::Node *node) void RemoteDeckList_TreeModel::refreshTree() { PendingCommand *pend = client->prepareSessionCommand(Command_DeckList()); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(deckListFinished(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(deckListFinished(const Response &))); client->sendCommand(pend); } diff --git a/cockatrice/src/remotereplaylist_treewidget.cpp b/cockatrice/src/remotereplaylist_treewidget.cpp index abbdf764..45ffe17a 100644 --- a/cockatrice/src/remotereplaylist_treewidget.cpp +++ b/cockatrice/src/remotereplaylist_treewidget.cpp @@ -207,7 +207,7 @@ void RemoteReplayList_TreeModel::clearTree() void RemoteReplayList_TreeModel::refreshTree() { PendingCommand *pend = client->prepareSessionCommand(Command_ReplayList()); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(replayListFinished(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(replayListFinished(const Response &))); client->sendCommand(pend); } diff --git a/cockatrice/src/tab_deck_storage.cpp b/cockatrice/src/tab_deck_storage.cpp index 4bae294d..b256d618 100644 --- a/cockatrice/src/tab_deck_storage.cpp +++ b/cockatrice/src/tab_deck_storage.cpp @@ -171,14 +171,14 @@ void TabDeckStorage::actUpload() cmd.set_deck_list(deck.writeToString_Native().toStdString()); PendingCommand *pend = client->prepareSessionCommand(cmd); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(uploadFinished(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(uploadFinished(Response, CommandContainer))); client->sendCommand(pend); } -void TabDeckStorage::uploadFinished(const Response &r) +void TabDeckStorage::uploadFinished(const Response &r, const CommandContainer &commandContainer) { const Response_DeckUpload &resp = r.GetExtension(Response_DeckUpload::ext); - const Command_DeckUpload &cmd = static_cast(static_cast(sender())->getCommandContainer().session_command(0).GetExtension(Command_DeckUpload::ext)); + const Command_DeckUpload &cmd = commandContainer.session_command(0).GetExtension(Command_DeckUpload::ext); serverDirView->addFileToTree(resp.new_file(), serverDirView->getNodeByPath(QString::fromStdString(cmd.path()))); } @@ -193,7 +193,7 @@ void TabDeckStorage::actOpenRemoteDeck() cmd.set_deck_id(curRight->getId()); PendingCommand *pend = client->prepareSessionCommand(cmd); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(openRemoteDeckFinished(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(openRemoteDeckFinished(const Response &))); client->sendCommand(pend); } @@ -228,16 +228,14 @@ void TabDeckStorage::actDownload() PendingCommand *pend = client->prepareSessionCommand(cmd); pend->setExtraData(filePath); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(downloadFinished(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(downloadFinished(Response, CommandContainer, QVariant))); client->sendCommand(pend); } -void TabDeckStorage::downloadFinished(const Response &r) +void TabDeckStorage::downloadFinished(const Response &r, const CommandContainer &/*commandContainer*/, const QVariant &extraData) { const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext); - - PendingCommand *pend = static_cast(sender()); - QString filePath = pend->getExtraData().toString(); + QString filePath = extraData.toString(); DeckList deck(QString::fromStdString(resp.deck())); deck.saveToFile(filePath, DeckList::CockatriceFormat); @@ -263,16 +261,16 @@ void TabDeckStorage::actNewFolder() cmd.set_dir_name(folderName.toStdString()); PendingCommand *pend = client->prepareSessionCommand(cmd); - connect(pend, SIGNAL(finished(Response::ResponseCode)), this, SLOT(newFolderFinished(Response::ResponseCode))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(newFolderFinished(Response, CommandContainer))); client->sendCommand(pend); } -void TabDeckStorage::newFolderFinished(Response::ResponseCode resp) +void TabDeckStorage::newFolderFinished(const Response &response, const CommandContainer &commandContainer) { - if (resp != Response::RespOk) + if (response.response_code() != Response::RespOk) return; - const Command_DeckNewDir &cmd = static_cast(static_cast(sender())->getCommandContainer().session_command(0).GetExtension(Command_DeckNewDir::ext)); + const Command_DeckNewDir &cmd = commandContainer.session_command(0).GetExtension(Command_DeckNewDir::ext); serverDirView->addFolderToTree(QString::fromStdString(cmd.dir_name()), serverDirView->getNodeByPath(QString::fromStdString(cmd.path()))); } @@ -290,34 +288,34 @@ void TabDeckStorage::actDelete() Command_DeckDelDir cmd; cmd.set_path(path.toStdString()); pend = client->prepareSessionCommand(cmd); - connect(pend, SIGNAL(finished(Response::ResponseCode)), this, SLOT(deleteFolderFinished(Response::ResponseCode))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(deleteFolderFinished(Response, CommandContainer))); } else { Command_DeckDel cmd; cmd.set_deck_id(dynamic_cast(curRight)->getId()); pend = client->prepareSessionCommand(cmd); - connect(pend, SIGNAL(finished(Response::ResponseCode)), this, SLOT(deleteDeckFinished(Response::ResponseCode))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(deleteDeckFinished(Response, CommandContainer))); } client->sendCommand(pend); } -void TabDeckStorage::deleteDeckFinished(Response::ResponseCode resp) +void TabDeckStorage::deleteDeckFinished(const Response &response, const CommandContainer &commandContainer) { - if (resp != Response::RespOk) + if (response.response_code() != Response::RespOk) return; - const Command_DeckDel &cmd = static_cast(static_cast(sender())->getCommandContainer().session_command(0).GetExtension(Command_DeckDel::ext)); + const Command_DeckDel &cmd = commandContainer.session_command(0).GetExtension(Command_DeckDel::ext); RemoteDeckList_TreeModel::Node *toDelete = serverDirView->getNodeById(cmd.deck_id()); if (toDelete) serverDirView->removeNode(toDelete); } -void TabDeckStorage::deleteFolderFinished(Response::ResponseCode resp) +void TabDeckStorage::deleteFolderFinished(const Response &response, const CommandContainer &commandContainer) { - if (resp != Response::RespOk) + if (response.response_code() != Response::RespOk) return; - const Command_DeckDelDir &cmd = static_cast(static_cast(sender())->getCommandContainer().session_command(0).GetExtension(Command_DeckDelDir::ext)); + const Command_DeckDelDir &cmd = commandContainer.session_command(0).GetExtension(Command_DeckDelDir::ext); RemoteDeckList_TreeModel::Node *toDelete = serverDirView->getNodeByPath(QString::fromStdString(cmd.path())); if (toDelete) serverDirView->removeNode(toDelete); diff --git a/cockatrice/src/tab_deck_storage.h b/cockatrice/src/tab_deck_storage.h index 41b53954..51344208 100644 --- a/cockatrice/src/tab_deck_storage.h +++ b/cockatrice/src/tab_deck_storage.h @@ -2,7 +2,6 @@ #define TAB_DECK_STORAGE_H #include "tab.h" -#include "pb/response.pb.h" class AbstractClient; class QTreeView; @@ -13,6 +12,8 @@ class QTreeWidget; class QTreeWidgetItem; class QGroupBox; class RemoteDeckList_TreeWidget; +class CommandContainer; +class Response; class TabDeckStorage : public Tab { Q_OBJECT @@ -30,20 +31,20 @@ private slots: void actOpenLocalDeck(); void actUpload(); - void uploadFinished(const Response &r); + void uploadFinished(const Response &r, const CommandContainer &commandContainer); void actOpenRemoteDeck(); void openRemoteDeckFinished(const Response &r); void actDownload(); - void downloadFinished(const Response &r); + void downloadFinished(const Response &r, const CommandContainer &commandContainer, const QVariant &extraData); void actNewFolder(); - void newFolderFinished(Response::ResponseCode resp); + void newFolderFinished(const Response &response, const CommandContainer &commandContainer); void actDelete(); - void deleteFolderFinished(Response::ResponseCode resp); - void deleteDeckFinished(Response::ResponseCode resp); + void deleteFolderFinished(const Response &response, const CommandContainer &commandContainer); + void deleteDeckFinished(const Response &response, const CommandContainer &commandContainer); public: TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_client); void retranslateUi(); diff --git a/cockatrice/src/tab_game.cpp b/cockatrice/src/tab_game.cpp index dae1456a..471a1eb2 100644 --- a/cockatrice/src/tab_game.cpp +++ b/cockatrice/src/tab_game.cpp @@ -147,7 +147,7 @@ void DeckViewContainer::loadLocalDeck() Command_DeckSelect cmd; cmd.set_deck(deck->writeToString_Native().toStdString()); PendingCommand *pend = static_cast(parent())->prepareGameCommand(cmd); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(deckSelectFinished(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(deckSelectFinished(const Response &))); static_cast(parent())->sendGameCommand(pend, playerId); } @@ -158,7 +158,7 @@ void DeckViewContainer::loadRemoteDeck() Command_DeckSelect cmd; cmd.set_deck_id(dlg.getDeckId()); PendingCommand *pend = static_cast(parent())->prepareGameCommand(cmd); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(deckSelectFinished(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(deckSelectFinished(const Response &))); static_cast(parent())->sendGameCommand(pend, playerId); } } diff --git a/cockatrice/src/tab_message.cpp b/cockatrice/src/tab_message.cpp index 0ef99a65..2cb1d15c 100644 --- a/cockatrice/src/tab_message.cpp +++ b/cockatrice/src/tab_message.cpp @@ -60,7 +60,7 @@ void TabMessage::sendMessage() cmd.set_message(sayEdit->text().toStdString()); PendingCommand *pend = client->prepareSessionCommand(cmd); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(messageSent(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(messageSent(const Response &))); client->sendCommand(pend); sayEdit->clear(); diff --git a/cockatrice/src/tab_replays.cpp b/cockatrice/src/tab_replays.cpp index 9e4ea43b..2b734d24 100644 --- a/cockatrice/src/tab_replays.cpp +++ b/cockatrice/src/tab_replays.cpp @@ -140,7 +140,7 @@ void TabReplays::actOpenRemoteReplay() cmd.set_replay_id(curRight->replay_id()); PendingCommand *pend = client->prepareSessionCommand(cmd); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(openRemoteReplayFinished(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(openRemoteReplayFinished(const Response &))); client->sendCommand(pend); } @@ -175,16 +175,14 @@ void TabReplays::actDownload() PendingCommand *pend = client->prepareSessionCommand(cmd); pend->setExtraData(filePath); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(downloadFinished(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(downloadFinished(Response, CommandContainer, QVariant))); client->sendCommand(pend); } -void TabReplays::downloadFinished(const Response &r) +void TabReplays::downloadFinished(const Response &r, const CommandContainer &commandContainer, const QVariant &extraData) { const Response_ReplayDownload &resp = r.GetExtension(Response_ReplayDownload::ext); - - PendingCommand *pend = static_cast(sender()); - QString filePath = pend->getExtraData().toString(); + QString filePath = extraData.toString(); const std::string &data = resp.replay_data(); QFile f(filePath); @@ -204,17 +202,16 @@ void TabReplays::actKeepRemoteReplay() cmd.set_do_not_hide(!curRight->do_not_hide()); PendingCommand *pend = client->prepareSessionCommand(cmd); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(keepRemoteReplayFinished(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(keepRemoteReplayFinished(Response, CommandContainer))); client->sendCommand(pend); } -void TabReplays::keepRemoteReplayFinished(const Response &r) +void TabReplays::keepRemoteReplayFinished(const Response &r, const CommandContainer &commandContainer) { if (r.response_code() != Response::RespOk) return; - PendingCommand *pend = static_cast(sender()); - const Command_ReplayModifyMatch &cmd = pend->getCommandContainer().session_command(0).GetExtension(Command_ReplayModifyMatch::ext); + const Command_ReplayModifyMatch &cmd = commandContainer.session_command(0).GetExtension(Command_ReplayModifyMatch::ext); ServerInfo_ReplayMatch temp; temp.set_do_not_hide(cmd.do_not_hide()); diff --git a/cockatrice/src/tab_replays.h b/cockatrice/src/tab_replays.h index 0cfc6ed1..4badc292 100644 --- a/cockatrice/src/tab_replays.h +++ b/cockatrice/src/tab_replays.h @@ -13,6 +13,7 @@ class QGroupBox; class RemoteReplayList_TreeWidget; class GameReplay; class Event_ReplayAdded; +class CommandContainer; class TabReplays : public Tab { Q_OBJECT @@ -33,10 +34,10 @@ private slots: void openRemoteReplayFinished(const Response &r); void actDownload(); - void downloadFinished(const Response &r); + void downloadFinished(const Response &r, const CommandContainer &commandContainer, const QVariant &extraData); void actKeepRemoteReplay(); - void keepRemoteReplayFinished(const Response &r); + void keepRemoteReplayFinished(const Response &r, const CommandContainer &commandContainer); void replayAddedEventReceived(const Event_ReplayAdded &event); signals: diff --git a/cockatrice/src/tab_room.cpp b/cockatrice/src/tab_room.cpp index 1961d8de..6cc78603 100644 --- a/cockatrice/src/tab_room.cpp +++ b/cockatrice/src/tab_room.cpp @@ -120,7 +120,7 @@ void TabRoom::sendMessage() cmd.set_message(sayEdit->text().toStdString()); PendingCommand *pend = prepareRoomCommand(cmd); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(sayFinished(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(sayFinished(const Response &))); sendRoomCommand(pend); sayEdit->clear(); } diff --git a/cockatrice/src/tab_server.cpp b/cockatrice/src/tab_server.cpp index 7c122831..f6b9448f 100644 --- a/cockatrice/src/tab_server.cpp +++ b/cockatrice/src/tab_server.cpp @@ -105,7 +105,7 @@ void RoomSelector::joinRoom(int id, bool setCurrent) PendingCommand *pend = client->prepareSessionCommand(cmd); pend->setExtraData(setCurrent); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(joinFinished(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(joinFinished(Response, CommandContainer, QVariant))); client->sendCommand(pend); } @@ -119,13 +119,13 @@ void RoomSelector::joinClicked() joinRoom(twi->data(0, Qt::UserRole).toInt(), true); } -void RoomSelector::joinFinished(const Response &r) +void RoomSelector::joinFinished(const Response &r, const CommandContainer & /*commandContainer*/, const QVariant &extraData) { if (r.response_code() != Response::RespOk) return; const Response_JoinRoom &resp = r.GetExtension(Response_JoinRoom::ext); - emit roomJoined(resp.room_info(), static_cast(sender())->getExtraData().toBool()); + emit roomJoined(resp.room_info(), extraData.toBool()); } TabServer::TabServer(TabSupervisor *_tabSupervisor, AbstractClient *_client, QWidget *parent) diff --git a/cockatrice/src/tab_server.h b/cockatrice/src/tab_server.h index 72f0463f..f64e4871 100644 --- a/cockatrice/src/tab_server.h +++ b/cockatrice/src/tab_server.h @@ -16,6 +16,7 @@ class Event_ListRooms; class Event_ServerMessage; class Response; class ServerInfo_Room; +class CommandContainer; class RoomSelector : public QGroupBox { Q_OBJECT @@ -28,7 +29,7 @@ private: private slots: void processListRoomsEvent(const Event_ListRooms &event); void joinClicked(); - void joinFinished(const Response &resp); + void joinFinished(const Response &resp, const CommandContainer &commandContainer, const QVariant &extraData); signals: void roomJoined(const ServerInfo_Room &info, bool setCurrent); public: diff --git a/cockatrice/src/tab_userlists.cpp b/cockatrice/src/tab_userlists.cpp index f982ac0e..d43fe41e 100644 --- a/cockatrice/src/tab_userlists.cpp +++ b/cockatrice/src/tab_userlists.cpp @@ -35,7 +35,7 @@ TabUserLists::TabUserLists(TabSupervisor *_tabSupervisor, AbstractClient *_clien connect(client, SIGNAL(removeFromListEventReceived(const Event_RemoveFromList &)), this, SLOT(processRemoveFromListEvent(const Event_RemoveFromList &))); PendingCommand *pend = client->prepareSessionCommand(Command_ListUsers()); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(processListUsersResponse(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(processListUsersResponse(const Response &))); client->sendCommand(pend); QVBoxLayout *vbox = new QVBoxLayout; diff --git a/cockatrice/src/userinfobox.cpp b/cockatrice/src/userinfobox.cpp index 08159323..6fd2736d 100644 --- a/cockatrice/src/userinfobox.cpp +++ b/cockatrice/src/userinfobox.cpp @@ -87,7 +87,7 @@ void UserInfoBox::updateInfo(const QString &userName) cmd.set_user_name(userName.toStdString()); PendingCommand *pend = client->prepareSessionCommand(cmd); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(processResponse(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(processResponse(const Response &))); client->sendCommand(pend); } diff --git a/cockatrice/src/userlist.cpp b/cockatrice/src/userlist.cpp index d87b95dd..706fbedc 100644 --- a/cockatrice/src/userlist.cpp +++ b/cockatrice/src/userlist.cpp @@ -305,10 +305,10 @@ void UserList::userClicked(QTreeWidgetItem *item, int /*column*/) emit openMessageDialog(item->data(2, Qt::UserRole).toString(), true); } -void UserList::gamesOfUserReceived(const Response &resp) +void UserList::gamesOfUserReceived(const Response &resp, const CommandContainer &commandContainer) { const Response_GetGamesOfUser &response = resp.GetExtension(Response_GetGamesOfUser::ext); - const Command_GetGamesOfUser &cmd = static_cast(static_cast(sender())->getCommandContainer().session_command(0).GetExtension(Command_GetGamesOfUser::ext)); + const Command_GetGamesOfUser &cmd = commandContainer.session_command(0).GetExtension(Command_GetGamesOfUser::ext); QMap gameTypeMap; QMap roomMap; @@ -429,7 +429,7 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index) cmd.set_user_name(userName.toStdString()); PendingCommand *pend = client->prepareSessionCommand(cmd); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(gamesOfUserReceived(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(gamesOfUserReceived(Response, CommandContainer))); client->sendCommand(pend); } else if (actionClicked == aAddToIgnoreList) { @@ -449,7 +449,7 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index) cmd.set_user_name(userName.toStdString()); PendingCommand *pend = client->prepareSessionCommand(cmd); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(banUser_processUserInfoResponse(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(banUser_processUserInfoResponse(Response))); client->sendCommand(pend); } diff --git a/cockatrice/src/userlist.h b/cockatrice/src/userlist.h index fae319fa..f81b9a39 100644 --- a/cockatrice/src/userlist.h +++ b/cockatrice/src/userlist.h @@ -16,6 +16,7 @@ class QSpinBox; class QRadioButton; class QPlainTextEdit; class Response; +class CommandContainer; class BanDialog : public QDialog { Q_OBJECT @@ -68,7 +69,7 @@ private slots: void userClicked(QTreeWidgetItem *item, int column); void banUser_processUserInfoResponse(const Response &resp); void banUser_dialogFinished(); - void gamesOfUserReceived(const Response &resp); + void gamesOfUserReceived(const Response &resp, const CommandContainer &commandContainer); signals: void openMessageDialog(const QString &userName, bool focus); void addBuddy(const QString &userName); diff --git a/cockatrice/src/window_main.cpp b/cockatrice/src/window_main.cpp index 01d47b2d..4d845e3e 100644 --- a/cockatrice/src/window_main.cpp +++ b/cockatrice/src/window_main.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "main.h" #include "window_main.h" @@ -337,7 +338,7 @@ MainWindow::MainWindow(QWidget *parent) { QPixmapCache::setCacheLimit(200000); - client = new RemoteClient(this); + client = new RemoteClient; connect(client, SIGNAL(connectionClosedEventReceived(const Event_ConnectionClosed &)), this, SLOT(processConnectionClosedEvent(const Event_ConnectionClosed &))); connect(client, SIGNAL(serverShutdownEventReceived(const Event_ServerShutdown &)), this, SLOT(processServerShutdownEvent(const Event_ServerShutdown &))); connect(client, SIGNAL(serverError(Response::ResponseCode, QString)), this, SLOT(serverError(Response::ResponseCode, QString))); @@ -346,6 +347,10 @@ MainWindow::MainWindow(QWidget *parent) connect(client, SIGNAL(statusChanged(ClientStatus)), this, SLOT(statusChanged(ClientStatus))); connect(client, SIGNAL(protocolVersionMismatch(int, int)), this, SLOT(protocolVersionMismatch(int, int))); connect(client, SIGNAL(userInfoChanged(const ServerInfo_User &)), this, SLOT(userInfoReceived(const ServerInfo_User &))); + + clientThread = new QThread(this); + client->moveToThread(clientThread); + clientThread->start(); tabSupervisor = new TabSupervisor; connect(tabSupervisor, SIGNAL(setMenu(QMenu *)), this, SLOT(updateTabMenu(QMenu *))); @@ -361,6 +366,12 @@ MainWindow::MainWindow(QWidget *parent) resize(900, 700); } +MainWindow::~MainWindow() +{ + client->deleteLater(); + clientThread->wait(); +} + void MainWindow::closeEvent(QCloseEvent *event) { if (tabSupervisor->getGameCount()) { diff --git a/cockatrice/src/window_main.h b/cockatrice/src/window_main.h index c49550fe..6f06b38d 100644 --- a/cockatrice/src/window_main.h +++ b/cockatrice/src/window_main.h @@ -29,6 +29,7 @@ class RemoteClient; class LocalClient; class LocalServer; class ServerInfo_User; +class QThread; class MainWindow : public QMainWindow { Q_OBJECT @@ -66,9 +67,12 @@ private: TabSupervisor *tabSupervisor; RemoteClient *client; + QThread *clientThread; + LocalServer *localServer; public: MainWindow(QWidget *parent = 0); + ~MainWindow(); protected: void closeEvent(QCloseEvent *event); void changeEvent(QEvent *event); diff --git a/cockatrice/src/zoneviewzone.cpp b/cockatrice/src/zoneviewzone.cpp index cd27984b..3f94d968 100644 --- a/cockatrice/src/zoneviewzone.cpp +++ b/cockatrice/src/zoneviewzone.cpp @@ -48,7 +48,7 @@ void ZoneViewZone::initializeCards(const QList &cardLis cmd.set_number_cards(numberCards); PendingCommand *pend = player->prepareGameCommand(cmd); - connect(pend, SIGNAL(finished(const Response &)), this, SLOT(zoneDumpReceived(const Response &))); + connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(zoneDumpReceived(const Response &))); player->sendGameCommand(pend); } else { const CardList &c = origZone->getCards();