diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 7b0a455b1..90f4fd6c4 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -35,6 +35,7 @@ #include "retroshare/rsgrouter.h" #include "rsgixs.h" #include "rsgxsutil.h" +#include "rsserver/p3face.h" #include @@ -992,105 +993,67 @@ bool RsGenExchange::checkAuthenFlag(const PrivacyBitPos& pos, const uint8_t& fla } } -void RsGenExchange::receiveChanges(std::vector& changes) -{ - RS_STACK_MUTEX(mGenMtx) ; - -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::receiveChanges()" << std::endl; -#endif - std::vector::iterator vit = changes.begin(); - - for(; vit != changes.end(); ++vit) - { - RsGxsNotify* n = *vit; - RsGxsGroupChange* gc; - RsGxsMsgChange* mc; - if((mc = dynamic_cast(n)) != NULL) - { - mMsgChange.push_back(mc); - } - else if((gc = dynamic_cast(n)) != NULL) - { - mGroupChange.push_back(gc); - } - else - { -#warning cyril: very weird code. Why delete an element without removing it from the array - delete n; - } - } - -} - static void addMessageChanged(std::map > &msgs, const std::map > &msgChanged) { - if (msgs.empty()) { - msgs = msgChanged; - } else { - std::map >::const_iterator mapIt; - for (mapIt = msgChanged.begin(); mapIt != msgChanged.end(); ++mapIt) { - const RsGxsGroupId &grpId = mapIt->first; - const std::vector &srcMsgIds = mapIt->second; - std::vector &destMsgIds = msgs[grpId]; + if (msgs.empty()) { + msgs = msgChanged; + } else { + std::map >::const_iterator mapIt; + for (mapIt = msgChanged.begin(); mapIt != msgChanged.end(); ++mapIt) { + const RsGxsGroupId &grpId = mapIt->first; + const std::vector &srcMsgIds = mapIt->second; + std::vector &destMsgIds = msgs[grpId]; - std::vector::const_iterator msgIt; - for (msgIt = srcMsgIds.begin(); msgIt != srcMsgIds.end(); ++msgIt) { - if (std::find(destMsgIds.begin(), destMsgIds.end(), *msgIt) == destMsgIds.end()) { - destMsgIds.push_back(*msgIt); - } - } - } - } + std::vector::const_iterator msgIt; + for (msgIt = srcMsgIds.begin(); msgIt != srcMsgIds.end(); ++msgIt) { + if (std::find(destMsgIds.begin(), destMsgIds.end(), *msgIt) == destMsgIds.end()) { + destMsgIds.push_back(*msgIt); + } + } + } + } } -void RsGenExchange::msgsChanged(std::map >& msgs, std::map >& msgsMeta) +void RsGenExchange::receiveChanges(std::vector& changes) { - if(mGenMtx.trylock()) - { - while(!mMsgChange.empty()) - { - RsGxsMsgChange* mc = mMsgChange.back(); - if (mc->metaChange()) - { - addMessageChanged(msgsMeta, mc->msgChangeMap); - } - else - { - addMessageChanged(msgs, mc->msgChangeMap); - } - mMsgChange.pop_back(); - delete mc; - } - mGenMtx.unlock(); - } -} +#ifdef GEN_EXCH_DEBUG + std::cerr << "RsGenExchange::receiveChanges()" << std::endl; +#endif + RsGxsChanges out; + out.mService = getTokenService(); -void RsGenExchange::groupsChanged(std::list& grpIds, std::list& grpIdsMeta) -{ - - if(mGenMtx.trylock()) - { - while(!mGroupChange.empty()) - { - RsGxsGroupChange* gc = mGroupChange.back(); - std::list& gList = gc->mGrpIdList; - std::list::iterator lit = gList.begin(); - for(; lit != gList.end(); ++lit) - if (gc->metaChange()) - { - grpIdsMeta.push_back(*lit); - } - else - { - grpIds.push_back(*lit); - } - - mGroupChange.pop_back(); - delete gc; - } - mGenMtx.unlock(); - } + // collect all changes in one GxsChanges object + std::vector::iterator vit = changes.begin(); + for(; vit != changes.end(); ++vit) + { + RsGxsNotify* n = *vit; + RsGxsGroupChange* gc; + RsGxsMsgChange* mc; + if((mc = dynamic_cast(n)) != NULL) + { + if (mc->metaChange()) + { + addMessageChanged(out.mMsgsMeta, mc->msgChangeMap); + } + else + { + addMessageChanged(out.mMsgs, mc->msgChangeMap); + } + } + else if((gc = dynamic_cast(n)) != NULL) + { + if(gc->metaChange()) + { + out.mGrpsMeta.splice(out.mGrpsMeta.end(), gc->mGrpIdList); + } + else + { + out.mGrps.splice(out.mGrps.end(), gc->mGrpIdList); + } + } + delete n; + } + RsServer::notify()->notifyGxsChange(out); } bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) @@ -1118,40 +1081,6 @@ bool RsGenExchange::getServiceStatistic(const uint32_t& token, GxsServiceStatist return mDataAccess->getServiceStatistic(token, stats); } -bool RsGenExchange::updated(bool willCallGrpChanged, bool willCallMsgChanged) -{ - bool changed = false; - - if(mGenMtx.trylock()) - { - changed = (!mGroupChange.empty() || !mMsgChange.empty()); - - if(!willCallGrpChanged) - { - while(!mGroupChange.empty()) - { - RsGxsGroupChange* gc = mGroupChange.back(); - mGroupChange.pop_back(); - delete gc; - } - } - - if(!willCallMsgChanged) - { - while(!mMsgChange.empty()) - { - RsGxsMsgChange* mc = mMsgChange.back(); - mMsgChange.pop_back(); - delete mc; - } - } - - mGenMtx.unlock(); - } - - return changed; -} - bool RsGenExchange::getGroupList(const uint32_t &token, std::list &groupIds) { return mDataAccess->getGroupList(token, groupIds); diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index ed0b123aa..a641fb9f1 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -255,44 +255,6 @@ public: */ virtual void receiveChanges(std::vector& changes); - /*! - * Checks to see if a change has been received for - * for a message or group - * @param willCallGrpChanged if this is set to true, group changed function will return list - * groups that have changed, if false, the group changed list is cleared - * @param willCallMsgChanged if this is set to true, msgChanged function will return map - * messages that have changed, if false, the message changed map is cleared - * @return true if a change has occured for msg or group - * @see groupsChanged - * @see msgsChanged - */ - bool updated(bool willCallGrpChanged = false, bool willCallMsgChanged = false); - - /*! - * The groups changed. \n - * class can reimplement to use to tailor - * the group actually set for ui notification. - * If receivedChanges is not passed RsGxsNotify changes - * this function does nothing - * @param grpIds returns list of grpIds that have changed - * @param grpIdsMeta returns list of grpIds with meta data changes - * @see updated - */ - void groupsChanged(std::list& grpIds, std::list& grpIdsMeta); - - /*! - * The msg changed. \n - * class can reimplement to use to tailor - * the msg actually set for ui notification. - * If receivedChanges is not passed RsGxsNotify changes - * this function does nothing - * @param msgs returns map of message ids that have changed - * @param msgsMeta returns map of message ids with meta data changes - * @see updated - */ - void msgsChanged(std::map >& msgs, std::map >& msgsMeta); - - bool subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe); /*! @@ -878,9 +840,6 @@ private: private: - std::vector mGroupChange; - std::vector mMsgChange; - const uint8_t CREATE_FAIL, CREATE_SUCCESS, CREATE_FAIL_TRY_LATER, SIGN_MAX_ATTEMPTS; const uint8_t SIGN_FAIL, SIGN_SUCCESS, SIGN_FAIL_TRY_LATER; const uint8_t VALIDATE_FAIL, VALIDATE_SUCCESS, VALIDATE_FAIL_TRY_LATER, VALIDATE_MAX_ATTEMPTS; diff --git a/libretroshare/src/pqi/p3notify.cc b/libretroshare/src/pqi/p3notify.cc index c047962e3..59dd5d210 100644 --- a/libretroshare/src/pqi/p3notify.cc +++ b/libretroshare/src/pqi/p3notify.cc @@ -235,6 +235,7 @@ void p3Notify::notifyOwnAvatarChanged () void p3Notify::notifyOwnStatusMessageChanged() { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyOwnStatusMessageChanged() ; } void p3Notify::notifyDiskFull (uint32_t location , uint32_t size_limit_in_MB ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiskFull (location,size_limit_in_MB) ; } void p3Notify::notifyPeerStatusChanged (const std::string& peer_id , uint32_t status ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChanged (peer_id,status) ; } +void p3Notify::notifyGxsChange (const RsGxsChanges& changes) {FOR_ALL_NOTIFY_CLIENTS (*it)->notifyGxsChange(changes) ;} void p3Notify::notifyPeerStatusChangedSummary () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChangedSummary() ; } void p3Notify::notifyDiscInfoChanged () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiscInfoChanged () ; } diff --git a/libretroshare/src/pqi/p3notify.h b/libretroshare/src/pqi/p3notify.h index 6130d8f42..37d984ebb 100644 --- a/libretroshare/src/pqi/p3notify.h +++ b/libretroshare/src/pqi/p3notify.h @@ -110,6 +110,7 @@ class p3Notify: public RsNotify void notifyOwnStatusMessageChanged () ; void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) ; void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) ; + void notifyGxsChange (const RsGxsChanges& /* changes */); void notifyPeerStatusChangedSummary () ; void notifyDiscInfoChanged () ; diff --git a/libretroshare/src/retroshare/rsgxsiface.h b/libretroshare/src/retroshare/rsgxsiface.h index ebcdd2289..9b555f2fe 100644 --- a/libretroshare/src/retroshare/rsgxsiface.h +++ b/libretroshare/src/retroshare/rsgxsiface.h @@ -31,6 +31,20 @@ #include "gxs/rsgxsdata.h" #include "retroshare/rsgxsifacetypes.h" +/*! + * Stores ids of changed gxs groups and messages. It is used to notify the GUI about changes. + */ +class RsGxsChanges +{ +public: + RsGxsChanges(): mService(0){} + RsTokenService *mService; + std::map > mMsgs; + std::map > mMsgsMeta; + std::list mGrps; + std::list mGrpsMeta; +}; + /*! * All implementations must offer thread safety */ @@ -49,43 +63,6 @@ public: */ virtual void receiveChanges(std::vector& changes) = 0; - /*! - * Checks to see if a change has been received for - * for a message or group - * @param willCallGrpChanged if this is set to true, group changed function will return list - * groups that have changed, if false, the group changed list is cleared - * @param willCallMsgChanged if this is set to true, msgChanged function will return map - * messages that have changed, if false, the message changed map is cleared - * @return true if a change has occured for msg or group - * @see groupsChanged - * @see msgsChanged - */ - virtual bool updated(bool willCallGrpChanged = false, bool willCallMsgChanged = false) = 0; - - /*! - * The groups changed. \n - * class can reimplement to use to tailor - * the group actually set for ui notification. - * If receivedChanges is not passed RsGxsNotify changes - * this function does nothing - * @param grpIds returns list of grpIds that have changed - * @param grpIdsMeta returns list of grpIds with meta data changes - * @see updated - */ - virtual void groupsChanged(std::list& grpIds, std::list& grpIdsMeta) = 0; - - /*! - * The msg changed. \n - * class can reimplement to use to tailor - * the msg actually set for ui notification. - * If receivedChanges is not passed RsGxsNotify changes - * this function does nothing - * @param msgs returns map of message ids that have changed - * @param msgsMeta returns map of message ids with meta data changes - * @see updated - */ - virtual void msgsChanged(std::map >& msgs, std::map >& msgsMeta) = 0; - /*! * @return handle to token service for this GXS service */ diff --git a/libretroshare/src/retroshare/rsgxsifacehelper.h b/libretroshare/src/retroshare/rsgxsifacehelper.h index 376442e74..3856c7294 100644 --- a/libretroshare/src/retroshare/rsgxsifacehelper.h +++ b/libretroshare/src/retroshare/rsgxsifacehelper.h @@ -61,51 +61,6 @@ public: mGxs->receiveChanges(changes); } - /*! - * Checks to see if a change has been received for - * for a message or group - * @param willCallGrpChanged if this is set to true, group changed function will return list - * groups that have changed, if false, the group changed list is cleared - * @param willCallMsgChanged if this is set to true, msgChanged function will return map - * messages that have changed, if false, the message changed map is cleared - * @return true if a change has occured for msg or group - * @see groupsChanged - * @see msgsChanged - */ - bool updated(bool willCallGrpChanged = false, bool willCallMsgChanged = false) - { - return mGxs->updated(willCallGrpChanged, willCallMsgChanged); - } - - /*! - * The groups changed. \n - * class can reimplement to use to tailor - * the group actually set for ui notification. - * If receivedChanges is not passed RsGxsNotify changes - * this function does nothing - * @param grpIds returns list of grpIds that have changed - * @param grpIdsMeta returns list of grpIds with meta data changes - * @see updated - */ - void groupsChanged(std::list &grpIds, std::list& grpIdsMeta) - { - mGxs->groupsChanged(grpIds, grpIdsMeta); - } - - /*! - * The msg changed. \n - * class can be reimplemented to use to tailor - * the msg actually set for ui notification. - * If receivedChanges is not passed RsGxsNotify changes - * this function does nothing - * @param msgs returns map of message ids that have changed - * @param msgsMeta returns map of message ids with meta data changes - * @see updated - */ - void msgsChanged(std::map > &msgs, std::map >& msgsMeta) - { - mGxs->msgsChanged(msgs, msgsMeta); - } /*! * @return handle to token service for this GXS service */ diff --git a/libretroshare/src/retroshare/rsnotify.h b/libretroshare/src/retroshare/rsnotify.h index ae3cd6cae..c6caa6017 100644 --- a/libretroshare/src/retroshare/rsnotify.h +++ b/libretroshare/src/retroshare/rsnotify.h @@ -34,9 +34,11 @@ #include #include "rsturtle.h" +#include "rsgxsifacetypes.h" class ChatId; class ChatMessage; +class RsGxsChanges; class RsNotify; extern RsNotify *rsNotify; @@ -215,6 +217,7 @@ class NotifyClient virtual void notifyOwnStatusMessageChanged () {} virtual void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) {} virtual void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) {} + virtual void notifyGxsChange (const RsGxsChanges& /* changes */) {} /* one or more peers has changed the states */ virtual void notifyPeerStatusChangedSummary () {} diff --git a/retroshare-gui/src/gui/notifyqt.cpp b/retroshare-gui/src/gui/notifyqt.cpp index 90881f34c..0522f910b 100644 --- a/retroshare-gui/src/gui/notifyqt.cpp +++ b/retroshare-gui/src/gui/notifyqt.cpp @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * *************************************************************************/ +#include #include #include @@ -140,6 +141,7 @@ NotifyQt::NotifyQt() : cDialog(NULL) // register to allow sending over Qt::QueuedConnection qRegisterMetaType("ChatId"); qRegisterMetaType("ChatMessage"); + qRegisterMetaType("RsGxsChanges"); } void NotifyQt::notifyErrorMsg(int list, int type, std::string msg) @@ -417,6 +419,22 @@ void NotifyQt::notifyPeerStatusChangedSummary() emit peerStatusChangedSummary(); } + +void NotifyQt::notifyGxsChange(const RsGxsChanges& changes) +{ + { + QMutexLocker m(&_mutex) ; + if(!_enabled) + return ; + } + +#ifdef NOTIFY_DEBUG + std::cerr << "Notifyqt:: notified that gxs has changes" << std::endl; +#endif + + emit gxsChange(changes); +} + #ifdef REMOVE void NotifyQt::notifyForumMsgReadSatusChanged(const std::string& forumId, const std::string& msgId, uint32_t status) { diff --git a/retroshare-gui/src/gui/notifyqt.h b/retroshare-gui/src/gui/notifyqt.h index 982eeb19c..add37fcdf 100644 --- a/retroshare-gui/src/gui/notifyqt.h +++ b/retroshare-gui/src/gui/notifyqt.h @@ -57,6 +57,9 @@ class NotifyQt: public QObject, public NotifyClient virtual void notifyPeerStatusChanged(const std::string& peer_id, uint32_t state); /* one or more peers has changed the states */ virtual void notifyPeerStatusChangedSummary(); + + virtual void notifyGxsChange(const RsGxsChanges& change); + #ifdef REMOVE virtual void notifyForumMsgReadSatusChanged(const std::string& forumId, const std::string& msgId, uint32_t status); virtual void notifyChannelMsgReadSatusChanged(const std::string& channelId, const std::string& msgId, uint32_t status); @@ -121,6 +124,7 @@ class NotifyQt: public QObject, public NotifyClient void diskFull(int,int) const ; void peerStatusChanged(const QString& /* peer_id */, int /* status */); void peerStatusChangedSummary() const; + void gxsChange(const RsGxsChanges& /* changes */); #ifdef REMOVE void publicChatChanged(int type) const ; void privateChatChanged(int list, int type) const ; diff --git a/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp b/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp index 879ef5510..8df24bc21 100644 --- a/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp +++ b/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp @@ -1,20 +1,21 @@ -//#include #include #include "RsGxsUpdateBroadcast.h" -#include "RsProtectedTimer.h" +#include "gui/notifyqt.h" #include +// previously gxs allowed only one event consumer to poll for changes +// this required a single broadcast instance per service +// now the update notify works through rsnotify and notifyqt +// so the single instance per service is not really needed anymore + QMap updateBroadcastMap; RsGxsUpdateBroadcast::RsGxsUpdateBroadcast(RsGxsIfaceHelper *ifaceImpl) : QObject(NULL), mIfaceImpl(ifaceImpl) { - mTimer = new RsProtectedTimer(this); - mTimer->setInterval(1000); - mTimer->setSingleShot(true); - connect(mTimer, SIGNAL(timeout()), this, SLOT(poll())); + connect(NotifyQt::getInstance(), SIGNAL(gxsChange(RsGxsChanges)), this, SLOT(onChangesReceived(RsGxsChanges))); } void RsGxsUpdateBroadcast::cleanup() @@ -36,34 +37,24 @@ RsGxsUpdateBroadcast *RsGxsUpdateBroadcast::get(RsGxsIfaceHelper *ifaceImpl) RsGxsUpdateBroadcast *updateBroadcast = new RsGxsUpdateBroadcast(ifaceImpl); updateBroadcastMap.insert(ifaceImpl, updateBroadcast); - updateBroadcast->poll(); return updateBroadcast; } -void RsGxsUpdateBroadcast::poll() +void RsGxsUpdateBroadcast::onChangesReceived(const RsGxsChanges& changes) { - std::map > msgs; - std::map > msgsMeta; - std::list grps; - std::list grpsMeta; + if(changes.mService != mIfaceImpl->getTokenService()) + return; - if (mIfaceImpl->updated(true, true)) - { - mIfaceImpl->msgsChanged(msgs, msgsMeta); - if (!msgs.empty() || !msgsMeta.empty()) - { - emit msgsChanged(msgs, msgsMeta); - } + if (!changes.mMsgs.empty() || !changes.mMsgsMeta.empty()) + { + emit msgsChanged(changes.mMsgs, changes.mMsgsMeta); + } - mIfaceImpl->groupsChanged(grps, grpsMeta); - if (!grps.empty() || !grpsMeta.empty()) - { - emit grpsChanged(grps, grpsMeta); - } + if (!changes.mGrps.empty() || !changes.mGrpsMeta.empty()) + { + emit grpsChanged(changes.mGrps, changes.mGrpsMeta); + } - emit changed(); - } - - mTimer->start(); + emit changed(); } diff --git a/retroshare-gui/src/util/RsGxsUpdateBroadcast.h b/retroshare-gui/src/util/RsGxsUpdateBroadcast.h index 7ace0ad2f..d9d90db1f 100644 --- a/retroshare-gui/src/util/RsGxsUpdateBroadcast.h +++ b/retroshare-gui/src/util/RsGxsUpdateBroadcast.h @@ -6,7 +6,7 @@ #include class RsGxsIfaceHelper; -class QTimer; +class RsGxsChanges; class RsGxsUpdateBroadcast : public QObject { @@ -23,14 +23,13 @@ signals: void grpsChanged(const std::list& grpIds, const std::list& grpIdsMeta); private slots: - void poll(); + void onChangesReceived(const RsGxsChanges& changes); private: explicit RsGxsUpdateBroadcast(RsGxsIfaceHelper* ifaceImpl); private: RsGxsIfaceHelper* mIfaceImpl; - QTimer *mTimer; }; #endif // RSGXSUPDATEBROADCAST_H