From: Manuel Nickschas Date: Sat, 10 Oct 2009 10:33:17 +0000 (+0200) Subject: Introduce a mechanism to test for certain core features X-Git-Tag: 0.6-beta1~99 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=7aa691713f4185fe142f54e14d6b623ee706f77a Introduce a mechanism to test for certain core features We sometimes implement features that needs an up-to-date core to work correctly, but not always a protocol bump is justified (because it's just a giant PITA). So we now have Client::coreFeatures() that returns a bitmask of such optional features, which can be checked for at runtime and used to disable client features if a too-old core is present. Note that with every protocol bump the feature enum in quassel.h needs to be cleaned, and runtime checks removed. Please mark all such places with a nice FIXME so we can find them easily. --- diff --git a/src/client/client.cpp b/src/client/client.cpp index 84d28ec0..30c11009 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -52,6 +52,7 @@ #include QPointer Client::instanceptr = 0; +Quassel::Features Client::_coreFeatures = 0; /*** Initialization/destruction ***/ @@ -159,6 +160,10 @@ AbstractUi *Client::mainUi() { return instance()->_mainUi; } +void Client::setCoreFeatures(Quassel::Features features) { + _coreFeatures = features; +} + bool Client::isConnected() { return instance()->_connected; } @@ -377,6 +382,8 @@ void Client::disconnectFromCore() { void Client::setDisconnectedFromCore() { _connected = false; + _coreFeatures = 0; + emit disconnected(); emit coreConnectionStateChanged(false); diff --git a/src/client/client.h b/src/client/client.h index 56083a96..53dc7864 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -26,6 +26,7 @@ #include "bufferinfo.h" #include "coreconnection.h" +#include "quassel.h" #include "types.h" class Message; @@ -118,6 +119,7 @@ public: static inline CoreAccountModel *coreAccountModel() { return instance()->_coreAccountModel; } static inline CoreConnection *coreConnection() { return instance()->_coreConnection; } static inline CoreAccount currentCoreAccount() { return coreConnection()->currentAccount(); } + static inline Quassel::Features coreFeatures() { return _coreFeatures; } static bool isConnected(); static bool internalCore(); @@ -200,6 +202,7 @@ private: void init(); static void addNetwork(Network *); + static void setCoreFeatures(Quassel::Features); static inline BufferSyncer *bufferSyncer() { return instance()->_bufferSyncer; } static QPointer instanceptr; @@ -230,6 +233,7 @@ private: QHash _identities; bool _connected; + static Quassel::Features _coreFeatures; QString _debugLogBuffer; QTextStream _debugLog; diff --git a/src/common/quassel.cpp b/src/common/quassel.cpp index 6b7fa78f..e6e20725 100644 --- a/src/common/quassel.cpp +++ b/src/common/quassel.cpp @@ -246,6 +246,14 @@ void Quassel::logFatalMessage(const char *msg) { #endif } +Quassel::Features Quassel::features() { + Features feats = 0; + for(int i = 1; i <= NumFeatures; i<<=1) + feats |= (Feature) i; + + return feats; +} + const QString &Quassel::coreDumpFileName() { if(_coreDumpFileName.isEmpty()) { QDir configDir(configDirPath()); diff --git a/src/common/quassel.h b/src/common/quassel.h index fa7d02c9..b42ee47d 100644 --- a/src/common/quassel.h +++ b/src/common/quassel.h @@ -58,6 +58,25 @@ public: QString organizationDomain; }; + //! A list of features that are optional in core and/or client, but need runtime checking + /** Some features require an uptodate counterpart, but don't justify a protocol break. + * This is what we use this enum for. Add such features to it and check at runtime on the other + * side for their existence. + * + * This list should be cleaned up after every protocol break, as we can assume them to be present then. + */ + enum Feature { + SynchronizedMarkerLine = 0x0001, + + NumFeatures = 0x0001 + }; + Q_DECLARE_FLAGS(Features, Feature); + + //! The features the current version of Quassel supports (\sa Feature) + /** \return An ORed list of all enum values in Feature + */ + static Features features(); + virtual ~Quassel(); static void setupBuildInfo(const QString &generated); @@ -132,6 +151,8 @@ private: static QString _translationDirPath; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(Quassel::Features); + const Quassel::BuildInfo & Quassel::buildInfo() { return _buildInfo; } Quassel::RunMode Quassel::runMode() { return _runMode; } void Quassel::setRunMode(Quassel::RunMode mode) { _runMode = mode; } diff --git a/src/core/core.cpp b/src/core/core.cpp index b24eefb9..20049a8f 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -538,6 +538,8 @@ void Core::processClientMessage(QTcpSocket *socket, const QVariantMap &msg) { .arg(Quassel::buildInfo().buildDate) .arg(updays).arg(uphours,2,10,QChar('0')).arg(upmins,2,10,QChar('0')).arg(startTime().toString(Qt::TextDate)); + reply["CoreFeatures"] = (int)Quassel::features(); + #ifdef HAVE_SSL SslServer *sslServer = qobject_cast(&_server); QSslSocket *sslSocket = qobject_cast(socket);