2
@author Shin'ichiro Nakaoka
5
#include "LazyCaller.h"
8
#include <QCoreApplication>
11
#include <boost/bind.hpp>
13
using namespace cnoid;
17
class CallEvent : public QEvent
20
CallEvent(const boost::function<void(void)>& function)
21
: QEvent(QEvent::User),
24
boost::function<void(void)> function;
27
class SynchronousCallEvent : public QEvent
30
SynchronousCallEvent(const boost::function<void(void)>& function, QSemaphore& semaphore)
31
: QEvent(QEvent::User),
33
semaphore(semaphore) {
35
boost::function<void(void)> function;
36
QSemaphore& semaphore;
39
class CallEventHandler : public QObject
43
mainThreadId = QThread::currentThreadId();
45
virtual bool event(QEvent* e);
46
Qt::HANDLE mainThreadId;
49
CallEventHandler callEventHandler;
53
void cnoid::callLater(const boost::function<void(void)>& function, int priority)
55
QCoreApplication::postEvent(&callEventHandler, new CallEvent(function), priority);
59
void cnoid::callSynchronously(const boost::function<void(void)>& function, int priority)
61
if(QThread::currentThreadId() == callEventHandler.mainThreadId){
62
callLater(function, priority);
65
QCoreApplication::postEvent(&callEventHandler, new SynchronousCallEvent(function, semaphore), priority);
66
semaphore.acquire(); // wait for finish
71
bool CallEventHandler::event(QEvent* e)
73
CallEvent* callEvent = dynamic_cast<CallEvent*>(e);
75
callEvent->function();
78
SynchronousCallEvent* scEvent = dynamic_cast<SynchronousCallEvent*>(e);
81
scEvent->semaphore.release(); // wake up
89
LazyCaller::LazyCaller()
91
isCallEventPending = false;
92
priority = IDLE_PRIORITY_HIGH;
96
LazyCaller::LazyCaller(const boost::function<void(void)>& function, int priority)
100
isCallEventPending = false;
104
void LazyCaller::set(const boost::function<void(void)>& function, int priority)
106
this->function = function;
107
this->priority = priority;
111
void LazyCaller::setPriority(int priority)
113
this->priority = priority;
117
void LazyCaller::request()
119
if(!isCallEventPending){
120
isCallEventPending = true;
121
callLater(boost::bind(&LazyCaller::onRequest, this), priority);
126
void LazyCaller::onRequest()
128
isCallEventPending = false;