chatdialog: Fix issue of creating QObjects in different thread.
Change-Id: I2f0dc2006cc330cd9d4fc5973eb475d841103b59
diff --git a/src/chatdialog.cpp b/src/chatdialog.cpp
index e43aa78..6603183 100644
--- a/src/chatdialog.cpp
+++ b/src/chatdialog.cpp
@@ -77,7 +77,7 @@
m_localChatPrefix.append("chronos").append(m_chatroomPrefix.get(-1)).append(randString.toStdString());
m_session = static_cast<uint64_t>(time::now());
- m_scene = new DigestTreeScene(this);
+ m_scene = new DigestTreeScene(m_ioService, this);
initializeSetting();
updateLabels();
@@ -122,6 +122,19 @@
this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
connect(m_scene, SIGNAL(rosterChanged(QStringList)),
this, SLOT(updateRosterList(QStringList)));
+ connect(this, SIGNAL(triggerHello()),
+ this, SLOT(sendHello()));
+ connect(this, SIGNAL(triggerJoin()),
+ this, SLOT(sendJoin()));
+ connect(this, SIGNAL(triggerLeave()),
+ this, SLOT(sendLeave()));
+ connect(this, SIGNAL(triggerReplot()),
+ this, SLOT(replot()));
+ connect(this, SIGNAL(triggerEnableTreeDisplay()),
+ this, SLOT(enableTreeDisplay()));
+ connect(this, SIGNAL(triggerReap()),
+ this, SLOT(reap()));
+
initializeSync();
@@ -180,14 +193,14 @@
usleep(100000);
- m_scheduler.scheduleEvent(time::milliseconds(600), bind(&ChatDialog::sendJoin, this));
+ m_scheduler.scheduleEvent(time::milliseconds(600), bind(&ChatDialog::sendJoinWrapper, this));
if(static_cast<bool>(m_replotEventId))
m_scheduler.cancelEvent(m_replotEventId);
m_replotEventId = m_scheduler.schedulePeriodicEvent(time::seconds(0), time::milliseconds(FRESHNESS * 1000),
- bind(&ChatDialog::replot, this));
+ bind(&ChatDialog::replotWrapper, this));
disableTreeDisplay();
- m_scheduler.scheduleEvent(time::milliseconds(2200), bind(&ChatDialog::enableTreeDisplay, this));
+ m_scheduler.scheduleEvent(time::milliseconds(2200), bind(&ChatDialog::enableTreeDisplayWrapper, this));
}
void
@@ -386,6 +399,10 @@
}
void
+ChatDialog::enableTreeDisplayWrapper()
+{ emit triggerEnableTreeDisplay(); }
+
+void
ChatDialog::processTreeUpdateWrapper(const vector<Sync::MissingDataInfo>& v, Sync::SyncSocket *sock)
{
emit treeUpdated(v);
@@ -520,10 +537,14 @@
boost::random::random_device rng;
boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
- m_scheduler.scheduleEvent(time::milliseconds(m_randomizedInterval), bind(&ChatDialog::sendHello, this));
+ m_scheduler.scheduleEvent(time::milliseconds(m_randomizedInterval), bind(&ChatDialog::sendHelloWrapper, this));
}
void
+ChatDialog::sendJoinWrapper()
+{ emit triggerJoin(); }
+
+void
ChatDialog::sendHello()
{
int64_t now = time::now();
@@ -536,16 +557,20 @@
boost::random::random_device rng;
boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
- m_scheduler.scheduleEvent(time::milliseconds(m_randomizedInterval), bind(&ChatDialog::sendHello, this));
+ m_scheduler.scheduleEvent(time::milliseconds(m_randomizedInterval), bind(&ChatDialog::sendHelloWrapper, this));
}
else
{
m_scheduler.scheduleEvent(time::milliseconds(m_randomizedInterval - elapsed * 1000),
- bind(&ChatDialog::sendHello, this));
+ bind(&ChatDialog::sendHelloWrapper, this));
}
}
void
+ChatDialog::sendHelloWrapper()
+{ emit triggerHello(); }
+
+void
ChatDialog::sendLeave()
{
SyncDemo::ChatMessage msg;
@@ -559,6 +584,10 @@
}
void
+ChatDialog::sendLeaveWrapper()
+{ emit triggerLeave(); }
+
+void
ChatDialog::replot()
{
boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
@@ -567,6 +596,10 @@
}
void
+ChatDialog::replotWrapper()
+{ emit triggerReplot(); }
+
+void
ChatDialog::summonReaper()
{
Sync::SyncLogic &logic = m_sock->getLogic ();
@@ -617,11 +650,15 @@
m_zombieIndex++;
// reap again in 10 seconds
m_scheduler.scheduleEvent(time::milliseconds(10000),
- bind(&ChatDialog::reap, this));
+ bind(&ChatDialog::reapWrapper, this));
}
}
void
+ChatDialog::reapWrapper()
+{ emit triggerReap(); }
+
+void
ChatDialog::updateRosterList(QStringList staleUserList)
{
boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
@@ -702,13 +739,13 @@
bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
bind(&ChatDialog::processRemoveWrapper, this, _1));
usleep(100000);
- m_scheduler.scheduleEvent(time::milliseconds(600), bind(&ChatDialog::sendJoin, this));
+ m_scheduler.scheduleEvent(time::milliseconds(600), bind(&ChatDialog::sendJoinWrapper, this));
if(static_cast<bool>(m_replotEventId))
m_scheduler.cancelEvent(m_replotEventId);
m_replotEventId = m_scheduler.schedulePeriodicEvent(time::seconds(0), time::milliseconds(FRESHNESS * 1000),
- bind(&ChatDialog::replot, this));
+ bind(&ChatDialog::replotWrapper, this));
disableTreeDisplay();
- m_scheduler.scheduleEvent(time::milliseconds(2200), bind(&ChatDialog::enableTreeDisplay, this));
+ m_scheduler.scheduleEvent(time::milliseconds(2200), bind(&ChatDialog::enableTreeDisplayWrapper, this));
}catch(Face::Error& e){
emit noNdnConnection(QString::fromStdString("Cannot conect to ndnd!\n Have you started your ndnd?"));
}
diff --git a/src/chatdialog.h b/src/chatdialog.h
index 742b4ee..5b7eea2 100644
--- a/src/chatdialog.h
+++ b/src/chatdialog.h
@@ -16,7 +16,6 @@
#include <QDialog>
#include <QTextTable>
#include <QStringListModel>
-#include <QTimer>
#include <QSystemTrayIcon>
#include <QMenu>
@@ -233,6 +232,24 @@
void
inivationRejection(const QString& msg);
+ void
+ triggerHello();
+
+ void
+ triggerJoin();
+
+ void
+ triggerLeave();
+
+ void
+ triggerReplot();
+
+ void
+ triggerEnableTreeDisplay();
+
+ void
+ triggerReap();
+
public slots:
void
processTreeUpdate(const std::vector<Sync::MissingDataInfo>&);
@@ -253,18 +270,30 @@
void
settingUpdated(QString, QString, QString);
+ void
+ sendJoinWrapper();
+
void
sendJoin();
void
+ sendHelloWrapper();
+
+ void
sendHello();
void
sendLeave();
+ void
+ sendLeaveWrapper();
+
void
replot();
+ void
+ replotWrapper();
+
void
updateRosterList(QStringList);
@@ -272,6 +301,9 @@
enableTreeDisplay();
void
+ enableTreeDisplayWrapper();
+
+ void
updateLocalPrefix();
void
@@ -280,6 +312,9 @@
void
reap();
+ void
+ reapWrapper();
+
void
iconActivated(QSystemTrayIcon::ActivationReason reason);
diff --git a/src/digesttreescene.cpp b/src/digesttreescene.cpp
index c2aa865..d692d4e 100644
--- a/src/digesttreescene.cpp
+++ b/src/digesttreescene.cpp
@@ -25,8 +25,10 @@
//DisplayUserPtr DisplayUserNullPtr;
-DigestTreeScene::DigestTreeScene(QWidget *parent)
+DigestTreeScene::DigestTreeScene(ndn::shared_ptr<boost::asio::io_service> ioService,
+ QWidget *parent)
: QGraphicsScene(parent)
+ , m_scheduler(*ioService)
{
previouslyUpdatedUser = DisplayUserNullPtr;
}
@@ -58,7 +60,7 @@
if (rePlot)
{
plot(digest);
- QTimer::singleShot(2100, this, SLOT(emitReplot()));
+ m_scheduler.scheduleEvent(ndn::time::milliseconds(600), ndn::bind(&DigestTreeScene::emitReplot, this));
}
else
{
diff --git a/src/digesttreescene.h b/src/digesttreescene.h
index e7600e8..c239a49 100644
--- a/src/digesttreescene.h
+++ b/src/digesttreescene.h
@@ -19,6 +19,7 @@
#include <QMap>
#ifndef Q_MOC_RUN
+#include <ndn-cpp-dev/util/scheduler.hpp>
#include <sync-seq-no.h>
#include <sync-logic.h>
#include <ctime>
@@ -44,7 +45,8 @@
typedef QMapIterator<QString, DisplayUserPtr> RosterIterator;
public:
- DigestTreeScene(QWidget *parent = 0);
+ DigestTreeScene(ndn::shared_ptr<boost::asio::io_service> ioService,
+ QWidget *parent = 0);
void processUpdate(const std::vector<Sync::MissingDataInfo> &v, QString digest);
void msgReceived(QString prefix, QString nick);
void clearAll();
@@ -65,12 +67,13 @@
void plotEdge(const std::vector<TreeLayout::Coordinate> &v, int nodeSize);
void plotNode(const std::vector<TreeLayout::Coordinate> &v, QString digest, int nodeSize);
void reDrawNode(DisplayUserPtr p, QColor rimColor);
+
private:
Roster m_roster;
QGraphicsTextItem *m_rootDigest;
DisplayUserPtr previouslyUpdatedUser;
QString m_currentPrefix;
-
+ ndn::Scheduler m_scheduler;
};
class User