The remote client now runs in an extra thread, fixing issue #29

This commit is contained in:
Max-Wilhelm Bruker 2012-03-25 13:19:40 +02:00
parent 542fd2c5c8
commit 4e4a7563db
26 changed files with 130 additions and 79 deletions

View file

@ -17,10 +17,32 @@
#include "pb/event_replay_added.pb.h" #include "pb/event_replay_added.pb.h"
#include "get_pb_extension.h" #include "get_pb_extension.h"
#include <google/protobuf/descriptor.h> #include <google/protobuf/descriptor.h>
#include "client_metatypes.h"
AbstractClient::AbstractClient(QObject *parent) AbstractClient::AbstractClient(QObject *parent)
: QObject(parent), nextCmdId(0), status(StatusDisconnected) : QObject(parent), nextCmdId(0), status(StatusDisconnected)
{ {
qRegisterMetaType<CommandContainer>("CommandContainer");
qRegisterMetaType<Response>("Response");
qRegisterMetaType<ClientStatus>("ClientStatus");
qRegisterMetaType<RoomEvent>("RoomEvent");
qRegisterMetaType<GameEventContainer>("GameEventContainer");
qRegisterMetaType<Event_ServerIdentification>("Event_ServerIdentification");
qRegisterMetaType<Event_ConnectionClosed>("Event_ConnectionClosed");
qRegisterMetaType<Event_ServerShutdown>("Event_ServerShutdown");
qRegisterMetaType<Event_AddToList>("Event_AddToList");
qRegisterMetaType<Event_RemoveFromList>("Event_RemoveFromList");
qRegisterMetaType<Event_UserJoined>("Event_UserJoined");
qRegisterMetaType<Event_UserLeft>("Event_UserLeft");
qRegisterMetaType<Event_ServerMessage>("Event_ServerMessage");
qRegisterMetaType<Event_ListRooms>("Event_ListRooms");
qRegisterMetaType<Event_GameJoined>("Event_GameJoined");
qRegisterMetaType<Event_UserMessage>("Event_UserMessage");
qRegisterMetaType<ServerInfo_User>("ServerInfo_User");
qRegisterMetaType<QList<ServerInfo_User> >("QList<ServerInfo_User>");
qRegisterMetaType<Event_ReplayAdded>("Event_ReplayAdded");
connect(this, SIGNAL(sigSendCommandContainer(CommandContainer)), this, SLOT(sendCommandContainer(CommandContainer)));
} }
AbstractClient::~AbstractClient() AbstractClient::~AbstractClient()
@ -33,6 +55,8 @@ void AbstractClient::processProtocolItem(const ServerMessage &item)
case ServerMessage::RESPONSE: { case ServerMessage::RESPONSE: {
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;
@ -87,9 +111,14 @@ void AbstractClient::sendCommand(const CommandContainer &cont)
void AbstractClient::sendCommand(PendingCommand *pend) void AbstractClient::sendCommand(PendingCommand *pend)
{ {
const int cmdId = nextCmdId++; const int cmdId = nextCmdId++;
pendingCommands.insert(cmdId, pend);
pend->getCommandContainer().set_cmd_id(cmdId); 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) PendingCommand *AbstractClient::prepareSessionCommand(const ::google::protobuf::Message &cmd)

View file

@ -3,6 +3,7 @@
#include <QObject> #include <QObject>
#include <QVariant> #include <QVariant>
#include <QMutex>
#include "pb/response.pb.h" #include "pb/response.pb.h"
#include "pb/serverinfo_user.pb.h" #include "pb/serverinfo_user.pb.h"
@ -59,16 +60,19 @@ signals:
void buddyListReceived(const QList<ServerInfo_User> &buddyList); void buddyListReceived(const QList<ServerInfo_User> &buddyList);
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);
private: private:
int nextCmdId; int nextCmdId;
QMutex clientMutex;
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; 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();
@ -77,10 +81,10 @@ public:
void sendCommand(const CommandContainer &cont); void sendCommand(const CommandContainer &cont);
void sendCommand(PendingCommand *pend); void sendCommand(PendingCommand *pend);
PendingCommand *prepareSessionCommand(const ::google::protobuf::Message &cmd); static PendingCommand *prepareSessionCommand(const ::google::protobuf::Message &cmd);
PendingCommand *prepareRoomCommand(const ::google::protobuf::Message &cmd, int roomId); static PendingCommand *prepareRoomCommand(const ::google::protobuf::Message &cmd, int roomId);
PendingCommand *prepareModeratorCommand(const ::google::protobuf::Message &cmd); static PendingCommand *prepareModeratorCommand(const ::google::protobuf::Message &cmd);
PendingCommand *prepareAdminCommand(const ::google::protobuf::Message &cmd); static PendingCommand *prepareAdminCommand(const ::google::protobuf::Message &cmd);
}; };
#endif #endif

View file

@ -15,6 +15,7 @@
#include "pending_command.h" #include "pending_command.h"
#include "pb/room_commands.pb.h" #include "pb/room_commands.pb.h"
#include "pb/serverinfo_game.pb.h" #include "pb/serverinfo_game.pb.h"
#include "pb/response.pb.h"
void DlgCreateGame::sharedCtor() void DlgCreateGame::sharedCtor()
{ {
@ -177,19 +178,19 @@ void DlgCreateGame::actOK()
} }
PendingCommand *pend = room->prepareRoomCommand(cmd); 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); room->sendRoomCommand(pend);
okButton->setEnabled(false); okButton->setEnabled(false);
cancelButton->setEnabled(false); cancelButton->setEnabled(false);
} }
void DlgCreateGame::checkResponse(Response::ResponseCode response) void DlgCreateGame::checkResponse(const Response &response)
{ {
okButton->setEnabled(true); okButton->setEnabled(true);
cancelButton->setEnabled(true); cancelButton->setEnabled(true);
if (response == Response::RespOk) if (response.response_code() == Response::RespOk)
accept(); accept();
else { else {
QMessageBox::critical(this, tr("Error"), tr("Server error.")); QMessageBox::critical(this, tr("Error"), tr("Server error."));

View file

@ -3,7 +3,6 @@
#include <QDialog> #include <QDialog>
#include <QMap> #include <QMap>
#include "pb/response.pb.h"
class QLabel; class QLabel;
class QLineEdit; class QLineEdit;
@ -13,6 +12,7 @@ class QGroupBox;
class QSpinBox; class QSpinBox;
class TabRoom; class TabRoom;
class Response;
class ServerInfo_Game; class ServerInfo_Game;
class DlgCreateGame : public QDialog { class DlgCreateGame : public QDialog {
@ -22,7 +22,7 @@ public:
DlgCreateGame(const ServerInfo_Game &game, const QMap<int, QString> &_gameTypes, QWidget *parent = 0); DlgCreateGame(const ServerInfo_Game &game, const QMap<int, QString> &_gameTypes, QWidget *parent = 0);
private slots: private slots:
void actOK(); void actOK();
void checkResponse(Response::ResponseCode response); void checkResponse(const Response &response);
void spectatorsAllowedChanged(int state); void spectatorsAllowedChanged(int state);
private: private:
TabRoom *room; TabRoom *room;

View file

@ -14,6 +14,7 @@
#include "pending_command.h" #include "pending_command.h"
#include "pb/room_commands.pb.h" #include "pb/room_commands.pb.h"
#include "pb/serverinfo_game.pb.h" #include "pb/serverinfo_game.pb.h"
#include "pb/response.pb.h"
GameSelector::GameSelector(AbstractClient *_client, TabSupervisor *_tabSupervisor, TabRoom *_room, const QMap<int, QString> &_rooms, const QMap<int, GameTypeMap> &_gameTypes, QWidget *parent) GameSelector::GameSelector(AbstractClient *_client, TabSupervisor *_tabSupervisor, TabRoom *_room, const QMap<int, QString> &_rooms, const QMap<int, GameTypeMap> &_gameTypes, QWidget *parent)
: QGroupBox(parent), client(_client), tabSupervisor(_tabSupervisor), room(_room) : QGroupBox(parent), client(_client), tabSupervisor(_tabSupervisor), room(_room)
@ -82,14 +83,14 @@ void GameSelector::actCreate()
dlg.exec(); dlg.exec();
} }
void GameSelector::checkResponse(Response::ResponseCode response) void GameSelector::checkResponse(const Response &response)
{ {
if (createButton) if (createButton)
createButton->setEnabled(true); createButton->setEnabled(true);
joinButton->setEnabled(true); joinButton->setEnabled(true);
spectateButton->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::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::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; 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); 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); r->sendRoomCommand(pend);
if (createButton) if (createButton)

View file

@ -4,7 +4,6 @@
#include <QGroupBox> #include <QGroupBox>
//#include "tab_room.h" //#include "tab_room.h"
#include "gametypemap.h" #include "gametypemap.h"
#include "pb/response.pb.h"
class QTreeView; class QTreeView;
class GamesModel; class GamesModel;
@ -15,6 +14,7 @@ class AbstractClient;
class TabSupervisor; class TabSupervisor;
class TabRoom; class TabRoom;
class ServerInfo_Game; class ServerInfo_Game;
class Response;
class GameSelector : public QGroupBox { class GameSelector : public QGroupBox {
Q_OBJECT Q_OBJECT
@ -22,7 +22,7 @@ private slots:
void showUnavailableGamesChanged(int state); void showUnavailableGamesChanged(int state);
void actCreate(); void actCreate();
void actJoin(); void actJoin();
void checkResponse(Response::ResponseCode response); void checkResponse(const Response &response);
signals: signals:
void gameJoined(int gameId); void gameJoined(int gameId);
private: private:

View file

@ -8,8 +8,8 @@
class PendingCommand : public QObject { class PendingCommand : public QObject {
Q_OBJECT Q_OBJECT
signals: signals:
void finished(const Response &response); void finished(const Response &response, const CommandContainer &commandContainer, const QVariant &extraData);
void finished(Response::ResponseCode response); void finished(Response::ResponseCode respCode);
private: private:
CommandContainer commandContainer; CommandContainer commandContainer;
QVariant extraData; QVariant extraData;
@ -22,7 +22,7 @@ public:
QVariant getExtraData() const { return extraData; } QVariant getExtraData() const { return extraData; }
void processResponse(const Response &response) void processResponse(const Response &response)
{ {
emit finished(response); emit finished(response, commandContainer, extraData);
emit finished(response.response_code()); emit finished(response.response_code());
} }
int tick() { return ++ticks; } int tick() { return ++ticks; }

View file

@ -1,4 +1,5 @@
#include <QTimer> #include <QTimer>
#include <QThread>
#include "remoteclient.h" #include "remoteclient.h"
#include "pending_command.h" #include "pending_command.h"
@ -28,6 +29,7 @@ RemoteClient::RemoteClient(QObject *parent)
RemoteClient::~RemoteClient() RemoteClient::~RemoteClient()
{ {
disconnectFromServer(); disconnectFromServer();
thread()->quit();
} }
void RemoteClient::slotSocketError(QAbstractSocket::SocketError /*error*/) void RemoteClient::slotSocketError(QAbstractSocket::SocketError /*error*/)
@ -58,7 +60,7 @@ void RemoteClient::processServerIdentificationEvent(const Event_ServerIdentifica
cmdLogin.set_password(password.toStdString()); cmdLogin.set_password(password.toStdString());
PendingCommand *pend = prepareSessionCommand(cmdLogin); 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); sendCommand(pend);
} }

View file

@ -249,7 +249,7 @@ void RemoteDeckList_TreeModel::removeNode(RemoteDeckList_TreeModel::Node *node)
void RemoteDeckList_TreeModel::refreshTree() void RemoteDeckList_TreeModel::refreshTree()
{ {
PendingCommand *pend = client->prepareSessionCommand(Command_DeckList()); 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); client->sendCommand(pend);
} }

View file

@ -207,7 +207,7 @@ void RemoteReplayList_TreeModel::clearTree()
void RemoteReplayList_TreeModel::refreshTree() void RemoteReplayList_TreeModel::refreshTree()
{ {
PendingCommand *pend = client->prepareSessionCommand(Command_ReplayList()); 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); client->sendCommand(pend);
} }

View file

@ -171,14 +171,14 @@ void TabDeckStorage::actUpload()
cmd.set_deck_list(deck.writeToString_Native().toStdString()); cmd.set_deck_list(deck.writeToString_Native().toStdString());
PendingCommand *pend = client->prepareSessionCommand(cmd); 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); 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 Response_DeckUpload &resp = r.GetExtension(Response_DeckUpload::ext);
const Command_DeckUpload &cmd = static_cast<const Command_DeckUpload &>(static_cast<PendingCommand *>(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()))); serverDirView->addFileToTree(resp.new_file(), serverDirView->getNodeByPath(QString::fromStdString(cmd.path())));
} }
@ -193,7 +193,7 @@ void TabDeckStorage::actOpenRemoteDeck()
cmd.set_deck_id(curRight->getId()); cmd.set_deck_id(curRight->getId());
PendingCommand *pend = client->prepareSessionCommand(cmd); 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); client->sendCommand(pend);
} }
@ -228,16 +228,14 @@ void TabDeckStorage::actDownload()
PendingCommand *pend = client->prepareSessionCommand(cmd); PendingCommand *pend = client->prepareSessionCommand(cmd);
pend->setExtraData(filePath); 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); 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); const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext);
QString filePath = extraData.toString();
PendingCommand *pend = static_cast<PendingCommand *>(sender());
QString filePath = pend->getExtraData().toString();
DeckList deck(QString::fromStdString(resp.deck())); DeckList deck(QString::fromStdString(resp.deck()));
deck.saveToFile(filePath, DeckList::CockatriceFormat); deck.saveToFile(filePath, DeckList::CockatriceFormat);
@ -263,16 +261,16 @@ void TabDeckStorage::actNewFolder()
cmd.set_dir_name(folderName.toStdString()); cmd.set_dir_name(folderName.toStdString());
PendingCommand *pend = client->prepareSessionCommand(cmd); 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); 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; return;
const Command_DeckNewDir &cmd = static_cast<const Command_DeckNewDir &>(static_cast<PendingCommand *>(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()))); serverDirView->addFolderToTree(QString::fromStdString(cmd.dir_name()), serverDirView->getNodeByPath(QString::fromStdString(cmd.path())));
} }
@ -290,34 +288,34 @@ void TabDeckStorage::actDelete()
Command_DeckDelDir cmd; Command_DeckDelDir cmd;
cmd.set_path(path.toStdString()); cmd.set_path(path.toStdString());
pend = client->prepareSessionCommand(cmd); 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 { } else {
Command_DeckDel cmd; Command_DeckDel cmd;
cmd.set_deck_id(dynamic_cast<RemoteDeckList_TreeModel::FileNode *>(curRight)->getId()); cmd.set_deck_id(dynamic_cast<RemoteDeckList_TreeModel::FileNode *>(curRight)->getId());
pend = client->prepareSessionCommand(cmd); 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); 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; return;
const Command_DeckDel &cmd = static_cast<const Command_DeckDel &>(static_cast<PendingCommand *>(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()); RemoteDeckList_TreeModel::Node *toDelete = serverDirView->getNodeById(cmd.deck_id());
if (toDelete) if (toDelete)
serverDirView->removeNode(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; return;
const Command_DeckDelDir &cmd = static_cast<const Command_DeckDelDir &>(static_cast<PendingCommand *>(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())); RemoteDeckList_TreeModel::Node *toDelete = serverDirView->getNodeByPath(QString::fromStdString(cmd.path()));
if (toDelete) if (toDelete)
serverDirView->removeNode(toDelete); serverDirView->removeNode(toDelete);

View file

@ -2,7 +2,6 @@
#define TAB_DECK_STORAGE_H #define TAB_DECK_STORAGE_H
#include "tab.h" #include "tab.h"
#include "pb/response.pb.h"
class AbstractClient; class AbstractClient;
class QTreeView; class QTreeView;
@ -13,6 +12,8 @@ class QTreeWidget;
class QTreeWidgetItem; class QTreeWidgetItem;
class QGroupBox; class QGroupBox;
class RemoteDeckList_TreeWidget; class RemoteDeckList_TreeWidget;
class CommandContainer;
class Response;
class TabDeckStorage : public Tab { class TabDeckStorage : public Tab {
Q_OBJECT Q_OBJECT
@ -30,20 +31,20 @@ private slots:
void actOpenLocalDeck(); void actOpenLocalDeck();
void actUpload(); void actUpload();
void uploadFinished(const Response &r); void uploadFinished(const Response &r, const CommandContainer &commandContainer);
void actOpenRemoteDeck(); void actOpenRemoteDeck();
void openRemoteDeckFinished(const Response &r); void openRemoteDeckFinished(const Response &r);
void actDownload(); void actDownload();
void downloadFinished(const Response &r); void downloadFinished(const Response &r, const CommandContainer &commandContainer, const QVariant &extraData);
void actNewFolder(); void actNewFolder();
void newFolderFinished(Response::ResponseCode resp); void newFolderFinished(const Response &response, const CommandContainer &commandContainer);
void actDelete(); void actDelete();
void deleteFolderFinished(Response::ResponseCode resp); void deleteFolderFinished(const Response &response, const CommandContainer &commandContainer);
void deleteDeckFinished(Response::ResponseCode resp); void deleteDeckFinished(const Response &response, const CommandContainer &commandContainer);
public: public:
TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_client); TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_client);
void retranslateUi(); void retranslateUi();

View file

@ -147,7 +147,7 @@ void DeckViewContainer::loadLocalDeck()
Command_DeckSelect cmd; Command_DeckSelect cmd;
cmd.set_deck(deck->writeToString_Native().toStdString()); cmd.set_deck(deck->writeToString_Native().toStdString());
PendingCommand *pend = static_cast<TabGame *>(parent())->prepareGameCommand(cmd); PendingCommand *pend = static_cast<TabGame *>(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<TabGame *>(parent())->sendGameCommand(pend, playerId); static_cast<TabGame *>(parent())->sendGameCommand(pend, playerId);
} }
@ -158,7 +158,7 @@ void DeckViewContainer::loadRemoteDeck()
Command_DeckSelect cmd; Command_DeckSelect cmd;
cmd.set_deck_id(dlg.getDeckId()); cmd.set_deck_id(dlg.getDeckId());
PendingCommand *pend = static_cast<TabGame *>(parent())->prepareGameCommand(cmd); PendingCommand *pend = static_cast<TabGame *>(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<TabGame *>(parent())->sendGameCommand(pend, playerId); static_cast<TabGame *>(parent())->sendGameCommand(pend, playerId);
} }
} }

View file

@ -60,7 +60,7 @@ void TabMessage::sendMessage()
cmd.set_message(sayEdit->text().toStdString()); cmd.set_message(sayEdit->text().toStdString());
PendingCommand *pend = client->prepareSessionCommand(cmd); 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); client->sendCommand(pend);
sayEdit->clear(); sayEdit->clear();

View file

@ -140,7 +140,7 @@ void TabReplays::actOpenRemoteReplay()
cmd.set_replay_id(curRight->replay_id()); cmd.set_replay_id(curRight->replay_id());
PendingCommand *pend = client->prepareSessionCommand(cmd); 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); client->sendCommand(pend);
} }
@ -175,16 +175,14 @@ void TabReplays::actDownload()
PendingCommand *pend = client->prepareSessionCommand(cmd); PendingCommand *pend = client->prepareSessionCommand(cmd);
pend->setExtraData(filePath); 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); 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); const Response_ReplayDownload &resp = r.GetExtension(Response_ReplayDownload::ext);
QString filePath = extraData.toString();
PendingCommand *pend = static_cast<PendingCommand *>(sender());
QString filePath = pend->getExtraData().toString();
const std::string &data = resp.replay_data(); const std::string &data = resp.replay_data();
QFile f(filePath); QFile f(filePath);
@ -204,17 +202,16 @@ void TabReplays::actKeepRemoteReplay()
cmd.set_do_not_hide(!curRight->do_not_hide()); cmd.set_do_not_hide(!curRight->do_not_hide());
PendingCommand *pend = client->prepareSessionCommand(cmd); 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); client->sendCommand(pend);
} }
void TabReplays::keepRemoteReplayFinished(const Response &r) void TabReplays::keepRemoteReplayFinished(const Response &r, const CommandContainer &commandContainer)
{ {
if (r.response_code() != Response::RespOk) if (r.response_code() != Response::RespOk)
return; return;
PendingCommand *pend = static_cast<PendingCommand *>(sender()); const Command_ReplayModifyMatch &cmd = commandContainer.session_command(0).GetExtension(Command_ReplayModifyMatch::ext);
const Command_ReplayModifyMatch &cmd = pend->getCommandContainer().session_command(0).GetExtension(Command_ReplayModifyMatch::ext);
ServerInfo_ReplayMatch temp; ServerInfo_ReplayMatch temp;
temp.set_do_not_hide(cmd.do_not_hide()); temp.set_do_not_hide(cmd.do_not_hide());

View file

@ -13,6 +13,7 @@ class QGroupBox;
class RemoteReplayList_TreeWidget; class RemoteReplayList_TreeWidget;
class GameReplay; class GameReplay;
class Event_ReplayAdded; class Event_ReplayAdded;
class CommandContainer;
class TabReplays : public Tab { class TabReplays : public Tab {
Q_OBJECT Q_OBJECT
@ -33,10 +34,10 @@ private slots:
void openRemoteReplayFinished(const Response &r); void openRemoteReplayFinished(const Response &r);
void actDownload(); void actDownload();
void downloadFinished(const Response &r); void downloadFinished(const Response &r, const CommandContainer &commandContainer, const QVariant &extraData);
void actKeepRemoteReplay(); void actKeepRemoteReplay();
void keepRemoteReplayFinished(const Response &r); void keepRemoteReplayFinished(const Response &r, const CommandContainer &commandContainer);
void replayAddedEventReceived(const Event_ReplayAdded &event); void replayAddedEventReceived(const Event_ReplayAdded &event);
signals: signals:

View file

@ -120,7 +120,7 @@ void TabRoom::sendMessage()
cmd.set_message(sayEdit->text().toStdString()); cmd.set_message(sayEdit->text().toStdString());
PendingCommand *pend = prepareRoomCommand(cmd); 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); sendRoomCommand(pend);
sayEdit->clear(); sayEdit->clear();
} }

View file

@ -105,7 +105,7 @@ void RoomSelector::joinRoom(int id, bool setCurrent)
PendingCommand *pend = client->prepareSessionCommand(cmd); PendingCommand *pend = client->prepareSessionCommand(cmd);
pend->setExtraData(setCurrent); 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); client->sendCommand(pend);
} }
@ -119,13 +119,13 @@ void RoomSelector::joinClicked()
joinRoom(twi->data(0, Qt::UserRole).toInt(), true); 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) if (r.response_code() != Response::RespOk)
return; return;
const Response_JoinRoom &resp = r.GetExtension(Response_JoinRoom::ext); const Response_JoinRoom &resp = r.GetExtension(Response_JoinRoom::ext);
emit roomJoined(resp.room_info(), static_cast<PendingCommand *>(sender())->getExtraData().toBool()); emit roomJoined(resp.room_info(), extraData.toBool());
} }
TabServer::TabServer(TabSupervisor *_tabSupervisor, AbstractClient *_client, QWidget *parent) TabServer::TabServer(TabSupervisor *_tabSupervisor, AbstractClient *_client, QWidget *parent)

View file

@ -16,6 +16,7 @@ class Event_ListRooms;
class Event_ServerMessage; class Event_ServerMessage;
class Response; class Response;
class ServerInfo_Room; class ServerInfo_Room;
class CommandContainer;
class RoomSelector : public QGroupBox { class RoomSelector : public QGroupBox {
Q_OBJECT Q_OBJECT
@ -28,7 +29,7 @@ private:
private slots: private slots:
void processListRoomsEvent(const Event_ListRooms &event); void processListRoomsEvent(const Event_ListRooms &event);
void joinClicked(); void joinClicked();
void joinFinished(const Response &resp); void joinFinished(const Response &resp, const CommandContainer &commandContainer, const QVariant &extraData);
signals: signals:
void roomJoined(const ServerInfo_Room &info, bool setCurrent); void roomJoined(const ServerInfo_Room &info, bool setCurrent);
public: public:

View file

@ -35,7 +35,7 @@ TabUserLists::TabUserLists(TabSupervisor *_tabSupervisor, AbstractClient *_clien
connect(client, SIGNAL(removeFromListEventReceived(const Event_RemoveFromList &)), this, SLOT(processRemoveFromListEvent(const Event_RemoveFromList &))); connect(client, SIGNAL(removeFromListEventReceived(const Event_RemoveFromList &)), this, SLOT(processRemoveFromListEvent(const Event_RemoveFromList &)));
PendingCommand *pend = client->prepareSessionCommand(Command_ListUsers()); 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); client->sendCommand(pend);
QVBoxLayout *vbox = new QVBoxLayout; QVBoxLayout *vbox = new QVBoxLayout;

View file

@ -87,7 +87,7 @@ void UserInfoBox::updateInfo(const QString &userName)
cmd.set_user_name(userName.toStdString()); cmd.set_user_name(userName.toStdString());
PendingCommand *pend = client->prepareSessionCommand(cmd); 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); client->sendCommand(pend);
} }

View file

@ -305,10 +305,10 @@ void UserList::userClicked(QTreeWidgetItem *item, int /*column*/)
emit openMessageDialog(item->data(2, Qt::UserRole).toString(), true); 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 Response_GetGamesOfUser &response = resp.GetExtension(Response_GetGamesOfUser::ext);
const Command_GetGamesOfUser &cmd = static_cast<const Command_GetGamesOfUser &>(static_cast<PendingCommand *>(sender())->getCommandContainer().session_command(0).GetExtension(Command_GetGamesOfUser::ext)); const Command_GetGamesOfUser &cmd = commandContainer.session_command(0).GetExtension(Command_GetGamesOfUser::ext);
QMap<int, GameTypeMap> gameTypeMap; QMap<int, GameTypeMap> gameTypeMap;
QMap<int, QString> roomMap; QMap<int, QString> roomMap;
@ -429,7 +429,7 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index)
cmd.set_user_name(userName.toStdString()); cmd.set_user_name(userName.toStdString());
PendingCommand *pend = client->prepareSessionCommand(cmd); 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); client->sendCommand(pend);
} else if (actionClicked == aAddToIgnoreList) { } else if (actionClicked == aAddToIgnoreList) {
@ -449,7 +449,7 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index)
cmd.set_user_name(userName.toStdString()); cmd.set_user_name(userName.toStdString());
PendingCommand *pend = client->prepareSessionCommand(cmd); 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); client->sendCommand(pend);
} }

View file

@ -16,6 +16,7 @@ class QSpinBox;
class QRadioButton; class QRadioButton;
class QPlainTextEdit; class QPlainTextEdit;
class Response; class Response;
class CommandContainer;
class BanDialog : public QDialog { class BanDialog : public QDialog {
Q_OBJECT Q_OBJECT
@ -68,7 +69,7 @@ private slots:
void userClicked(QTreeWidgetItem *item, int column); void userClicked(QTreeWidgetItem *item, int column);
void banUser_processUserInfoResponse(const Response &resp); void banUser_processUserInfoResponse(const Response &resp);
void banUser_dialogFinished(); void banUser_dialogFinished();
void gamesOfUserReceived(const Response &resp); void gamesOfUserReceived(const Response &resp, const CommandContainer &commandContainer);
signals: signals:
void openMessageDialog(const QString &userName, bool focus); void openMessageDialog(const QString &userName, bool focus);
void addBuddy(const QString &userName); void addBuddy(const QString &userName);

View file

@ -26,6 +26,7 @@
#include <QInputDialog> #include <QInputDialog>
#include <QFile> #include <QFile>
#include <QFileDialog> #include <QFileDialog>
#include <QThread>
#include "main.h" #include "main.h"
#include "window_main.h" #include "window_main.h"
@ -337,7 +338,7 @@ MainWindow::MainWindow(QWidget *parent)
{ {
QPixmapCache::setCacheLimit(200000); 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(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(serverShutdownEventReceived(const Event_ServerShutdown &)), this, SLOT(processServerShutdownEvent(const Event_ServerShutdown &)));
connect(client, SIGNAL(serverError(Response::ResponseCode, QString)), this, SLOT(serverError(Response::ResponseCode, QString))); 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(statusChanged(ClientStatus)), this, SLOT(statusChanged(ClientStatus)));
connect(client, SIGNAL(protocolVersionMismatch(int, int)), this, SLOT(protocolVersionMismatch(int, int))); connect(client, SIGNAL(protocolVersionMismatch(int, int)), this, SLOT(protocolVersionMismatch(int, int)));
connect(client, SIGNAL(userInfoChanged(const ServerInfo_User &)), this, SLOT(userInfoReceived(const ServerInfo_User &))); 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; tabSupervisor = new TabSupervisor;
connect(tabSupervisor, SIGNAL(setMenu(QMenu *)), this, SLOT(updateTabMenu(QMenu *))); connect(tabSupervisor, SIGNAL(setMenu(QMenu *)), this, SLOT(updateTabMenu(QMenu *)));
@ -361,6 +366,12 @@ MainWindow::MainWindow(QWidget *parent)
resize(900, 700); resize(900, 700);
} }
MainWindow::~MainWindow()
{
client->deleteLater();
clientThread->wait();
}
void MainWindow::closeEvent(QCloseEvent *event) void MainWindow::closeEvent(QCloseEvent *event)
{ {
if (tabSupervisor->getGameCount()) { if (tabSupervisor->getGameCount()) {

View file

@ -29,6 +29,7 @@ class RemoteClient;
class LocalClient; class LocalClient;
class LocalServer; class LocalServer;
class ServerInfo_User; class ServerInfo_User;
class QThread;
class MainWindow : public QMainWindow { class MainWindow : public QMainWindow {
Q_OBJECT Q_OBJECT
@ -66,9 +67,12 @@ private:
TabSupervisor *tabSupervisor; TabSupervisor *tabSupervisor;
RemoteClient *client; RemoteClient *client;
QThread *clientThread;
LocalServer *localServer; LocalServer *localServer;
public: public:
MainWindow(QWidget *parent = 0); MainWindow(QWidget *parent = 0);
~MainWindow();
protected: protected:
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent *event);
void changeEvent(QEvent *event); void changeEvent(QEvent *event);

View file

@ -48,7 +48,7 @@ void ZoneViewZone::initializeCards(const QList<const ServerInfo_Card *> &cardLis
cmd.set_number_cards(numberCards); cmd.set_number_cards(numberCards);
PendingCommand *pend = player->prepareGameCommand(cmd); 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); player->sendGameCommand(pend);
} else { } else {
const CardList &c = origZone->getCards(); const CardList &c = origZone->getCards();