diff --git a/main.cpp b/main.cpp index 02a10607..bac6c2b5 100644 --- a/main.cpp +++ b/main.cpp @@ -345,30 +345,40 @@ class B: public PIObject { PIOBJECT(B) public: EVENT_HANDLER1(void, h1, MyType, v) {piCout << "handler h1" << v;} + EVENT_HANDLER(void, th) {piCout << "handler th";} }; int main() { - PIThread thread([](){piCout << "thread";}, true, 100); - piMSleep(2000); - return 0; - - PITimer timer([](){piCout << "timer";}); - //t.setSlot(test); - timer.addDelimiter(5, [](void * d){piCout << "delim 5";}); - timer.addDelimiter(2, [](){piCout << "delim 2";}); - timer.start(100); - piMSleep(2000); - - A a; B b; - CONNECTU_QUEUED(&a, e1, &b, h1, &b); - a.e1(PIVector() << 1 << 2); - b.callQueuedEvents(); - - + PIThread::runOnce([](){piCout << "thread 1"; piMSleep(1000);}, "first"); + PIThread::runOnce([](){piCout << "thread 2"; piMSleep(500);}, "second"); + PIThread::runOnce([](){piCout << "thread 3"; piMSleep(0);}, "third"); + PIThread::runOnce(&b, "th", "first th"); + PIThread::runOnce(&b, "th", "second th"); + PIThread::runOnce(&b, "th", "third th"); + piSleep(2); return 0; + // + //PITimer timer([](){piCout << "timer";}); + //t.setSlot(test); + //timer.addDelimiter(5, [](void * d){piCout << "delim 5";}); + //timer.addDelimiter(2, [](){piCout << "delim 2";}); + //timer.start(100); + //piMSleep(2000); + + //A a; + //B b; + //int iii = 10; + //CONNECTL(&a, e1, [&](MyType v){piCout << "lambda" << v << iii; ++iii;}); + //std::function f = [&](MyType v){piCout << "lambda" << v << iii; ++iii;}; + //piCout << typeid([&](MyType v){piCout << "lambda" << v << iii; ++iii;}).name(); + //piCout << typeid(f).name(); + //a.e1(PIVector() << 1 << 2); + //piCout << iii; + // + //return 0; /*for (int i = 0; i < 0x2; ++i) { PIByteArray ba, ba2; diff --git a/src_main/thread/pithread.cpp b/src_main/thread/pithread.cpp index 66978ba1..82ef9004 100755 --- a/src_main/thread/pithread.cpp +++ b/src_main/thread/pithread.cpp @@ -120,6 +120,22 @@ PIVector __PIThreadCollection::threads() const { } +void __PIThreadCollection::startedAuto(PIThread * t) { + PIMutexLocker _ml(auto_mutex); + auto_threads_ << t; +} + + +void __PIThreadCollection::stoppedAuto() { + PIThread * t = emitter()->cast(); + if (!t) return; + auto_mutex.lock(); + auto_threads_.removeAll(t); + auto_mutex.unlock(); + delete t; +} + + int __PIThreadCollection_Initializer__::count_(0); @@ -549,10 +565,26 @@ void PIThread::__thread_func_once__() { } -PIThread * PIThread::runOnce(std::function func) { +void PIThread::runOnce(PIObject * object, const char * handler, const PIString & name) { PIThread * t = new PIThread(); - t->setSlot(func); + t->setName(name); + if (!PIObject::piConnectU(t, PIStringAscii("started"), object, object, PIStringAscii(handler), "PIThread::runOnce")) { + delete t; + return; + } + __PIThreadCollection::instance()->startedAuto(t); + CONNECTU(t, stopped, __PIThreadCollection::instance(), stoppedAuto); t->startOnce(); - return t; +} + + +void PIThread::runOnce(std::function func, const PIString & name) { + PIThread * t = new PIThread(); + t->setName(name); + t->setSlot(func); + __PIThreadCollection::instance()->startedAuto(t); + CONNECTU(t, stopped, __PIThreadCollection::instance(), stoppedAuto); + t->startOnce(); + //return t; } diff --git a/src_main/thread/pithread.h b/src_main/thread/pithread.h index 5c0d9212..8d73b562 100755 --- a/src_main/thread/pithread.h +++ b/src_main/thread/pithread.h @@ -32,7 +32,8 @@ class PIThread; class PIIntrospectionThreads; -class PIP_EXPORT __PIThreadCollection { +class PIP_EXPORT __PIThreadCollection: public PIObject { + PIOBJECT(__PIThreadCollection) public: static __PIThreadCollection * instance(); void registerThread(PIThread * t); @@ -40,9 +41,11 @@ public: PIVector threads() const; void lock() {mutex.lock();} void unlock() {mutex.unlock();} + void startedAuto(PIThread * t); + EVENT_HANDLER(void, stoppedAuto); private: - PIVector threads_; - mutable PIMutex mutex; + PIVector threads_, auto_threads_; + mutable PIMutex mutex, auto_mutex; }; @@ -155,8 +158,15 @@ public: EVENT(started) EVENT(stopped) + //! \brief Start event handler with name \"handler\" of object \"object\" + //! in separate thread with name \"name\" + //! and automatically delete it on function finish + static void runOnce(PIObject * object, const char * handler, const PIString & name = PIString()); + #ifdef PIP_CXX11_SUPPORT - static PIThread * runOnce(std::function func); + //! \brief Start function \"func\" in separate thread with name \"name\" + //! and automatically delete it on function finish + static void runOnce(std::function func, const PIString & name = PIString()); #endif //! \handlers