From 42ff71aaa8d3cee9e348a45758c56c380a4f1b45 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Sun, 8 Jul 2007 14:36:08 +0000 Subject: [PATCH] I am starting to clean up the mess that is Global right now, and to implement a clean infrastructure for storing settings (session-wide and local). First step: Instead of putting synchronization stuff into Global and doing special treatment for signals in Core, we have now a clear interface for handling session-wide data in both Client and CoreSession: Client::storeSessionData(key, data) [static] Client::retrieveSessionData(key, defdata) [static] CoreSession::storeSessionData(key, data) CoreSession::retrieveSessionData(key, defdata) CoreSession also cares for persistent storage using QSettings. It should be noted that the client-side store function just sends a signal to the core, and the client-side data is actually updated upon receipt of the sync signal from core. IOW, stuff is not stored immediately, and you should thus not rely on it being available right after your call to storeSessionData(). If this is a bad idea, we might change this behavior at some point. Note: The code has not yet been tested thoroughly, and it's only the first step anyway. --- src/client/client.cpp | 21 +++++++++++++++++++++ src/client/client.h | 10 ++++++++++ src/client/clientproxy.cpp | 1 + src/client/clientproxy.h | 3 +++ src/common/proxy_common.h | 4 ++-- src/common/util.cpp | 2 +- src/core/coreproxy.cpp | 2 ++ src/core/coreproxy.h | 2 ++ src/core/coresession.cpp | 34 ++++++++++++++++++++++++++++++++++ src/core/coresession.h | 14 ++++++++++++++ 10 files changed, 90 insertions(+), 3 deletions(-) diff --git a/src/client/client.cpp b/src/client/client.cpp index 6be7e077..9a74119d 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -77,6 +77,8 @@ void Client::init() { connect(Global::instance(), SIGNAL(dataPutLocally(UserId, QString)), this, SLOT(updateCoreData(UserId, QString))); connect(clientProxy, SIGNAL(csUpdateGlobalData(QString, QVariant)), this, SLOT(updateLocalData(QString, QVariant))); + connect(this, SIGNAL(sendSessionData(const QString &, const QVariant &)), clientProxy, SLOT(gsSessionDataChanged(const QString &, const QVariant &))); + connect(clientProxy, SIGNAL(csSessionDataChanged(const QString &, const QVariant &)), this, SLOT(recvSessionData(const QString &, const QVariant &))); connect(clientProxy, SIGNAL(send(ClientSignal, QVariant, QVariant, QVariant)), this, SLOT(recvProxySignal(ClientSignal, QVariant, QVariant, QVariant))); connect(clientProxy, SIGNAL(csServerState(QString, QVariant)), this, SLOT(recvNetworkState(QString, QVariant))); @@ -196,6 +198,25 @@ void Client::updateLocalData(QString key, QVariant data) { Global::updateData(key, data); } +void Client::recvSessionData(const QString &key, const QVariant &data) { + sessionData[key] = data; + emit sessionDataChanged(key, data); + emit sessionDataChanged(key); + qDebug() << "stored data in client:" << key; +} + +void Client::storeSessionData(const QString &key, const QVariant &data) { + // Not sure if this is a good idea, but we'll try it anyway: + // Calling this function only sends a signal to core. Data is stored upon reception of the update signal, + // rather than immediately. + emit instance()->sendSessionData(key, data); +} + +QVariant Client::retrieveSessionData(const QString &key, const QVariant &def) { + if(instance()->sessionData.contains(key)) return instance()->sessionData[key]; + else return def; +} + void Client::recvProxySignal(ClientSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { if(clientMode == LocalCore) return; QList sigdata; diff --git a/src/client/client.h b/src/client/client.h index 452bed07..1b3a4e8d 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -55,6 +55,9 @@ class Client : public QObject { static bool isConnected(); + static void storeSessionData(const QString &key, const QVariant &data); + static QVariant retrieveSessionData(const QString &key, const QVariant &def = QVariant()); + signals: void sendInput(BufferId, QString message); void showBuffer(Buffer *); @@ -72,6 +75,10 @@ class Client : public QObject { void connected(); void disconnected(); + void sessionDataChanged(const QString &key); + void sessionDataChanged(const QString &key, const QVariant &data); + void sendSessionData(const QString &key, const QVariant &data); + public slots: //void selectBuffer(Buffer *); //void connectToLocalCore(); @@ -81,6 +88,7 @@ class Client : public QObject { private slots: void updateCoreData(UserId, QString); void updateLocalData(QString, QVariant); + void recvSessionData(const QString &key, const QVariant &data); void recvProxySignal(ClientSignal sig, QVariant arg1, QVariant arg2, QVariant arg3); void serverError(QAbstractSocket::SocketError); @@ -134,6 +142,8 @@ class Client : public QObject { QTimer *layoutTimer; QList layoutQueue; + + VarMap sessionData; }; #endif diff --git a/src/client/clientproxy.cpp b/src/client/clientproxy.cpp index 3614aa29..6118ff1c 100644 --- a/src/client/clientproxy.cpp +++ b/src/client/clientproxy.cpp @@ -48,6 +48,7 @@ void ClientProxy::recv(CoreSignal sig, QVariant arg1, QVariant arg2, QVariant ar case CS_SERVER_DISCONNECTED: emit csServerDisconnected(arg1.toString()); break; case CS_UPDATE_GLOBAL_DATA: emit csUpdateGlobalData(arg1.toString(), arg2); break; //case CS_GLOBAL_DATA_CHANGED: emit csGlobalDataChanged(arg1.toString()); break; + case CS_SESSION_DATA_CHANGED: emit csSessionDataChanged(arg1.toString(), arg2); break; case CS_DISPLAY_MSG: emit csDisplayMsg(arg1.value()); break; case CS_DISPLAY_STATUS_MSG: emit csDisplayStatusMsg(arg1.toString(), arg2.toString()); break; case CS_MODE_SET: emit csModeSet(arg1.toString(), arg2.toString(), arg3.toString()); break; diff --git a/src/client/clientproxy.h b/src/client/clientproxy.h index e66aa65a..33b34030 100644 --- a/src/client/clientproxy.h +++ b/src/client/clientproxy.h @@ -22,6 +22,7 @@ #define _CLIENTPROXY_H_ #include +#include #include "proxy_common.h" #include "message.h" @@ -35,6 +36,7 @@ class ClientProxy : public QObject { static void destroy(); public slots: + inline void gsSessionDataChanged(const QString &key, const QVariant &data) { send(GS_SESSION_DATA_CHANGED, key, data); } inline void gsUserInput(BufferId id, QString msg) { send(GS_USER_INPUT, QVariant::fromValue(id), msg); } inline void gsRequestConnect(QStringList networks) { send(GS_REQUEST_CONNECT, networks); } inline void gsImportBacklog() { send(GS_IMPORT_BACKLOG); } @@ -52,6 +54,7 @@ class ClientProxy : public QObject { void csDisplayStatusMsg(QString, QString); void csUpdateGlobalData(QString key, QVariant data); void csGlobalDataChanged(QString key); + void csSessionDataChanged(const QString &key, const QVariant &data); void csModeSet(QString, QString, QString); void csTopicSet(QString, QString, QString); void csNickAdded(QString, QString, VarMap); diff --git a/src/common/proxy_common.h b/src/common/proxy_common.h index 609b5933..05405747 100644 --- a/src/common/proxy_common.h +++ b/src/common/proxy_common.h @@ -22,12 +22,12 @@ #define _PROXY_COMMON_H_ enum ClientSignal { GS_CLIENT_INIT, GS_USER_INPUT, GS_REQUEST_CONNECT, GS_UPDATE_GLOBAL_DATA, GS_IMPORT_BACKLOG, - GS_REQUEST_BACKLOG, GS_REQUEST_NETWORK_STATES + GS_REQUEST_BACKLOG, GS_REQUEST_NETWORK_STATES, GS_SESSION_DATA_CHANGED }; enum CoreSignal { CS_CORE_STATE, CS_SERVER_CONNECTED, CS_SERVER_DISCONNECTED, CS_SERVER_STATE, - CS_DISPLAY_MSG, CS_DISPLAY_STATUS_MSG, CS_UPDATE_GLOBAL_DATA, + CS_DISPLAY_MSG, CS_DISPLAY_STATUS_MSG, CS_UPDATE_GLOBAL_DATA, CS_SESSION_DATA_CHANGED, CS_MODE_SET, CS_TOPIC_SET, CS_SET_NICKS, CS_NICK_ADDED, CS_NICK_REMOVED, CS_NICK_RENAMED, CS_NICK_UPDATED, CS_OWN_NICK_SET, CS_QUERY_REQUESTED, CS_BACKLOG_DATA, CS_UPDATE_BUFFERID diff --git a/src/common/util.cpp b/src/common/util.cpp index b5095d9e..1c3d9058 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -56,7 +56,7 @@ QString decodeString(QByteArray input, QString encoding) { cnt--; continue; } - if(!(input[i] & 0x80)) continue; // 7 bit is always ok + if((input[i] & 0x80) == 0x00) continue; // 7 bit is always ok if((input[i] & 0xf8) == 0xf0) { cnt = 3; continue; } // 4-byte char 11110xxx 10yyyyyy 10zzzzzz 10vvvvvv if((input[i] & 0xf0) == 0xe0) { cnt = 2; continue; } // 3-byte char 1110xxxx 10yyyyyy 10zzzzzz if((input[i] & 0xe0) == 0xc0) { cnt = 1; continue; } // 2-byte char 110xxxxx 10yyyyyy diff --git a/src/core/coreproxy.cpp b/src/core/coreproxy.cpp index f10af419..e6b9b493 100644 --- a/src/core/coreproxy.cpp +++ b/src/core/coreproxy.cpp @@ -19,6 +19,7 @@ ***************************************************************************/ #include "coreproxy.h" +#include CoreProxy::CoreProxy() { @@ -28,6 +29,7 @@ void CoreProxy::recv(ClientSignal sig, QVariant arg1, QVariant arg2, QVariant ar //qDebug() << "[CORE] Received signal" << sig << ":" << arg1<(), arg2.toString()); break; case GS_REQUEST_CONNECT: emit gsRequestConnect(arg1.toStringList()); break; case GS_IMPORT_BACKLOG: emit gsImportBacklog(); break; diff --git a/src/core/coreproxy.h b/src/core/coreproxy.h index fbb34b68..12f5d845 100644 --- a/src/core/coreproxy.h +++ b/src/core/coreproxy.h @@ -42,6 +42,7 @@ class CoreProxy : public QObject { public slots: inline void csUpdateGlobalData(QString key, QVariant data) { send(CS_UPDATE_GLOBAL_DATA, key, data); } + inline void csSessionDataChanged(const QString &key, const QVariant &data) { send(CS_SESSION_DATA_CHANGED, key, data); } inline void csServerConnected(QString net) { send(CS_SERVER_CONNECTED, net); } inline void csServerDisconnected(QString net) { send(CS_SERVER_DISCONNECTED, net); } inline void csServerState(QString net, VarMap data) { send(CS_SERVER_STATE, net, data); } @@ -62,6 +63,7 @@ class CoreProxy : public QObject { signals: void gsPutGlobalData(QString, QVariant); + void gsSessionDataChanged(const QString &, const QVariant &); void gsUserInput(BufferId, QString); void gsRequestConnect(QStringList networks); void gsImportBacklog(); diff --git a/src/core/coresession.cpp b/src/core/coresession.cpp index ae0bdb28..49467118 100644 --- a/src/core/coresession.cpp +++ b/src/core/coresession.cpp @@ -26,6 +26,14 @@ CoreSession::CoreSession(UserId uid, Storage *_storage) : user(uid), storage(_storage) { coreProxy = new CoreProxy(); + QSettings s; + s.beginGroup(QString("SessionData/%1").arg(user)); + mutex.lock(); + foreach(QString key, s.allKeys()) { + sessionData[key] = s.value(key); + } + mutex.unlock(); + connect(coreProxy, SIGNAL(send(CoreSignal, QVariant, QVariant, QVariant)), this, SIGNAL(proxySignal(CoreSignal, QVariant, QVariant, QVariant))); connect(coreProxy, SIGNAL(requestServerStates()), this, SIGNAL(serverStateRequested())); connect(coreProxy, SIGNAL(gsRequestConnect(QStringList)), this, SLOT(connectToIrc(QStringList))); @@ -40,6 +48,8 @@ CoreSession::CoreSession(UserId uid, Storage *_storage) : user(uid), storage(_st connect(storage, SIGNAL(bufferIdUpdated(BufferId)), coreProxy, SLOT(csUpdateBufferId(BufferId))); connect(Global::instance(), SIGNAL(dataUpdatedRemotely(UserId, QString)), this, SLOT(globalDataUpdated(UserId, QString))); connect(Global::instance(), SIGNAL(dataPutLocally(UserId, QString)), this, SLOT(globalDataUpdated(UserId, QString))); + connect(this, SIGNAL(sessionDataChanged(const QString &, const QVariant &)), coreProxy, SLOT(csSessionDataChanged(const QString &, const QVariant &))); + connect(coreProxy, SIGNAL(gsSessionDataChanged(const QString &, const QVariant &)), this, SLOT(storeSessionData(const QString &, const QVariant &))); } CoreSession::~CoreSession() { @@ -61,6 +71,27 @@ void CoreSession::globalDataUpdated(UserId uid, QString key) { s.setValue(QString("Global/%1/").arg(userId())+key, data); } +void CoreSession::storeSessionData(const QString &key, const QVariant &data) { + QSettings s; + s.beginGroup(QString("SessionData/%1").arg(user)); + mutex.lock(); + sessionData[key] = data; + s.setValue(key, data); + mutex.unlock(); + s.endGroup(); + emit sessionDataChanged(key, data); + emit sessionDataChanged(key); +} + +QVariant CoreSession::retrieveSessionData(const QString &key, const QVariant &def) { + QVariant data; + mutex.lock(); + if(!sessionData.contains(key)) data = def; + else data = sessionData[key]; + mutex.unlock(); + return data; +} + void CoreSession::connectToIrc(QStringList networks) { foreach(QString net, networks) { if(servers.contains(net)) { @@ -147,6 +178,9 @@ QVariant CoreSession::sessionState() { QList bufs; foreach(BufferId id, storage->requestBuffers(user)) { bufs.append(QVariant::fromValue(id)); } v["Buffers"] = bufs; + mutex.lock(); + v["SessionData"] = sessionData; + mutex.unlock(); return v; } diff --git a/src/core/coresession.h b/src/core/coresession.h index 24d3d8d0..f9336b27 100644 --- a/src/core/coresession.h +++ b/src/core/coresession.h @@ -40,6 +40,15 @@ class CoreSession : public QObject { QList buffers() const; UserId userId() const; QVariant sessionState(); + + public slots: + //! Store a piece session-wide data and distribute it to connected clients. + void storeSessionData(const QString &key, const QVariant &data); + + public: + //! Retrieve a piece of session-wide data. + QVariant retrieveSessionData(const QString &key, const QVariant &def = QVariant()); + CoreProxy *proxy(); public slots: @@ -63,6 +72,8 @@ class CoreSession : public QObject { void backlogData(BufferId, QList, bool done); void bufferIdUpdated(BufferId); + void sessionDataChanged(const QString &key); + void sessionDataChanged(const QString &key, const QVariant &data); private slots: //void recvProxySignal(CoreSignal, QVariant arg1 = QVariant(), QVariant arg2 = QVariant(), QVariant arg3 = QVariant()); @@ -78,6 +89,9 @@ class CoreSession : public QObject { QHash servers; UserId user; + VarMap sessionData; + QMutex mutex; + }; #endif -- 2.20.1