mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-02 22:25:04 -04:00
use notify for gxs events. Removed the previous polling based system. Now multiple clients can receive gxs changes. This also fixes the always growing changes queue in rs-nogui.
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@8057 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
b912ac656c
commit
6dff335515
11 changed files with 117 additions and 280 deletions
|
@ -35,6 +35,7 @@
|
|||
#include "retroshare/rsgrouter.h"
|
||||
#include "rsgixs.h"
|
||||
#include "rsgxsutil.h"
|
||||
#include "rsserver/p3face.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -992,105 +993,67 @@ bool RsGenExchange::checkAuthenFlag(const PrivacyBitPos& pos, const uint8_t& fla
|
|||
}
|
||||
}
|
||||
|
||||
void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
|
||||
{
|
||||
RS_STACK_MUTEX(mGenMtx) ;
|
||||
|
||||
#ifdef GEN_EXCH_DEBUG
|
||||
std::cerr << "RsGenExchange::receiveChanges()" << std::endl;
|
||||
#endif
|
||||
std::vector<RsGxsNotify*>::iterator vit = changes.begin();
|
||||
|
||||
for(; vit != changes.end(); ++vit)
|
||||
{
|
||||
RsGxsNotify* n = *vit;
|
||||
RsGxsGroupChange* gc;
|
||||
RsGxsMsgChange* mc;
|
||||
if((mc = dynamic_cast<RsGxsMsgChange*>(n)) != NULL)
|
||||
{
|
||||
mMsgChange.push_back(mc);
|
||||
}
|
||||
else if((gc = dynamic_cast<RsGxsGroupChange*>(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<RsGxsGroupId, std::vector<RsGxsMessageId> > &msgs, const std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &msgChanged)
|
||||
{
|
||||
if (msgs.empty()) {
|
||||
msgs = msgChanged;
|
||||
} else {
|
||||
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >::const_iterator mapIt;
|
||||
for (mapIt = msgChanged.begin(); mapIt != msgChanged.end(); ++mapIt) {
|
||||
const RsGxsGroupId &grpId = mapIt->first;
|
||||
const std::vector<RsGxsMessageId> &srcMsgIds = mapIt->second;
|
||||
std::vector<RsGxsMessageId> &destMsgIds = msgs[grpId];
|
||||
if (msgs.empty()) {
|
||||
msgs = msgChanged;
|
||||
} else {
|
||||
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >::const_iterator mapIt;
|
||||
for (mapIt = msgChanged.begin(); mapIt != msgChanged.end(); ++mapIt) {
|
||||
const RsGxsGroupId &grpId = mapIt->first;
|
||||
const std::vector<RsGxsMessageId> &srcMsgIds = mapIt->second;
|
||||
std::vector<RsGxsMessageId> &destMsgIds = msgs[grpId];
|
||||
|
||||
std::vector<RsGxsMessageId>::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<RsGxsMessageId>::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<RsGxsGroupId, std::vector<RsGxsMessageId> >& msgs, std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >& msgsMeta)
|
||||
void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& 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<RsGxsGroupId>& grpIds, std::list<RsGxsGroupId>& grpIdsMeta)
|
||||
{
|
||||
|
||||
if(mGenMtx.trylock())
|
||||
{
|
||||
while(!mGroupChange.empty())
|
||||
{
|
||||
RsGxsGroupChange* gc = mGroupChange.back();
|
||||
std::list<RsGxsGroupId>& gList = gc->mGrpIdList;
|
||||
std::list<RsGxsGroupId>::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<RsGxsNotify*>::iterator vit = changes.begin();
|
||||
for(; vit != changes.end(); ++vit)
|
||||
{
|
||||
RsGxsNotify* n = *vit;
|
||||
RsGxsGroupChange* gc;
|
||||
RsGxsMsgChange* mc;
|
||||
if((mc = dynamic_cast<RsGxsMsgChange*>(n)) != NULL)
|
||||
{
|
||||
if (mc->metaChange())
|
||||
{
|
||||
addMessageChanged(out.mMsgsMeta, mc->msgChangeMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
addMessageChanged(out.mMsgs, mc->msgChangeMap);
|
||||
}
|
||||
}
|
||||
else if((gc = dynamic_cast<RsGxsGroupChange*>(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<RsGxsGroupId> &groupIds)
|
||||
{
|
||||
return mDataAccess->getGroupList(token, groupIds);
|
||||
|
|
|
@ -255,44 +255,6 @@ public:
|
|||
*/
|
||||
virtual void receiveChanges(std::vector<RsGxsNotify*>& 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<RsGxsGroupId>& grpIds, std::list<RsGxsGroupId>& 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<RsGxsGroupId, std::vector<RsGxsMessageId> >& msgs, std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >& msgsMeta);
|
||||
|
||||
|
||||
bool subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe);
|
||||
|
||||
/*!
|
||||
|
@ -878,9 +840,6 @@ private:
|
|||
|
||||
private:
|
||||
|
||||
std::vector<RsGxsGroupChange*> mGroupChange;
|
||||
std::vector<RsGxsMsgChange*> 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;
|
||||
|
|
|
@ -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 () ; }
|
||||
|
|
|
@ -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 () ;
|
||||
|
|
|
@ -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<RsGxsGroupId, std::vector<RsGxsMessageId> > mMsgs;
|
||||
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > mMsgsMeta;
|
||||
std::list<RsGxsGroupId> mGrps;
|
||||
std::list<RsGxsGroupId> mGrpsMeta;
|
||||
};
|
||||
|
||||
/*!
|
||||
* All implementations must offer thread safety
|
||||
*/
|
||||
|
@ -49,43 +63,6 @@ public:
|
|||
*/
|
||||
virtual void receiveChanges(std::vector<RsGxsNotify*>& 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<RsGxsGroupId>& grpIds, std::list<RsGxsGroupId>& 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<RsGxsGroupId, std::vector<RsGxsMessageId> >& msgs, std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >& msgsMeta) = 0;
|
||||
|
||||
/*!
|
||||
* @return handle to token service for this GXS service
|
||||
*/
|
||||
|
|
|
@ -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<RsGxsGroupId> &grpIds, std::list<RsGxsGroupId>& 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<RsGxsGroupId, std::vector<RsGxsMessageId> > &msgs, std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >& msgsMeta)
|
||||
{
|
||||
mGxs->msgsChanged(msgs, msgsMeta);
|
||||
}
|
||||
/*!
|
||||
* @return handle to token service for this GXS service
|
||||
*/
|
||||
|
|
|
@ -34,9 +34,11 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#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 () {}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue