diff --git a/main.cpp b/main.cpp index 08cd414a..877ad2ca 100644 --- a/main.cpp +++ b/main.cpp @@ -32,141 +32,33 @@ const char pult_config[] = "; */ -#include -template -struct Info { - enum {Defined = 0}; -}; -template -struct TypeInfo { - typedef T PureType; - typedef const T ConstPureType; - typedef T * PointerType; - typedef const T * ConstPointerType; - typedef T & ReferenceType; - typedef const T & ConstReferenceType; -}; - -#define TYPEINFO_SINGLE(PT, T) \ - template<> struct TypeInfo { \ - typedef PT PureType; \ - typedef const PT ConstPureType; \ - typedef PT * PointerType; \ - typedef const PT * ConstPointerType; \ - typedef PT & ReferenceType; \ - typedef const PT & ConstReferenceType; \ - }; -#define TYPEINFO(T) \ - TYPEINFO_SINGLE(T, T &) \ - TYPEINFO_SINGLE(T, const T) \ - TYPEINFO_SINGLE(T, const T &) \ - TYPEINFO_SINGLE(T, T *) \ - TYPEINFO_SINGLE(T, const T *) - -TYPEINFO(PIString) - - -template -class A { +class A: public PIObject { + PIOBJECT(A) public: - void f() { - piCout << "T"; - } + EVENT1(ev1, float, f) }; -template -class A { +class B: public PIObject { + PIOBJECT(B) public: - void f() { - piCout << "const T&"; - } + EVENT_HANDLER0(void, eh0) {piCout << "eh0";} + EVENT_HANDLER1(void, eh1, float, f) {piCout << "eh1" << f;} }; -#include "pivector2d.h" int main(int argc, char *argv[]) { - /* - enum VCO_Aim_Type {VCO_Aim_Type_None, VCO_Aim_Type_Detected, VCO_Aim_Type_New, VCO_Aim_Type_Confirmed, VCO_Aim_Type_Deleted = 127}; -#pragma pack (push, 1) - struct VCO_Element { - VCO_Element() {} - VCO_Aim_Type type; - double elapsed; - float wls_a; // m/s - float wls_b; // m - float speed; - float acceleration; // m/s^2 - float prediction_pos; // m - float variance; // m - float power; - float angle; - int id; - int missed; - int missed_ml; - int confirmed; - int history_size; - bool tracing; - bool _found; - bool _checked; - bool _delete; - PIVector > history; - }; -#pragma pack (pop) - struct VCO_ElementX { - VCO_Aim_Type type; - double elapsed; - float wls_a; // m/s - float wls_b; // m - float speed; - float acceleration; // m/s^2 - float prediction_pos; // m - float variance; // m - float power; - float angle; - int id; - int missed; - int missed_ml; - int confirmed; - int history_size; - bool tracing; - bool _found; - bool _checked; - bool _delete; - }; - struct VCO_ElementY : VCO_ElementX { - PIVector > history; - }; - VCO_Element v; - VCO_ElementX x; - VCO_ElementY y; - piCout << sizeof(x); - piCout << sizeof(y) << sizeof(y.history) << sizeof(y) - sizeof(y.history) ; - piCout << sizeof(v) << sizeof(v.history) << sizeof(v) - sizeof(v.history) ; - return 0;*/ - - PIVector > in; - in.resize(5); - for (int i = 0; i < in.size_s(); ++i) - for (int j = 0; j < 20; ++j) - in[i] << j+i*100; -// piCout << in.size() << in[0].size(); - PIVector2D f0; - PIVector2D f1(30, 40); - //in.resize(1); - PIVector2D f2(in); - f0 = f2; -// piCout << f0; -// piCout << f1; -// piCout << f2; -// piCout << f2.rows() << f2.cols() << f2.size_all() << f2.rows()*f2.cols(); - piCout << in; - piCout << f2; - piCout << f2.toVectors(); - PIVector t = f2.toPlainVector(); - piCout << t; - piCout << PIVector2D(f2.rows(), f2.cols(), t); - return 0; + A a; + B b; + CONNECTU_QUEUED(&a, ev1, &b, eh0, &b); + CONNECTU_QUEUED(&a, ev1, &b, eh1, &a); + piCout << "start"; + a.ev1(1.5); + piSleep(1); + piCout << a.maybeCallQueuedEvents(); + piSleep(1); + piCout << b.maybeCallQueuedEvents(); + piCout << "end"; // PIFFTWf fft; // fft.preparePlan(50, PIFFTWf::foReal); // PIVector out = fft.calcFFT(in); diff --git a/src_main/core/piobject.cpp b/src_main/core/piobject.cpp index 59756bf6..9e35f293 100755 --- a/src_main/core/piobject.cpp +++ b/src_main/core/piobject.cpp @@ -72,7 +72,7 @@ PIString PIObject::__EHFunc::fullFormat() const { } -PIObject::PIObject(const PIString & name): _signature_(__PIOBJECT_SIGNATURE__), emitter_(0), thread_safe_(false) { +PIObject::PIObject(const PIString & name): _signature_(__PIOBJECT_SIGNATURE__), emitter_(0), thread_safe_(false), proc_event_queue(false) { piMonitor.objects++; //__PIVariantInitBuiltin__(); setName(name); @@ -225,7 +225,7 @@ void PIObject::piConnect(PIObject * src, const PIString & sig, PIObject * dest_o } -bool PIObject::piConnectU(PIObject * src, const PIString & ename, PIObject * dest_o, void * dest, const PIString & hname, const char * loc) { +bool PIObject::piConnectU(PIObject * src, const PIString & ename, PIObject * dest_o, void * dest, const PIString & hname, const char * loc, PIObject * performer) { if (src == 0 || dest_o == 0 || dest == 0) return false; if (!src->isPIObject()) { piCout << "[piConnectU] \"" << ename << "\" -> \"" << hname << "\" error: source object is not PIObject! (" << loc << ")"; @@ -249,13 +249,14 @@ bool PIObject::piConnectU(PIObject * src, const PIString & ename, PIObject * des } void * addr_src(0), * addr_dest(0); int args(0); + bool que = (performer != 0); piForeachC (__EHFunc & fs, m_src) { if (addr_src != 0) break; piForeachC (__EHFunc & fd, m_dest) { if (addr_src != 0) break; if (fs.arguments().startsWith(fd.arguments()) || fd.arguments().isEmpty()) { addr_src = fs.addr; - addr_dest = fd.addr; + addr_dest = que ? fd.addrV : fd.addr; args = fd.names.size_s(); } } @@ -266,7 +267,8 @@ bool PIObject::piConnectU(PIObject * src, const PIString & ename, PIObject * des return false; } //piCout << "connect" << ename << "->" << hname << "with" << args << "args"; - src->connections << PIObject::Connection(addr_dest, addr_src, ename, dest_o, dest, args); + src->connections << PIObject::Connection(addr_dest, addr_src, ename, dest_o, dest, args, performer); + if (que) performer->proc_event_queue = true; dest_o->connectors << src; return true; } @@ -354,6 +356,13 @@ void PIObject::updateConnectors() { } +void PIObject::postQueuedEvent(const PIObject::QueuedEvent & e) { + mutex_queue.lock(); + events_queue << e; + mutex_queue.unlock(); +} + + PIMutex & PIObject::__meta_mutex() { static PIMutex ret; return ret; @@ -366,6 +375,28 @@ PIMap & PIObject::__meta_data() { } +void PIObject::callQueuedEvents() { + mutex_queue.lock(); + PIVector qe = events_queue; + events_queue.clear(); + mutex_queue.unlock(); + piForeachC (QueuedEvent & e, qe) { + if (e.dest_o->thread_safe_) e.dest_o->mutex_.lock(); + e.dest_o->emitter_ = e.src; + switch (e.values.size_s()) { + case 0: ((void(*)(void *))e.slot)(e.dest); break; + case 1: ((void(*)(void * , const PIVariant & ))e.slot)(e.dest, e.values[0]); break; + case 2: ((void(*)(void * , const PIVariant & , const PIVariant & ))e.slot)(e.dest, e.values[0], e.values[1]); break; + case 3: ((void(*)(void * , const PIVariant & , const PIVariant & , const PIVariant & ))e.slot)(e.dest, e.values[0], e.values[1], e.values[2]); break; + case 4: ((void(*)(void * , const PIVariant & , const PIVariant & , const PIVariant & , const PIVariant & ))e.slot)(e.dest, e.values[0], e.values[1], e.values[2], e.values[3]); break; + default: break; + } + e.dest_o->emitter_ = 0; + if (e.dest_o->thread_safe_) e.dest_o->mutex_.unlock(); + } +} + + PIVector & PIObject::objects() { static PIVector ret; return ret; diff --git a/src_main/core/piobject.h b/src_main/core/piobject.h index f2670f27..4b005897 100755 --- a/src_main/core/piobject.h +++ b/src_main/core/piobject.h @@ -29,6 +29,7 @@ #include "pivariant.h" #include "pimutex.h" #include "piset.h" +#include "piqueue.h" #ifdef DOXYGEN @@ -109,6 +110,10 @@ /// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\". \"Event\" and \"handler\" must has equal argument lists. #define CONNECTU(src, event, dest, handler) +/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\". +/// Event handler will be executed by \"performer\". \"Event\" and \"handler\" must has equal argument lists. +#define CONNECTU_QUEUED(src, event, dest, handler, performer) + /// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists #define CONNECT0(ret, src, event, dest, handler) @@ -421,6 +426,7 @@ #define RAISE_EVENT RAISE_EVENT0 #define CONNECTU(src, event, dest, handler) PIObject::piConnectU(src, PIStringAscii(#event), dest, dest, PIStringAscii(#handler), LOCATION); +#define CONNECTU_QUEUED(src, event, dest, handler, performer) PIObject::piConnectU(src, PIStringAscii(#event), dest, dest, PIStringAscii(#handler), LOCATION, performer); #define CONNECT0(ret, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*))(&(src)->__stat_eh_##event##__), 0, LOCATION); #define CONNECT1(ret, a0, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0))(&(src)->__stat_eh_##event##__), 1, LOCATION); @@ -556,7 +562,7 @@ public: // / Direct connect static void piConnect(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, void * ev_h, void * e_h, int args, const char * loc); - static bool piConnectU(PIObject * src, const PIString & ename, PIObject * dest_o, void * dest, const PIString & hname, const char * loc); + static bool piConnectU(PIObject * src, const PIString & ename, PIObject * dest_o, void * dest, const PIString & hname, const char * loc, PIObject * performer = 0); // / Through names and mixed static void piConnect(const PIString & src, const PIString & sig, void * dest, void * ev_h); @@ -578,12 +584,15 @@ public: for (int j = 0; j < sender->connections.size_s(); ++j) { Connection & i(sender->connections[j]); if (i.event != event) continue; - //piCout << uint(i.dest) << uint(i.dest_o); - if (sender->thread_safe_) i.dest_o->mutex_.lock(); - i.dest_o->emitter_ = sender; - ((void( *)(void * ))i.slot)(i.dest); - i.dest_o->emitter_ = 0; - if (sender->thread_safe_) i.dest_o->mutex_.unlock(); + if (i.performer) { + i.performer->postQueuedEvent(QueuedEvent(i.slot, i.dest, i.dest_o, sender)); + } else { + if (sender->thread_safe_) i.dest_o->mutex_.lock(); + i.dest_o->emitter_ = sender; + ((void( *)(void * ))i.slot)(i.dest); + i.dest_o->emitter_ = 0; + if (sender->thread_safe_) i.dest_o->mutex_.unlock(); + } } } @@ -592,12 +601,18 @@ public: for (int j = 0; j < sender->connections.size_s(); ++j) { Connection & i(sender->connections[j]); if (i.event != event) continue; - if (sender->thread_safe_) i.dest_o->mutex_.lock(); - i.dest_o->emitter_ = sender; - if (i.args_count == 0) ((void(*)(void *))i.slot)(i.dest); - else ((void(*)(void * , T0))i.slot)(i.dest, v0); - i.dest_o->emitter_ = 0; - if (sender->thread_safe_) i.dest_o->mutex_.unlock(); + if (i.performer) { + PIVector vl; + if (i.args_count > 0) vl << PIVariant::fromValue(v0); + i.performer->postQueuedEvent(QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); + } else { + if (sender->thread_safe_) i.dest_o->mutex_.lock(); + i.dest_o->emitter_ = sender; + if (i.args_count == 0) ((void(*)(void *))i.slot)(i.dest); + else ((void(*)(void * , T0))i.slot)(i.dest, v0); + i.dest_o->emitter_ = 0; + if (sender->thread_safe_) i.dest_o->mutex_.unlock(); + } } } template @@ -605,15 +620,22 @@ public: for (int j = 0; j < sender->connections.size_s(); ++j) { Connection & i(sender->connections[j]); if (i.event != event) continue; - if (sender->thread_safe_) i.dest_o->mutex_.lock(); - i.dest_o->emitter_ = sender; - switch (i.args_count) { - case 0: ((void(*)(void *))i.slot)(i.dest); break; - case 1: ((void(*)(void * , T0))i.slot)(i.dest, v0); break; - default: ((void(*)(void * , T0, T1))i.slot)(i.dest, v0, v1); break; + if (i.performer) { + PIVector vl; + if (i.args_count > 0) vl << PIVariant::fromValue(v0); + if (i.args_count > 1) vl << PIVariant::fromValue(v1); + i.performer->postQueuedEvent(QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); + } else { + if (sender->thread_safe_) i.dest_o->mutex_.lock(); + i.dest_o->emitter_ = sender; + switch (i.args_count) { + case 0: ((void(*)(void *))i.slot)(i.dest); break; + case 1: ((void(*)(void * , T0))i.slot)(i.dest, v0); break; + default: ((void(*)(void * , T0, T1))i.slot)(i.dest, v0, v1); break; + } + i.dest_o->emitter_ = 0; + if (sender->thread_safe_) i.dest_o->mutex_.unlock(); } - i.dest_o->emitter_ = 0; - if (sender->thread_safe_) i.dest_o->mutex_.unlock(); } } template @@ -621,16 +643,24 @@ public: for (int j = 0; j < sender->connections.size_s(); ++j) { Connection & i(sender->connections[j]); if (i.event != event) continue; - if (sender->thread_safe_) i.dest_o->mutex_.lock(); - i.dest_o->emitter_ = sender; - switch (i.args_count) { - case 0: ((void(*)(void *))i.slot)(i.dest); break; - case 1: ((void(*)(void * , T0))i.slot)(i.dest, v0); break; - case 2: ((void(*)(void * , T0, T1))i.slot)(i.dest, v0, v1); break; - default: ((void(*)(void * , T0, T1, T2))i.slot)(i.dest, v0, v1, v2); break; + if (i.performer) { + PIVector vl; + if (i.args_count > 0) vl << PIVariant::fromValue(v0); + if (i.args_count > 1) vl << PIVariant::fromValue(v1); + if (i.args_count > 2) vl << PIVariant::fromValue(v2); + i.performer->postQueuedEvent(QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); + } else { + if (sender->thread_safe_) i.dest_o->mutex_.lock(); + i.dest_o->emitter_ = sender; + switch (i.args_count) { + case 0: ((void(*)(void *))i.slot)(i.dest); break; + case 1: ((void(*)(void * , T0))i.slot)(i.dest, v0); break; + case 2: ((void(*)(void * , T0, T1))i.slot)(i.dest, v0, v1); break; + default: ((void(*)(void * , T0, T1, T2))i.slot)(i.dest, v0, v1, v2); break; + } + i.dest_o->emitter_ = 0; + if (sender->thread_safe_) i.dest_o->mutex_.unlock(); } - i.dest_o->emitter_ = 0; - if (sender->thread_safe_) i.dest_o->mutex_.unlock(); } } template @@ -638,17 +668,26 @@ public: for (int j = 0; j < sender->connections.size_s(); ++j) { Connection & i(sender->connections[j]); if (i.event != event) continue; - if (sender->thread_safe_) i.dest_o->mutex_.lock(); - i.dest_o->emitter_ = sender; - switch (i.args_count) { - case 0: ((void(*)(void *))i.slot)(i.dest); break; - case 1: ((void(*)(void * , T0))i.slot)(i.dest, v0); break; - case 2: ((void(*)(void * , T0, T1))i.slot)(i.dest, v0, v1); break; - case 3: ((void(*)(void * , T0, T1, T2))i.slot)(i.dest, v0, v1, v2); break; - default: ((void(*)(void * , T0, T1, T2, T3))i.slot)(i.dest, v0, v1, v2, v3); break; + if (i.performer) { + PIVector vl; + if (i.args_count > 0) vl << PIVariant::fromValue(v0); + if (i.args_count > 1) vl << PIVariant::fromValue(v1); + if (i.args_count > 2) vl << PIVariant::fromValue(v2); + if (i.args_count > 3) vl << PIVariant::fromValue(v3); + i.performer->postQueuedEvent(QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); + } else { + if (sender->thread_safe_) i.dest_o->mutex_.lock(); + i.dest_o->emitter_ = sender; + switch (i.args_count) { + case 0: ((void(*)(void *))i.slot)(i.dest); break; + case 1: ((void(*)(void * , T0))i.slot)(i.dest, v0); break; + case 2: ((void(*)(void * , T0, T1))i.slot)(i.dest, v0, v1); break; + case 3: ((void(*)(void * , T0, T1, T2))i.slot)(i.dest, v0, v1, v2); break; + default: ((void(*)(void * , T0, T1, T2, T3))i.slot)(i.dest, v0, v1, v2, v3); break; + } + i.dest_o->emitter_ = 0; + if (sender->thread_safe_) i.dest_o->mutex_.unlock(); } - i.dest_o->emitter_ = 0; - if (sender->thread_safe_) i.dest_o->mutex_.unlock(); } } @@ -754,9 +793,13 @@ public: PIMap eh_func; }; typedef PIPair __EHPair; + static PIMutex & __meta_mutex(); static PIMap & __meta_data(); // [classname]=__MetaData - + + void callQueuedEvents(); + bool maybeCallQueuedEvents() {if (proc_event_queue) callQueuedEvents(); return proc_event_queue;} + protected: //! Returns PIObject* which has raised an event. This value is correct only in definition of some event handler @@ -764,8 +807,7 @@ protected: //! Virtual function executes after property with name "name" has been changed virtual void propertyChanged(const PIString & name) {} - - + EVENT(deleted) //! \events @@ -780,36 +822,53 @@ protected: private: struct Connection { - Connection(void * sl = 0, void * si = 0, const PIString & e = PIString(), PIObject * d_o = 0, void * d = 0, int ac = 0) { + Connection(void * sl = 0, void * si = 0, const PIString & e = PIString(), PIObject * d_o = 0, void * d = 0, int ac = 0, PIObject * p = 0) { slot = sl; signal = si; event = e; dest_o = d_o; dest = d; args_count = ac; + performer = p; } void * slot; void * signal; PIString event; PIObject * dest_o; + PIObject * performer; void * dest; int args_count; }; - + struct QueuedEvent { + QueuedEvent(void * sl = 0, void * d = 0, PIObject * d_o = 0, PIObject * s = 0, const PIVector & v = PIVector()) { + slot = sl; + dest = d; + dest_o = d_o; + src = s; + values = v; + } + void * slot; + void * dest; + PIObject * dest_o; + PIObject * src; + PIVector values; + }; + typedef PIPair Property; + PIVector<__EHFunc> findEH(const PIString & name) const; __EHFunc methodEH(const void * addr) const; void updateConnectors(); - - PIVector connections; - typedef PIPair Property; - PIMap properties_; + void postQueuedEvent(const QueuedEvent & e); static PIVector & objects(); + PIVector connections; + PIMap properties_; PISet connectors; - PIMutex mutex_, mutex_connect; + PIVector events_queue; + PIMutex mutex_, mutex_connect, mutex_queue; PIObject * emitter_; - bool thread_safe_; + bool thread_safe_, proc_event_queue; }; diff --git a/src_main/io/pisharedmemory.cpp b/src_main/io/pisharedmemory.cpp index d867954a..db9b3767 100644 --- a/src_main/io/pisharedmemory.cpp +++ b/src_main/io/pisharedmemory.cpp @@ -249,7 +249,7 @@ int PISharedMemory::read(void * read_to, int max_size, int offset) { memcpy(read_to, &(((char*)(PRIVATE->data))[offset]), max_size); return max_size; #endif - + return -1; } @@ -269,4 +269,5 @@ int PISharedMemory::write(const void * data, int max_size, int offset) { memcpy(&(((char*)(PRIVATE->data))[offset]), data, max_size); return max_size; #endif + return -1; }