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.
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)));
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<QVariant> sigdata;
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 *);
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();
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);
QTimer *layoutTimer;
QList<Buffer *> layoutQueue;
+
+ VarMap sessionData;
};
#endif
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<Message>()); 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;
#define _CLIENTPROXY_H_
#include <QStringList>
+#include <QtDebug>
#include "proxy_common.h"
#include "message.h"
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); }
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);
#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
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
***************************************************************************/
#include "coreproxy.h"
+#include <QtDebug>
CoreProxy::CoreProxy() {
//qDebug() << "[CORE] Received signal" << sig << ":" << arg1<<arg2<<arg3;
switch(sig) {
case GS_UPDATE_GLOBAL_DATA: emit gsPutGlobalData(arg1.toString(), arg2); break;
+ case GS_SESSION_DATA_CHANGED: emit gsSessionDataChanged(arg1.toString(), arg2); break;
case GS_USER_INPUT: emit gsUserInput(arg1.value<BufferId>(), arg2.toString()); break;
case GS_REQUEST_CONNECT: emit gsRequestConnect(arg1.toStringList()); break;
case GS_IMPORT_BACKLOG: emit gsImportBacklog(); break;
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); }
signals:
void gsPutGlobalData(QString, QVariant);
+ void gsSessionDataChanged(const QString &, const QVariant &);
void gsUserInput(BufferId, QString);
void gsRequestConnect(QStringList networks);
void gsImportBacklog();
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)));
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() {
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)) {
QList<QVariant> bufs;
foreach(BufferId id, storage->requestBuffers(user)) { bufs.append(QVariant::fromValue(id)); }
v["Buffers"] = bufs;
+ mutex.lock();
+ v["SessionData"] = sessionData;
+ mutex.unlock();
return v;
}
QList<BufferId> 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:
void backlogData(BufferId, QList<QVariant>, 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());
QHash<QString, Server *> servers;
UserId user;
+ VarMap sessionData;
+ QMutex mutex;
+
};
#endif