git-svn-id: svn://db.shs.com.ru/pip@886 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2020-02-26 11:11:59 +00:00
parent d0d709dd5a
commit 3c252bbeae
4 changed files with 679 additions and 92 deletions

View File

@@ -273,22 +273,22 @@ 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, PIObject * performer) {
bool PIObject::piConnectU(PIObject * src, const PIString & sig, 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 << ")";
piCout << "[piConnectU] \"" << sig << "\" -> \"" << hname << "\" error: source object is not PIObject! (" << loc << ")";
return false;
}
if (!dest_o->isPIObject()) {
piCout << "[piConnectU] \"" << ename << "\" -> \"" << hname << "\" error: destination object is not PIObject! (" << loc << ")";
piCout << "[piConnectU] \"" << sig << "\" -> \"" << hname << "\" error: destination object is not PIObject! (" << loc << ")";
return false;
}
PIMutexLocker ml(__meta_mutex());
PIMutexLocker mls(src->mutex_connect);
PIMutexLocker mld(dest_o->mutex_connect, src != dest_o);
PIVector<__MetaFunc> m_src = src->findEH(ename), m_dest = dest_o->findEH(hname);
PIVector<__MetaFunc> m_src = src->findEH(sig), m_dest = dest_o->findEH(hname);
if (m_src.isEmpty()) {
piCout << "[piConnectU] Error: can`t find event \"" << ename << "\" in class \"" << src->className() << "\"! (" << loc << ")";
piCout << "[piConnectU] Error: can`t find event \"" << sig << "\" in class \"" << src->className() << "\"! (" << loc << ")";
return false;
}
if (m_dest.isEmpty()) {
@@ -310,11 +310,11 @@ bool PIObject::piConnectU(PIObject * src, const PIString & ename, PIObject * des
}
}
if (addr_src == 0) {
piCout << "[piConnectU] Error: can`t find suitable pair of event \"" << ename << "\" in class \"" << src->className()
piCout << "[piConnectU] Error: can`t find suitable pair of event \"" << sig << "\" in class \"" << src->className()
<< "\" and handler \"" << hname << "\" in class \"" << dest_o->className() << "\"! (" << loc << ")";
return false;
}
src->connections << PIObject::__Connection(addr_dest, addr_src, ename, dest_o, dest, args, performer);
src->connections << PIObject::__Connection(addr_dest, addr_src, sig, dest_o, dest, args, performer);
if (que) performer->proc_event_queue = true;
dest_o->connectors << src;
//piCout << cc << cq << _ol.size();//"connect" << src << "->" << dest_o << ", dest.connectors.size() =" << dest_o->connectors.size();
@@ -322,12 +322,48 @@ bool PIObject::piConnectU(PIObject * src, const PIString & ename, PIObject * des
}
#ifdef PIP_CXX11_SUPPORT
bool PIObject::piConnectLS(PIObject * src, const PIString & sig, std::function<void()> * f, const char * loc) {
if (src == 0) {
delete f;
return false;
}
if (!src->isPIObject()) {
piCout << "[piConnectLS] \"" << sig << "\" -> [lambda] error: source object is not PIObject! (" << loc << ")";
delete f;
return false;
}
PIMutexLocker ml(__meta_mutex());
PIMutexLocker mls(src->mutex_connect);
//piCout << "locked";
PIVector<__MetaFunc> m_src = src->findEH(sig);
if (m_src.isEmpty()) {
piCout << "[piConnectLS] Error: can`t find event \"" << sig << "\" in class \"" << src->className() << "\"! (" << loc << ")";
delete f;
return false;
}
if (m_src.size() != 1) {
piCout << "[piConnectLS] Error: can`t connect overloaded event \"" << sig << "\" in class \"" << src->className() << "\"! (" << loc << ")";
delete f;
return false;
}
PIObject::__Connection conn(0, m_src[0].addr, sig);
//piCout << "found";
conn.functor = f;
src->connections << conn;
//piCout << "finished";
return true;
}
#endif
void PIObject::piDisconnect(PIObject * src, const PIString & sig, PIObject * dest, void * ev_h) {
PIMutexLocker _ml(src->mutex_connect);
PIMutexLocker _mld(dest->mutex_connect, src != dest);
for (int i = 0; i < src->connections.size_s(); ++i) {
__Connection & cc(src->connections[i]);
if (cc.event == sig && cc.dest_o == dest && cc.slot == ev_h) {
src->connections[i].destroy();
src->connections.remove(i);
i--;
}
@@ -342,6 +378,7 @@ void PIObject::piDisconnect(PIObject * src, const PIString & sig, PIObject * des
for (int i = 0; i < src->connections.size_s(); ++i) {
__Connection & cc(src->connections[i]);
if (cc.event == sig && cc.dest_o == dest) {
src->connections[i].destroy();
src->connections.remove(i);
i--;
}
@@ -356,12 +393,15 @@ void PIObject::piDisconnect(PIObject * src, const PIString & sig) {
__Connection & cc(src->connections[i]);
if (cc.event == sig) {
PIObject * dest = cc.dest_o;
src->connections.remove(i);
i--;
if (!dest) {
src->connections[i].destroy();
src->connections.remove(i);
i--;
#if !defined(ANDROID) && !defined(MAC_OS) && !defined(FREERTOS)
PIMutexLocker _mld(dest->mutex_connect, src != dest);
PIMutexLocker _mld(dest->mutex_connect, src != dest);
#endif
dest->updateConnectors();
dest->updateConnectors();
}
}
}
}
@@ -380,17 +420,23 @@ void PIObject::piDisconnect(PIObject * src) {
#endif
PIVector<__Connection> & oc(o->connections);
for (int i = 0; i < oc.size_s(); ++i) {
if (oc[i].functor) continue;
//piCout << " check" << (void*)(oc[i].dest_o) << "==" << (void*)(src);
if (oc[i].dest_o == src) {
oc[i].destroy();
oc.remove(i);
--i;
}
}
}
piForeachC (PIObject::__Connection & c, src->connections) {
if (c.functor) continue;
if (!c.dest_o) continue;
if (!c.dest_o->isPIObject()) continue;
c.dest_o->connectors.remove(src);
}
for (int i = 0; i < src->connections.size_s(); ++i)
src->connections[i].destroy();
src->connections.clear();
}
@@ -562,14 +608,18 @@ void PIObject::dump(const PIString & line_prefix) const {
//printf("dump %d connections\n",connections.size());
piForeachC (__Connection & c, connections) {
PIObject * dst = c.dest_o;
__MetaFunc hf = dst->methodEH(c.slot);
__MetaFunc ef = methodEH(c.signal);
if (hf.func_name.isEmpty()) hf.func_name = "[BROKEN]";
else hf.func_name += "(" + hf.arguments() + ")";
PIString src(c.event);
if (!ef.func_name.isEmpty())
src = ef.func_name + "(" + ef.arguments() + ")";
PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << src << " -> " << dst->className() << " (" << c.dest << ", \"" << dst->name() << "\")::" << hf.func_name;
if (dst) {
__MetaFunc hf = dst->methodEH(c.slot);
if (hf.func_name.isEmpty()) hf.func_name = "[BROKEN]";
else hf.func_name += "(" + hf.arguments() + ")";
PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << src << " -> " << dst->className() << " (" << c.dest << ", \"" << dst->name() << "\")::" << hf.func_name;
} else {
PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << src << " -> " << "[lambda]";
}
}
//printf("dump %d connections ok\n",connections.size());
PICout(PICoutManipulators::AddNewLine) << line_prefix << " }";
@@ -630,3 +680,13 @@ void PIObject::__MetaData::addScope(const PIString & s) {
scope_id << s.hash();
}
}
void PIObject::__Connection::destroy() {
#ifdef PIP_CXX11_SUPPORT
if (functor) delete functor;
functor = nullptr;
#endif
}

View File

@@ -114,6 +114,9 @@
/// 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 lambda-expression \"functor\". \"Event\" and \"functor\" must has equal argument lists.
#define CONNECTL(src, event, functor)
/// \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)
@@ -452,6 +455,9 @@
#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);
#ifdef PIP_CXX11_SUPPORT
# define CONNECTL(src, event, functor) PIObject::piConnectLS(src, PIStringAscii(#event), PIObject::__newFunctor(&(src)->__stat_eh_##event##__, functor), LOCATION);
#endif
#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);
@@ -590,8 +596,15 @@ 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, PIObject * performer = 0);
static bool piConnectU(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, const PIString & hname, const char * loc, PIObject * performer = 0);
#ifdef PIP_CXX11_SUPPORT
static bool piConnectLS(PIObject * src, const PIString & sig, std::function<void()> * f, const char * loc);
template <typename INPUT, typename... TYPES>
static std::function<void()> * __newFunctor(void(*stat_handler)(void*,TYPES...), INPUT functor) {
return (std::function<void()>*)(new std::function<void(TYPES...)>(functor));
}
#endif
// / Through names and mixed
static void piConnect(const PIString & src, const PIString & sig, void * dest, void * ev_h);
static void piConnect(PIObject * src, const PIString & sig, const PIString & dest, void * ev_h);
@@ -612,15 +625,23 @@ public:
for (int j = 0; j < sender->connections.size_s(); ++j) {
__Connection & i(sender->connections[j]);
if (i.eventID != eventID) continue;
if (i.performer) {
i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender));
#ifdef PIP_CXX11_SUPPORT
if (i.functor) {
(*(i.functor))();
} 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();
#endif
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();
}
#ifdef PIP_CXX11_SUPPORT
}
#endif
}
}
@@ -629,18 +650,26 @@ public:
for (int j = 0; j < sender->connections.size_s(); ++j) {
__Connection & i(sender->connections[j]);
if (i.eventID != eventID) continue;
if (i.performer) {
PIVector<PIVariant> vl;
if (i.args_count > 0) vl << PIVariant::fromValue(v0);
i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl));
#ifdef PIP_CXX11_SUPPORT
if (i.functor) {
(*((std::function<void(T0)>*)i.functor))(v0);
} 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();
#endif
if (i.performer) {
PIVector<PIVariant> 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();
}
#ifdef PIP_CXX11_SUPPORT
}
#endif
}
}
template <typename T0, typename T1>
@@ -648,22 +677,30 @@ public:
for (int j = 0; j < sender->connections.size_s(); ++j) {
__Connection & i(sender->connections[j]);
if (i.eventID != eventID) continue;
if (i.performer) {
PIVector<PIVariant> 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));
#ifdef PIP_CXX11_SUPPORT
if (i.functor) {
(*((std::function<void(T0, T1)>*)i.functor))(v0, v1);
} 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;
#endif
if (i.performer) {
PIVector<PIVariant> 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();
#ifdef PIP_CXX11_SUPPORT
}
#endif
}
}
template <typename T0, typename T1, typename T2>
@@ -671,24 +708,32 @@ public:
for (int j = 0; j < sender->connections.size_s(); ++j) {
__Connection & i(sender->connections[j]);
if (i.eventID != eventID) continue;
if (i.performer) {
PIVector<PIVariant> 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));
#ifdef PIP_CXX11_SUPPORT
if (i.functor) {
(*((std::function<void(T0, T1, T2)>*)i.functor))(v0, v1, v2);
} 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;
#endif
if (i.performer) {
PIVector<PIVariant> 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();
#ifdef PIP_CXX11_SUPPORT
}
#endif
}
}
template <typename T0, typename T1, typename T2, typename T3>
@@ -696,26 +741,34 @@ public:
for (int j = 0; j < sender->connections.size_s(); ++j) {
__Connection & i(sender->connections[j]);
if (i.eventID != eventID) continue;
if (i.performer) {
PIVector<PIVariant> 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));
#ifdef PIP_CXX11_SUPPORT
if (i.functor) {
(*((std::function<void(T0, T1, T2, T3)>*)i.functor))(v0, v1, v2, v3);
} 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;
#endif
if (i.performer) {
PIVector<PIVariant> 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();
#ifdef PIP_CXX11_SUPPORT
}
#endif
}
}
@@ -815,9 +868,16 @@ private:
dest = d;
args_count = ac;
performer = p;
#ifdef PIP_CXX11_SUPPORT
functor = 0;
#endif
}
void destroy();
void * slot;
void * signal;
#ifdef PIP_CXX11_SUPPORT
std::function<void()> * functor;
#endif
PIString event;
uint eventID;
PIObject * dest_o;