C++ (Qt)void MyClass::methodForSync(void) { ...} void MyClass::doAny(void) { ... ... sb_synchronize_method(MyClass, methodForSync); ... ...}
C++ (Qt)//--------------------------------------------------------------------------- #ifndef sbw_kernelH#define sbw_kernelH //--------------------------------------------------------------------------- #include <QObject>#include <QApplication>#include <QThread>#include <QWaitCondition>#include <QMutex> /*-----------------------------------------------------------------------------*/ class SbThread;class SbThreadSync;class SbApplication; /*-----------------------------------------------------------------------------*/ class SbThread : public QThread { Q_OBJECT protected: QAtomicInt Stopped; QMutex Mutex; QWaitCondition Wait; SbApplication* Application; public: SbThread(bool FreeOnComplete = false, QObject * parent = 0); virtual ~SbThread(); inline bool stopped (void) const {return Stopped;} inline void stop (void) {Stopped.ref();} void wake (void); public: static void synchronize(SbThreadSync* s); protected: void doSynchronize(SbThreadSync* s); signals: void signalSynchronize(SbThreadSync* s); }; /*-----------------------------------------------------------------------------*/ class SbThreadSync { friend class SbThread; friend class SbApplication; private: SbThread* Thread; protected: void syncCall(void); public: SbThreadSync() {Thread = NULL;} virtual ~SbThreadSync() {} virtual void call(void) = 0;}; #define sb_synchronize_method(__type, __method) \ { \ class TrSync : public SbThreadSync { \ private : \ __type* obj; \ void (__type::*method)(void); \ public : \ TrSync(__type* obj, void (__type::*method)(void)): SbThreadSync() {this->obj = obj; this->method = method;} \ void call (void) {(obj->*method)();} \ } trs(this, &__type::__method); \ SbThread::synchronize(&trs); \ } /*-----------------------------------------------------------------------------*/ class SbApplication : public QApplication { Q_OBJECT public: static QThread* thread(void) {return QApplication::instance()->thread();} public: SbApplication(int& argc, char** argv) : QApplication(argc, argv) {} private slots: void synchronize(SbThreadSync* s) {s->syncCall();}}; #endif
C++ (Qt)/*-----------------------------------------------------------------------------*/ #include "sbw_kernel.h" /*-----------------------------------------------------------------------------*/ /*************************** * class SbThread ***************************/ SbThread::SbThread(bool FreeOnComplete, QObject* parent) : QThread(parent) { Stopped = 0; if(FreeOnComplete) {connect(this , SIGNAL(finished()), this , SLOT(deleteLater()));} SbApplication* Application = qobject_cast<SbApplication*>(QApplication::instance()); if(Application) {connect(this , SIGNAL(signalSynchronize(SbThreadSync*)), Application, SLOT(synchronize(SbThreadSync*)), Qt::QueuedConnection);}} SbThread::~SbThread() {} void SbThread::wake (void) { Wait.wakeOne();} void SbThread::doSynchronize(SbThreadSync* s) { Mutex.lock(); emit signalSynchronize(s); Wait.wait(&Mutex); Mutex.unlock();} void SbThread::synchronize(SbThreadSync* s) { if(SbApplication::thread() == QThread::currentThread()) { s->call(); return; } SbThread* Thread = qobject_cast<SbThread*>(QThread::currentThread()); if(!Thread || !Thread->Application) { s->call(); // OR throw return; } s->Thread = Thread; Thread->doSynchronize(s);} /*-----------------------------------------------------------------------------*/ /*************************** * class SbThreadSync ***************************/ void SbThreadSync::syncCall(void) { call(); Thread->wake();} /*-----------------------------------------------------------------------------*/
C++ (Qt)void SbThread::wake (void) { Mutex.lock(); Wait.wakeOne(); Mutex.unlock();} void SbThread::doSynchronize(SbThreadSync* s) { Mutex.lock(); emit signalSynchronize(s); Wait.wait(&Mutex); Mutex.unlock();}