p3ConnectMgr::connectResult

- added "mStatusChanged = true" on disconnect of a peer - the statusChange was not notified in time

MessengerWindow
- removed unused method updatePeersAvatar

Changes in status service:
- removed unused method statusAvailable
- new notifier for status change
- enabled the tick for receiving items
  - always up to date status map
  - no huge memory usage, if no list is visible who call getStatus and processed the received items
  - send notify on status change
- renamed getStatus to getStatusList and created a new method getStatus to get status of one peer
- fixed: send status directly after the connect of a peer

Now the frame around the avatar in private chat changes when the peer change the state.


git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3380 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
thunder2 2010-08-20 18:45:44 +00:00
parent 331ed93720
commit 340982b996
14 changed files with 198 additions and 138 deletions

View File

@ -1772,6 +1772,7 @@ bool p3ConnectMgr::connectResult(std::string id, bool success, uint32_t flags, s
{
it->second.state &= (~RS_PEER_S_CONNECTED);
it->second.actions |= RS_PEER_DISCONNECTED;
mStatusChanged = true;
it->second.lastcontact = time(NULL); /* time of disconnect */

View File

@ -208,6 +208,10 @@ class NotifyBase
virtual void notifyOwnAvatarChanged() {}
virtual void notifyOwnStatusMessageChanged() {}
virtual void notifyDiskFull(uint32_t /* location */,uint32_t /* size limit in MB */) {}
/* peer has changed the status */
virtual void notifyPeerStatusChanged(const std::string& /* peer_id */, uint32_t /* status */) {}
/* one or more peers has changed the states */
virtual void notifyPeerStatusChangedSummary() {}
virtual std::string askForPassword(const std::string& /* key_details */ ,bool /* prev_is_bad */ ) { return "" ;}
};

View File

@ -36,6 +36,7 @@ extern RsStatus *rsStatus;
#include <list>
const uint32_t RS_STATUS_OFFLINE = 0x0000;
const uint32_t RS_STATUS_AWAY = 0x0001;
const uint32_t RS_STATUS_BUSY = 0x0002;
const uint32_t RS_STATUS_ONLINE = 0x0003;
@ -79,7 +80,13 @@ class RsStatus
* This retrieves the status info on the client's peers
* @param statusInfo is populated with client's peer's status
*/
virtual bool getStatus(std::list<StatusInfo>& statusInfo) = 0;
virtual bool getStatusList(std::list<StatusInfo>& statusInfo) = 0;
/**
* This retrieves the status info one peer
* @param statusInfo is populated with client's peer's status
*/
virtual bool getStatus(std::string &id, StatusInfo &statusInfo) = 0;
/**
* send the client's status to his/her peers
@ -89,11 +96,6 @@ class RsStatus
*/
virtual bool sendStatus(std::string id, uint32_t status) = 0;
/**
* checks to see if any status items have been received
*/
virtual bool statusAvailable() = 0;
/**
* translates the status field of a peer to a string
* @status the status id that needs to be translated

View File

@ -42,9 +42,14 @@ bool p3Status::getOwnStatus(StatusInfo& statusInfo){
return mStatusSrv->getOwnStatus(statusInfo);
}
bool p3Status::getStatus(std::list<StatusInfo >& statusInfo){
bool p3Status::getStatusList(std::list<StatusInfo>& statusInfo){
return mStatusSrv->getStatus(statusInfo);
return mStatusSrv->getStatusList(statusInfo);
}
bool p3Status::getStatus(std::string &id, StatusInfo &statusInfo)
{
return mStatusSrv->getStatus(id, statusInfo);
}
bool p3Status::sendStatus(std::string id, uint32_t status){
@ -52,11 +57,6 @@ bool p3Status::sendStatus(std::string id, uint32_t status){
return mStatusSrv->sendStatus(id, status);
}
bool p3Status::statusAvailable(){
return mStatusSrv->statusAvailable();
}
void p3Status::getStatusString(uint32_t status, std::string& statusString){
if (status == RS_STATUS_AWAY){

View File

@ -44,9 +44,9 @@ public:
virtual bool getOwnStatus(StatusInfo& statusInfo);
virtual bool getStatus(std::list<StatusInfo>& statusInfo);
virtual bool getStatusList(std::list<StatusInfo>& statusInfo);
virtual bool getStatus(std::string &id, StatusInfo &statusInfo);
virtual bool sendStatus(std::string id, uint32_t status);
virtual bool statusAvailable();
virtual void getStatusString(uint32_t status, std::string& statusString);

View File

@ -25,6 +25,7 @@
#include "services/p3statusservice.h"
#include "serialiser/rsstatusitems.h"
#include "retroshare/rsiface.h"
#include <iostream>
#include <map>
@ -55,6 +56,10 @@ p3StatusService::~p3StatusService()
bool p3StatusService::getOwnStatus(StatusInfo& statusInfo)
{
#ifdef STATUS_DEBUG
std::cerr << "p3StatusService::getOwnStatus() " << std::endl;
#endif
std::map<std::string, StatusInfo>::iterator it;
std::string ownId = mConnMgr->getOwnId();
@ -71,76 +76,45 @@ bool p3StatusService::getOwnStatus(StatusInfo& statusInfo)
return true;
}
bool p3StatusService::getStatus(std::list<StatusInfo>& statusInfo)
bool p3StatusService::getStatusList(std::list<StatusInfo>& statusInfo)
{
time_t time_now = time(NULL);
#ifdef STATUS_DEBUG
std::cerr << "p3StatusService::getStatus() " << std::endl;
std::cerr << "p3StatusService::getStatusList() " << std::endl;
#endif
statusInfo.clear();
std::list<RsStatusItem* > status_items;
getStatusQueue(status_items);
RsStackMutex stack(mStatusMtx);
// fill up statusInfo list with this information
std::map<std::string, StatusInfo>::iterator mit;
std::list<std::string> peers, peersOnline;
std::list<std::string>::iterator pit, pit_online;
{
RsStackMutex stack(mStatusMtx);
/* first update map */
mConnMgr->getFriendList(peers);
mConnMgr->getOnlineList(peersOnline);
pit_online = peersOnline.begin();
// ensure member map is up to date with all client's peers
for(pit = peers.begin(); pit != peers.end(); pit++){
mit = mStatusInfoMap.find(*pit);
if(mit == mStatusInfoMap.end()){
StatusInfo info;
info.id = *pit;
info.status = RS_STATUS_ONLINE;
info.time_stamp = time_now;
std::pair<std::string, StatusInfo> pr(*pit, info);
mStatusInfoMap.insert(pr);
}
}
// now note members who have sent specific status updates
while (status_items.size()){
RsStatusItem* si = status_items.front();
status_items.pop_front();
mit = mStatusInfoMap.find(si->PeerId());
if(mit != mStatusInfoMap.end()){
mit->second.id = si->PeerId();
mit->second.status = si->status;
mit->second.time_stamp = si->sendTime;
#ifdef STATUS_DEBUG
} else {
std::cerr << "p3GetStatus() " << "Could not find Peer" << si->PeerId();
std::cerr << std::endl;
#endif
}
delete (si);
}
// then fill up statusInfo list with this information
for(mit = mStatusInfoMap.begin(); mit != mStatusInfoMap.end(); mit++){
statusInfo.push_back(mit->second);
}
for(mit = mStatusInfoMap.begin(); mit != mStatusInfoMap.end(); mit++){
statusInfo.push_back(mit->second);
}
return true;
}
bool p3StatusService::getStatus(std::string &id, StatusInfo &statusInfo)
{
#ifdef STATUS_DEBUG
std::cerr << "p3StatusService::getStatus() " << std::endl;
#endif
RsStackMutex stack(mStatusMtx);
std::map<std::string, StatusInfo>::iterator mit = mStatusInfoMap.find(id);
if (mit == mStatusInfoMap.end()) {
/* return fake status info as offline */
statusInfo = StatusInfo();
statusInfo.id = id;
statusInfo.status = RS_STATUS_OFFLINE;
return false;
}
statusInfo = mit->second;
return true;
}
@ -199,36 +173,63 @@ bool p3StatusService::sendStatus(const std::string &id, uint32_t status)
return true;
}
bool p3StatusService::statusAvailable(){
return receivedItems();
}
/******************************/
void p3StatusService::getStatusQueue(std::list<RsStatusItem* > &ilist)
void p3StatusService::receiveStatusQueue()
{
time_t time_now = time(NULL);
std::map<std::string, uint32_t> changed;
RsItem* item;
{
RsStackMutex stack(mStatusMtx);
while(NULL != (item = recvItem())){
RsItem* item;
RsStatusItem* status_item = dynamic_cast<RsStatusItem*>(item);
while(NULL != (item = recvItem())){
if(status_item == NULL) {
std::cerr << "p3Status::getStatusQueue() " << "Failed to cast Item \n" << std::endl;
delete (item);
continue;
}
RsStatusItem* status_item = dynamic_cast<RsStatusItem*>(item);
if(status_item == NULL) {
std::cerr << "p3Status::getStatusQueue() " << "Failed to cast Item \n" << std::endl;
delete (item);
continue;
}
#ifdef STATUS_DEBUG
std::cerr << "p3StatusService::getStatusQueue()" << std::endl;
std::cerr << "PeerId : " << status_item->PeerId() << std::endl;
std::cerr << "Status: " << status_item->status << std::endl;
std::cerr << "Got status Item" << std::endl;
std::cerr << "p3StatusService::getStatusQueue()" << std::endl;
std::cerr << "PeerId : " << status_item->PeerId() << std::endl;
std::cerr << "Status: " << status_item->status << std::endl;
std::cerr << "Got status Item" << std::endl;
#endif
status_item->recvTime = time_now;
ilist.push_back(status_item);
std::map<std::string, StatusInfo>::iterator mit = mStatusInfoMap.find(status_item->PeerId());
if(mit != mStatusInfoMap.end()){
mit->second.id = status_item->PeerId();
if (mit->second.status != status_item->status) {
changed [mit->second.id] = status_item->status;
}
mit->second.status = status_item->status;
mit->second.time_stamp = status_item->sendTime;
#ifdef STATUS_DEBUG
} else {
std::cerr << "getStatus() " << "Could not find Peer" << status_item->PeerId();
std::cerr << std::endl;
#endif
}
delete (status_item);
}
} /* UNLOCKED */
if (changed.size()) {
std::map<std::string, uint32_t>::iterator it;
for (it = changed.begin(); it != changed.end(); it++) {
rsicontrol->getNotify().notifyPeerStatusChanged(it->first, it->second);
}
rsicontrol->getNotify().notifyPeerStatusChangedSummary();
}
}
@ -313,7 +314,12 @@ bool p3StatusService::loadList(std::list<RsItem*> load){
}
int p3StatusService::tick(){
int p3StatusService::tick()
{
if (receivedItems()) {
receiveStatusQueue();
}
return 0;
}
@ -325,14 +331,50 @@ int p3StatusService::status(){
void p3StatusService::statusChange(const std::list<pqipeer> &plist)
{
bool changedState = false;
StatusInfo statusInfo;
std::list<pqipeer>::const_iterator it;
for (it = plist.begin(); it != plist.end(); it++) {
if ((it->state & RS_PEER_S_FRIEND) && (it->state & RS_PEER_CONNECTED)) {
/* send current status */
if (statusInfo.id.empty() == false || getOwnStatus(statusInfo)) {
sendStatus(it->id, statusInfo.status);
if (it->state & RS_PEER_S_FRIEND) {
if (it->actions & RS_PEER_DISCONNECTED)
{
{
RsStackMutex stack(mStatusMtx);
/* remove peer from status map */
mStatusInfoMap.erase(it->id);
} /* UNLOCKED */
changedState = true;
rsicontrol->getNotify().notifyPeerStatusChanged(it->id, RS_STATUS_OFFLINE);
}
if (it->actions & RS_PEER_CONNECTED) {
/* send current status, only call getOwnStatus once in the loop */
if (statusInfo.id.empty() == false || getOwnStatus(statusInfo)) {
sendStatus(it->id, statusInfo.status);
}
{
RsStackMutex stack(mStatusMtx);
/* We assume that the peer is online. If not, he send us a new status */
StatusInfo info;
info.id = it->id;
info.status = RS_STATUS_ONLINE;
info.time_stamp = time(NULL);
mStatusInfoMap[it->id] = info;
} /* UNLOCKED */
changedState = true;
rsicontrol->getNotify().notifyPeerStatusChanged(it->id, RS_STATUS_ONLINE);
}
}
}
if (changedState)
{
rsicontrol->getNotify().notifyPeerStatusChangedSummary();
}
}

View File

@ -61,10 +61,10 @@ virtual void statusChange(const std::list<pqipeer> &plist);
* Status is set to offline as default if no info received from relevant peer
*/
virtual bool getOwnStatus(StatusInfo& statusInfo);
virtual bool getStatus(std::list<StatusInfo>& statusInfo);
virtual bool getStatusList(std::list<StatusInfo>& statusInfo);
virtual bool getStatus(std::string &id, StatusInfo &statusInfo);
/* id = "", status is sent to all online peers */
virtual bool sendStatus(const std::string &id, uint32_t status);
virtual bool statusAvailable();
/******************************/
@ -88,7 +88,7 @@ virtual bool loadList(std::list<RsItem*> load);
private:
virtual void getStatusQueue(std::list<RsStatusItem* > &ilist);
virtual void receiveStatusQueue();
p3ConnectMgr *mConnMgr;

View File

@ -405,7 +405,7 @@ void MessengerWindow::insertPeers()
std::list<std::string> gpgFriends;
std::list<std::string>::iterator it;
std::list<StatusInfo> statusInfo;
rsStatus->getStatus(statusInfo);
rsStatus->getStatusList(statusInfo);
// if(isIdle)
// QMessageBox::StandardButton sb = QMessageBox::warning ( NULL, tr("Idle"),
@ -915,14 +915,6 @@ void MessengerWindow::pastePerson()
RSLinkClipboard::process(RetroShareLink::TYPE_PERSON, RSLINK_PROCESS_NOTIFY_ERROR);
}
void MessengerWindow::updatePeersAvatar(const QString& peer_id)
{
std::cerr << "PeersDialog: Got notified of new avatar for peer " << peer_id.toStdString() << std::endl ;
PopupChatDialog *pcd = PopupChatDialog::getPrivateChat(peer_id.toStdString(),rsPeers->getPeerName(peer_id.toStdString()), 0);
pcd->updatePeerAvatar(peer_id.toStdString());
}
//============================================================================

View File

@ -43,7 +43,6 @@ class MessengerWindow : public RWindow
public slots:
void updateMessengerDisplay() ;
void updatePeersAvatar(const QString& peer_id);
void updateAvatar();
void loadmystatusmessage();

View File

@ -468,7 +468,7 @@ void PeersDialog::insertPeers()
std::list<std::string>::iterator it;
std::list<StatusInfo> statusInfo;
rsStatus->getStatus(statusInfo);
rsStatus->getStatusList(statusInfo);
if (!rsPeers) {
/* not ready yet! */

View File

@ -45,7 +45,7 @@
#include <retroshare/rsstatus.h>
#include <retroshare/rsiface.h>
#include "gui/settings/rsharesettings.h"
#include "gui/notifyqt.h"
#include "gui/feeds/AttachFileItem.h"
#include "gui/msgs/MessageComposer.h"
@ -108,6 +108,8 @@ PopupChatDialog::PopupChatDialog(std::string id, std::string name,
connect(ui.textBrowser, SIGNAL(anchorClicked(const QUrl &)), SLOT(anchorClicked(const QUrl &)));
connect(NotifyQt::getInstance(), SIGNAL(peerStatusChanged(const QString&, int)), this, SLOT(updateStatus(const QString&, int)));
std::cerr << "Connecting custom context menu" << std::endl;
ui.chattextEdit->setContextMenuPolicy(Qt::CustomContextMenu) ;
connect(ui.chattextEdit,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(contextMenu(QPoint)));
@ -158,11 +160,14 @@ PopupChatDialog::PopupChatDialog(std::string id, std::string name,
updateAvatar() ;
updatePeerAvatar(id) ;
updateStatus();
// load settings
// load settings
processSettings(true);
// initialize first status
StatusInfo statusInfo;
rsStatus->getStatus(dialogId, statusInfo);
updateStatus(QString::fromStdString(dialogId), statusInfo.status);
}
/** Destructor. */
@ -1159,24 +1164,15 @@ void PopupChatDialog::setCurrentFileName(const QString &fileName)
setWindowModified(false);
}
void PopupChatDialog::updateStatus()
void PopupChatDialog::updateStatus(const QString &peer_id, int status)
{
std::list<StatusInfo> statusInfo;
rsStatus->getStatus(statusInfo);
uint32_t status = 0;
std::list<StatusInfo>::iterator it = statusInfo.begin();
for(; it != statusInfo.end() ; it++){
if (it->id == dialogId) {
status = it->status;
break;
}
if (peer_id != QString::fromStdString(dialogId)) {
// it's not me
return;
}
switch (status) {
case 0:
//here show offline state
case RS_STATUS_OFFLINE:
ui.avatarlabel->setStyleSheet("QLabel#avatarlabel{ border-image:url(:/images/mystatus_bg_offline.png); }");
break;

View File

@ -74,6 +74,7 @@ public slots:
void updateStatusString(const QString&) ;
void anchorClicked (const QUrl &);
void updateStatus(const QString &peer_id, int status);
protected:
/** Default constructor */
@ -107,9 +108,7 @@ private slots:
bool fileSaveAs();
void setCurrentFileName(const QString &fileName);
void updateStatus();
private:
void colorChanged(const QColor &c);

View File

@ -76,6 +76,26 @@ void NotifyQt::notifyDiskFull(uint32_t loc,uint32_t size_in_mb)
emit diskFull(loc,size_in_mb) ;
}
/* peer has changed the state */
void NotifyQt::notifyPeerStatusChanged(const std::string& peer_id, uint32_t state)
{
#ifdef NOTIFY_DEBUG
std::cerr << "Notifyqt:: notified that peer " << peer_id << " has changed the state to " << state << std::endl;
#endif
emit peerStatusChanged(QString::fromStdString(peer_id), state);
}
/* one or more peers has changed the states */
void NotifyQt::notifyPeerStatusChangedSummary()
{
#ifdef NOTIFY_DEBUG
std::cerr << "Notifyqt:: notified that one peer has changed the state" << std::endl;
#endif
emit peerStatusChangedSummary();
}
void NotifyQt::notifyOwnStatusMessageChanged()
{
#ifdef NOTIFY_DEBUG

View File

@ -40,8 +40,11 @@ class NotifyQt: public QObject, public NotifyBase
virtual void notifyOwnAvatarChanged() ;
virtual void notifyOwnStatusMessageChanged() ;
virtual void notifyDiskFull(uint32_t loc,uint32_t size_in_mb) ;
/* peer has changed the state */
virtual void notifyPeerStatusChanged(const std::string& peer_id, uint32_t state);
/* one or more peers has changed the states */
virtual void notifyPeerStatusChangedSummary();
virtual std::string askForPassword(const std::string& key_details,bool prev_is_bad) ;
signals:
@ -66,6 +69,8 @@ class NotifyQt: public QObject, public NotifyBase
void ownStatusMessageChanged() const ;
void errorOccurred(int,int,const QString&) const ;
void diskFull(int,int) const ;
void peerStatusChanged(const QString& /* peer_id */, int /* status */);
void peerStatusChangedSummary() const;
public slots: