18.03.2013 - Bug fixes, add in/out speed diagnostic to PIProtocol, fixed PIConsole tab switch segfault, PIObject EVENT / EVENT_HANDLER mechanism update - new EVENT macros that use EVENT_HANDLER with raiseEvent implementation.

This allow compile check event for CONNECT and use EVENT as CONNECT target, also raise event now is simple execute EVENT function.
This commit is contained in:
peri4
2013-03-18 12:07:44 +04:00
parent cfc5eed75e
commit 66c53a27fc
72 changed files with 4407 additions and 960 deletions

120
piobject.h Executable file → Normal file
View File

@@ -1,7 +1,7 @@
/*
PIP - Platform Independent Primitives
Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,37 +22,62 @@
#include "pistring.h"
//#ifdef CC_VC
//#define HANDLER(c,s) #s,PIObject::handlerPtr<c>((void(c::*)())&c::s)
//#else
//#define HANDLER(c,s) #s,(void*)&c::s
//#endif
//#define EVENT_HANDLER0(obj, name) static void __stat_##name##__(obj * o) {o->name();} void name()
//#define EVENT_HANDLER1(obj, name, a0, n0) static void __stat_##name##__(obj * o, a0 n0) {o->name(n0);} void name(a0 n0)
//#define EVENT_HANDLER2(obj, name, a0, n0, a1, n1) static void __stat_##name##__(obj * o, a0 n0, a1 n1) {o->name(n0, n1);} void name(a0 n0, a1 n1)
#define EVENT_HANDLER0(obj, ret, name) static ret __stat_##name##__(void * o) {return ((obj*)o)->name();} ret name()
#define EVENT_HANDLER1(obj, ret, name, a0, n0) static ret __stat_##name##__(void * o, a0 n0) {return ((obj*)o)->name(n0);} ret name(a0 n0)
#define EVENT_HANDLER2(obj, ret, name, a0, n0, a1, n1) static ret __stat_##name##__(void * o, a0 n0, a1 n1) {return ((obj*)o)->name(n0, n1);} ret name(a0 n0, a1 n1)
#define EVENT_HANDLER3(obj, ret, name, a0, n0, a1, n1, a2, n2) static ret __stat_##name##__(void * o, a0 n0, a1 n1, a2 n2) {return ((obj*)o)->name(n0, n1, n2);} ret name(a0 n0, a1 n1, a2 n2)
#define EVENT_HANDLER4(obj, ret, name, a0, n0, a1, n1, a2, n2, a3, n3) static ret __stat_##name##__(void * o, a0 n0, a1 n1, a2 n2, a3 n3) {return ((obj*)o)->name(n0, n1, n2, n3);} ret name(a0 n0, a1 n1, a2 n2, a3 n3)
/// declare event handler \"event\" inside class \"obj\" with name \"name\", ret name()
#define EVENT_HANDLER0(obj, ret, name) static ret __stat_eh_##name##__(void * o) {return ((obj*)o)->name();} ret name()
#define EVENT_HANDLER1(obj, ret, name, a0, n0) static ret __stat_eh_##name##__(void * o, a0 n0) {return ((obj*)o)->name(n0);} ret name(a0 n0)
#define EVENT_HANDLER2(obj, ret, name, a0, n0, a1, n1) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1) {return ((obj*)o)->name(n0, n1);} ret name(a0 n0, a1 n1)
#define EVENT_HANDLER3(obj, ret, name, a0, n0, a1, n1, a2, n2) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1, a2 n2) {return ((obj*)o)->name(n0, n1, n2);} ret name(a0 n0, a1 n1, a2 n2)
#define EVENT_HANDLER4(obj, ret, name, a0, n0, a1, n1, a2, n2, a3, n3) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1, a2 n2, a3 n3) {return ((obj*)o)->name(n0, n1, n2, n3);} ret name(a0 n0, a1 n1, a2 n2, a3 n3)
#define EVENT_HANDLER EVENT_HANDLER0
#define EVENT_VHANDLER0(obj, ret, name) static ret __stat_##name##__(void * o) {return ((obj*)o)->name();} virtual ret name()
#define EVENT_VHANDLER1(obj, ret, name, a0, n0) static ret __stat_##name##__(void * o, a0 n0) {return ((obj*)o)->name(n0);} virtual ret name(a0 n0)
#define EVENT_VHANDLER2(obj, ret, name, a0, n0, a1, n1) static ret __stat_##name##__(void * o, a0 n0, a1 n1) {return ((obj*)o)->name(n0, n1);} virtual ret name(a0 n0, a1 n1)
#define EVENT_VHANDLER3(obj, ret, name, a0, n0, a1, n1, a2, n2) static ret __stat_##name##__(void * o, a0 n0, a1 n1, a2 n2) {return ((obj*)o)->name(n0, n1, n2);} virtual ret name(a0 n0, a1 n1, a2 n2)
#define EVENT_VHANDLER4(obj, ret, name, a0, n0, a1, n1, a2, n2, a3, n3) static ret __stat_##name##__(void * o, a0 n0, a1 n1, a2 n2, a3 n3) {return ((obj*)o)->name(n0, n1, n2, n3);} virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)
/// declare virtual event handler \"event\" inside class \"obj\" with name \"name\", virtual ret name()
#define EVENT_VHANDLER0(obj, ret, name) static ret __stat_eh_##name##__(void * o) {return ((obj*)o)->name();} virtual ret name()
#define EVENT_VHANDLER1(obj, ret, name, a0, n0) static ret __stat_eh_##name##__(void * o, a0 n0) {return ((obj*)o)->name(n0);} virtual ret name(a0 n0)
#define EVENT_VHANDLER2(obj, ret, name, a0, n0, a1, n1) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1) {return ((obj*)o)->name(n0, n1);} virtual ret name(a0 n0, a1 n1)
#define EVENT_VHANDLER3(obj, ret, name, a0, n0, a1, n1, a2, n2) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1, a2 n2) {return ((obj*)o)->name(n0, n1, n2);} virtual ret name(a0 n0, a1 n1, a2 n2)
#define EVENT_VHANDLER4(obj, ret, name, a0, n0, a1, n1, a2, n2, a3, n3) static ret __stat_eh_##name##__(void * o, a0 n0, a1 n1, a2 n2, a3 n3) {return ((obj*)o)->name(n0, n1, n2, n3);} virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)
#define EVENT_VHANDLER EVENT_VHANDLER0
#define CONNECT0(ret, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*))(&(dst)->__stat_##handler##__));
#define CONNECT1(ret, a0, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0))(&(dst)->__stat_##handler##__));
#define CONNECT2(ret, a0, a1, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0, a1))(&(dst)->__stat_##handler##__));
#define CONNECT3(ret, a0, a1, a2, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2))(&(dst)->__stat_##handler##__));
#define CONNECT4(ret, a0, a1, a2, a3, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dst)->__stat_##handler##__));
/// declare event \"event\" inside class \"obj\" with name \"name\", void name();
#define EVENT0(obj, name) EVENT_HANDLER0(obj, void, name) {PIObject::raiseEvent(this, #name);}
#define EVENT1(obj, name, a0, n0) EVENT_HANDLER1(obj, void, name, a0, n0) {PIObject::raiseEvent(this, #name, n0);}
#define EVENT2(obj, name, a0, n0, a1, n1) EVENT_HANDLER2(obj, void, name, a0, n0, a1, n1) {PIObject::raiseEvent(this, #name, n0, n1);}
#define EVENT3(obj, name, a0, n0, a1, n1, a2, n2) EVENT_HANDLER3(obj, void, name, a0, n0, a1, n1, a2, n2) {PIObject::raiseEvent(this, #name, n0, n1, n2);}
#define EVENT4(obj, name, a0, n0, a1, n1, a2, n2, a3, n3) EVENT_HANDLER4(obj, void, name, a0, n0, a1, n1, a2, n2, a3, n3) {PIObject::raiseEvent(this, #name, n0, n1, n2, n3);}
#define EVENT EVENT0
/// raise event \"event\" from object \"src\"
#define RAISE_EVENT0(src, event) (src)->event();
#define RAISE_EVENT1(src, event, v0) (src)->event(v0);
#define RAISE_EVENT2(src, event, v0, v1) (src)->event(v0, v1);
#define RAISE_EVENT3(src, event, v0, v1, v2) (src)->event(v0, v1, v2);
#define RAISE_EVENT4(src, event, v0, v1, v2, v3) (src)->event(v0, v1, v2, v3);
#define RAISE_EVENT RAISE_EVENT0
/// connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dst\" with check of event and handler exists
#define CONNECT0(ret, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*))(&(dst)->__stat_eh_##handler##__), (void*)(void(*)(void*))(&(src)->__stat_eh_##event##__));
#define CONNECT1(ret, a0, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0))(&(dst)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0))(&(src)->__stat_eh_##event##__));
#define CONNECT2(ret, a0, a1, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1))(&(dst)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0, a1))(&(src)->__stat_eh_##event##__));
#define CONNECT3(ret, a0, a1, a2, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2))(&(dst)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0, a1, a2))(&(src)->__stat_eh_##event##__));
#define CONNECT4(ret, a0, a1, a2, a3, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dst)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0, a1, a2, a3))(&(src)->__stat_eh_##event##__));
#define CONNECT CONNECT0
/// connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dst\" without check of event exists
#define WEAK_CONNECT0(ret, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*))(&(dst)->__stat_eh_##handler##__));
#define WEAK_CONNECT1(ret, a0, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0))(&(dst)->__stat_eh_##handler##__));
#define WEAK_CONNECT2(ret, a0, a1, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1))(&(dst)->__stat_eh_##handler##__));
#define WEAK_CONNECT3(ret, a0, a1, a2, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2))(&(dst)->__stat_eh_##handler##__));
#define WEAK_CONNECT4(ret, a0, a1, a2, a3, src, event, dst, handler) PIObject::piConnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dst)->__stat_eh_##handler##__));
#define WEAK_CONNECT WEAK_CONNECT0
/// piDisconnect event \"event\" from object \"src\" from event handler \"handler\" from object \"dst\"
#define DISCONNECT0(ret, src, event, dst, handler) PIObject::piDisconnect(src, #event, dst, (void*)(ret(*)(void*))(&(dst)->__stat_eh_##handler##__));
#define DISCONNECT1(ret, a0, src, event, dst, handler) PIObject::piDisconnect(src, #event, dst, (void*)(ret(*)(void*, a0))(&(dst)->__stat_eh_##handler##__));
#define DISCONNECT2(ret, a0, a1, src, event, dst, handler) PIObject::piDisconnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1))(&(dst)->__stat_eh_##handler##__));
#define DISCONNECT3(ret, a0, a1, a2, src, event, dst, handler) PIObject::piDisconnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2))(&(dst)->__stat_eh_##handler##__));
#define DISCONNECT4(ret, a0, a1, a2, a3, src, event, dst, handler) PIObject::piDisconnect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dst)->__stat_eh_##handler##__));
#define DISCONNECT DISCONNECT0
class PIObject
{
friend class PIObjectManager;
@@ -109,24 +134,34 @@ public:
}
*/
/// Direct connect
static void connect(PIObject * src, const PIString & sig, void * dest, void * ev_h) {src->connections << Connection(ev_h, sig, dest);}
//static void connect(PIObject & src, const PIString & sig, PIObject * dest, void * ev_h) {src.connections << Connection(ev_h, sig, dest);}
//static void connect(PIObject * src, const PIString & sig, PIObject & dest, void * ev_h) {src->connections << Connection(ev_h, sig, &dest);}
//static void connect(PIObject & src, const PIString & sig, PIObject & dest, void * ev_h) {src.connections << Connection(ev_h, sig, &dest);}
static void piConnect(PIObject * src, const PIString & sig, void * dest, void * ev_h) {src->connections << Connection(ev_h, 0, sig, dest);}
static void piConnect(PIObject * src, const PIString & sig, void * dest, void * ev_h, void * e_h) {src->connections << Connection(ev_h, e_h, sig, dest);}
static void piDisconnect(PIObject * src, const PIString & sig, void * dest, void * ev_h) {
for (int i = 0; i < src->connections.size_s(); ++i) {
Connection & cc(src->connections[i]);
if (cc.event == sig && cc.dest == dest && cc.slot == ev_h) {
src->connections.remove(i);
i--;
}
}
}
//static void piConnect(PIObject & src, const PIString & sig, PIObject * dest, void * ev_h) {src.connections << Connection(ev_h, sig, dest);}
//static void piConnect(PIObject * src, const PIString & sig, PIObject & dest, void * ev_h) {src->connections << Connection(ev_h, sig, &dest);}
//static void piConnect(PIObject & src, const PIString & sig, PIObject & dest, void * ev_h) {src.connections << Connection(ev_h, sig, &dest);}
/*/// Connect through manager
static bool connect(const PIString & srcObject, const PIString & event, const PIString & destObject, const PIString & handler, bool force = false) {
static bool piConnect(const PIString & srcObject, const PIString & event, const PIString & destObject, const PIString & handler, bool force = false) {
PIObject * src = findByName(srcObject);
if (src == 0) {
cout << "PIObject::connect: can`t find PIObject with \"" << srcObject << "\" name!" << endl;
cout << "PIObject::piConnect: can`t find PIObject with \"" << srcObject << "\" name!" << endl;
return false;
}
PIObject * dest = findByName(destObject);
if (dest == 0) {
cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
cout << "PIObject::piConnect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
return false;
}
return PIObject::connect(src, event, dest, handler, force);
return PIObject::piConnect(src, event, dest, handler, force);
}*/
/// Raise events
@@ -195,7 +230,7 @@ public:
static void raiseEvent(const PIString & destObject, const PIString & name) {
PIObject * dest = findByName(destObject);
if (dest == 0) {
cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
cout << "PIObject::piConnect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
return;
}
raiseEvent(dest, name);
@@ -204,7 +239,7 @@ public:
static void raiseEvent(const PIString & destObject, const PIString & name, const T0 & v0 = T0()) {
PIObject * dest = findByName(destObject);
if (dest == 0) {
cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
cout << "PIObject::piConnect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
return;
}
raiseEvent<T0>(dest, name, v0);
@@ -213,7 +248,7 @@ public:
static void raiseEvent(const PIString & destObject, const PIString & name, const T0 & v0 = T0(), const T1 & v1 = T1()) {
PIObject * dest = findByName(destObject);
if (dest == 0) {
cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
cout << "PIObject::piConnect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
return;
}
raiseEvent<T0, T1>(dest, name, v0, v1);
@@ -222,7 +257,7 @@ public:
static void raiseEvent(const PIString & destObject, const PIString & name, const T0 & v0 = T0(), const T1 & v1 = T1(), const T2 & v2 = T2()) {
PIObject * dest = findByName(destObject);
if (dest == 0) {
cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
cout << "PIObject::piConnect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
return;
}
raiseEvent<T0, T1, T2>(name, dest, v0, v1, v2);
@@ -231,21 +266,24 @@ public:
static void raiseEvent(const PIString & destObject, const PIString & name, const T0 & v0 = T0(), const T1 & v1 = T1(), const T2 & v2 = T2(), const T3 & v3 = T3()) {
PIObject * dest = findByName(destObject);
if (dest == 0) {
cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
cout << "PIObject::piConnect: can`t find PIObject with \"" << destObject << "\" name!" << endl;
return;
}
raiseEvent<T0, T1, T2, T3>(name,dest , v0, v1, v2, v3);
}
protected:
PIString name_;
private:
struct Connection {
Connection(void * s = 0, const PIString & e = PIString(), void * o = 0) {slot = s; event = e; dest = o;}
Connection(void * sl = 0, void * si = 0, const PIString & e = PIString(), void * o = 0) {slot = sl; signal = si; event = e; dest = o;}
void * slot;
void * signal;
PIString event;
void * dest;
};
PIString name_;
PIVector<Connection> connections;
static PIVector<PIObject * > objects;