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

This commit is contained in:
2017-04-25 12:38:43 +00:00
parent 7f2fa410cf
commit 826db9e87d
7 changed files with 266 additions and 68 deletions

View File

@@ -32,16 +32,77 @@ const char pult_config[] =
"; ";
*/ */
#include <typeinfo>
template<typename T>
struct Info {
enum {Defined = 0};
};
template<typename T>
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<T> { \
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 <typename T>
class A { class A {
public: public:
void f() { void f() {
piCout << this; piCout << "T";
}
};
template <typename T>
class A<const T&> {
public:
void f() {
piCout << "const T&";
} }
}; };
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
PIVariant v; PIString s("123");
A a = v.value<A>(); typedef PIString & MyT;
MyT i(s);
PIVariant v = PIVariant::fromValue(i);
piCout << v << v.value<__PIVariantTypeInfo__<MyT>::PureType>();
/*typedef PIString MyT;
piCout << typeid(MyT).name();
piCout << typeid(MyT&).name();
piCout << typeid(const MyT).name();
piCout << typeid(const MyT &).name();
piCout << typeid(MyT*).name();
piCout << typeid(const MyT*).name();
piCout << "";
piCout << typeid(TypeInfo<MyT>::PureType).name();
piCout << typeid(TypeInfo<MyT&>::PureType).name();
piCout << typeid(TypeInfo<const MyT>::PureType).name();
piCout << typeid(TypeInfo<const MyT&>::PureType).name();
piCout << typeid(TypeInfo<MyT*>::PureType).name();
piCout << typeid(TypeInfo<const MyT*>::PureType).name();*/
// v = PIVariant::fromValue(a); // v = PIVariant::fromValue(a);

View File

@@ -180,6 +180,8 @@
#define _PI_STR(x) #x #define _PI_STR(x) #x
#define _PI_SSTR(x) _PI_STR(x) #define _PI_SSTR(x) _PI_STR(x)
#define LOCATION __FILE__ ":" _PI_SSTR(__LINE__) #define LOCATION __FILE__ ":" _PI_SSTR(__LINE__)
#define __PTYPE(t) typename __PIVariantTypeInfo__<t>::PureType
#define __VVALUE(t, v) v.value< __PTYPE(t) >()
#define PIOBJECT(name) \ #define PIOBJECT(name) \
@@ -224,12 +226,14 @@
PIMutexLocker ml(__meta_mutex()); \ PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameS()]); \ __MetaData & eh(__meta_data()[__classNameS()]); \
void * fp = (void*)(ret(*)(void*))__stat_eh_##name##__; \ void * fp = (void*)(ret(*)(void*))__stat_eh_##name##__; \
void * fpV = fp; \
if (eh.eh_set[fp]) return; \ if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \ eh.eh_set << fp; \
__EHFunc & f(eh.eh_func[fp]); \ __EHFunc & f(eh.eh_func[fp]); \
f.scope = __classNameS(); \ f.scope = __classNameS(); \
f.func_name = PIStringAscii(#name); \ f.func_name = PIStringAscii(#name); \
f.addr = fp; \ f.addr = fp; \
f.addrV = fpV; \
f.type_ret = PIStringAscii(#ret); \ f.type_ret = PIStringAscii(#ret); \
} \ } \
}; \ }; \
@@ -242,12 +246,14 @@
PIMutexLocker ml(__meta_mutex()); \ PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameS()]); \ __MetaData & eh(__meta_data()[__classNameS()]); \
void * fp = (void*)(ret(*)(void*, a0))__stat_eh_##name##__; \ void * fp = (void*)(ret(*)(void*, a0))__stat_eh_##name##__; \
void * fpV = (void*)(ret(*)(void*, const PIVariant &))__stat_eh_v_##name##__; \
if (eh.eh_set[fp]) return; \ if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \ eh.eh_set << fp; \
__EHFunc & f(eh.eh_func[fp]); \ __EHFunc & f(eh.eh_func[fp]); \
f.scope = __classNameS(); \ f.scope = __classNameS(); \
f.func_name = PIStringAscii(#name); \ f.func_name = PIStringAscii(#name); \
f.addr = fp; \ f.addr = fp; \
f.addrV = fpV; \
f.type_ret = PIStringAscii(#ret); \ f.type_ret = PIStringAscii(#ret); \
f.types << PIObject::simplifyType(#a0); \ f.types << PIObject::simplifyType(#a0); \
f.names << PIStringAscii(#n0); \ f.names << PIStringAscii(#n0); \
@@ -262,12 +268,14 @@
PIMutexLocker ml(__meta_mutex()); \ PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameS()]); \ __MetaData & eh(__meta_data()[__classNameS()]); \
void * fp = (void*)(ret(*)(void*, a0, a1))__stat_eh_##name##__; \ void * fp = (void*)(ret(*)(void*, a0, a1))__stat_eh_##name##__; \
void * fpV = (void*)(ret(*)(void*, const PIVariant &, const PIVariant &))__stat_eh_v_##name##__; \
if (eh.eh_set[fp]) return; \ if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \ eh.eh_set << fp; \
__EHFunc & f(eh.eh_func[fp]); \ __EHFunc & f(eh.eh_func[fp]); \
f.scope = __classNameS(); \ f.scope = __classNameS(); \
f.func_name = PIStringAscii(#name); \ f.func_name = PIStringAscii(#name); \
f.addr = fp; \ f.addr = fp; \
f.addrV = fpV; \
f.type_ret = PIStringAscii(#ret); \ f.type_ret = PIStringAscii(#ret); \
f.types << PIObject::simplifyType(#a0) << PIObject::simplifyType(#a1); \ f.types << PIObject::simplifyType(#a0) << PIObject::simplifyType(#a1); \
f.names << PIStringAscii(#n0) << PIStringAscii(#n1); \ f.names << PIStringAscii(#n0) << PIStringAscii(#n1); \
@@ -282,12 +290,14 @@
PIMutexLocker ml(__meta_mutex()); \ PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameS()]); \ __MetaData & eh(__meta_data()[__classNameS()]); \
void * fp = (void*)(ret(*)(void*, a0, a1, a2))__stat_eh_##name##__; \ void * fp = (void*)(ret(*)(void*, a0, a1, a2))__stat_eh_##name##__; \
void * fpV = (void*)(ret(*)(void*, const PIVariant &, const PIVariant &, const PIVariant &))__stat_eh_v_##name##__; \
if (eh.eh_set[fp]) return; \ if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \ eh.eh_set << fp; \
__EHFunc & f(eh.eh_func[fp]); \ __EHFunc & f(eh.eh_func[fp]); \
f.scope = __classNameS(); \ f.scope = __classNameS(); \
f.func_name = PIStringAscii(#name); \ f.func_name = PIStringAscii(#name); \
f.addr = fp; \ f.addr = fp; \
f.addrV = fpV; \
f.type_ret = PIStringAscii(#ret); \ f.type_ret = PIStringAscii(#ret); \
f.types << PIObject::simplifyType(#a0) << PIObject::simplifyType(#a1) << PIObject::simplifyType(#a2); \ f.types << PIObject::simplifyType(#a0) << PIObject::simplifyType(#a1) << PIObject::simplifyType(#a2); \
f.names << PIStringAscii(#n0) << PIStringAscii(#n1) << PIStringAscii(#n2); \ f.names << PIStringAscii(#n0) << PIStringAscii(#n1) << PIStringAscii(#n2); \
@@ -302,12 +312,14 @@
PIMutexLocker ml(__meta_mutex()); \ PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameS()]); \ __MetaData & eh(__meta_data()[__classNameS()]); \
void * fp = (void*)(ret(*)(void*, a0, a1, a2, a3))__stat_eh_##name##__; \ void * fp = (void*)(ret(*)(void*, a0, a1, a2, a3))__stat_eh_##name##__; \
void * fpV = (void*)(ret(*)(void*, const PIVariant &, const PIVariant &, const PIVariant &, const PIVariant &))__stat_eh_v_##name##__; \
if (eh.eh_set[fp]) return; \ if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \ eh.eh_set << fp; \
__EHFunc & f(eh.eh_func[fp]); \ __EHFunc & f(eh.eh_func[fp]); \
f.scope = __classNameS(); \ f.scope = __classNameS(); \
f.func_name = PIStringAscii(#name); \ f.func_name = PIStringAscii(#name); \
f.addr = fp; \ f.addr = fp; \
f.addrV = fpV; \
f.type_ret = PIStringAscii(#ret); \ f.type_ret = PIStringAscii(#ret); \
f.types << PIObject::simplifyType(#a0) << PIObject::simplifyType(#a1) << PIObject::simplifyType(#a2) << PIObject::simplifyType(#a3); \ f.types << PIObject::simplifyType(#a0) << PIObject::simplifyType(#a1) << PIObject::simplifyType(#a2) << PIObject::simplifyType(#a3); \
f.names << PIStringAscii(#n0) << PIStringAscii(#n1) << PIStringAscii(#n2) << PIStringAscii(#n3); \ f.names << PIStringAscii(#n0) << PIStringAscii(#n1) << PIStringAscii(#n2) << PIStringAscii(#n3); \
@@ -324,21 +336,39 @@
#define EVENT_HANDLER1(ret, name, a0, n0) \ #define EVENT_HANDLER1(ret, name, a0, n0) \
EH_INIT1(ret, name, a0, n0) \ EH_INIT1(ret, name, a0, n0) \
static ret __stat_eh_##name##__(void * __o__, a0 n0) {return ((__PIObject__*)__o__)->name(n0);} \ static ret __stat_eh_##name##__(void * __o__, a0 n0) {return ((__PIObject__*)__o__)->name(n0);} \
static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0) { \
__PTYPE(a0) tv0 = __VVALUE(a0, v0); \
return ((__PIObject__*)__o__)->name(tv0);} \
ret name(a0 n0) ret name(a0 n0)
#define EVENT_HANDLER2(ret, name, a0, n0, a1, n1) \ #define EVENT_HANDLER2(ret, name, a0, n0, a1, n1) \
EH_INIT2(ret, name, a0, n0, a1, n1) \ EH_INIT2(ret, name, a0, n0, a1, n1) \
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) {return ((__PIObject__*)__o__)->name(n0, n1);} \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) {return ((__PIObject__*)__o__)->name(n0, n1);} \
static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1) { \
__PTYPE(a0) tv0 = __VVALUE(a0, v0); \
__PTYPE(a1) tv1 = __VVALUE(a1, v1); \
return ((__PIObject__*)__o__)->name(tv0, tv1);} \
ret name(a0 n0, a1 n1) ret name(a0 n0, a1 n1)
#define EVENT_HANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \ #define EVENT_HANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \
EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \ EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) {return ((__PIObject__*)__o__)->name(n0, n1, n2);} \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) {return ((__PIObject__*)__o__)->name(n0, n1, n2);} \
static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) { \
__PTYPE(a0) tv0 = __VVALUE(a0, v0); \
__PTYPE(a1) tv1 = __VVALUE(a1, v1); \
__PTYPE(a2) tv2 = __VVALUE(a2, v2); \
return ((__PIObject__*)__o__)->name(tv0, tv1, tv2);} \
ret name(a0 n0, a1 n1, a2 n2) ret name(a0 n0, a1 n1, a2 n2)
#define EVENT_HANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ #define EVENT_HANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \
EH_INIT4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ EH_INIT4(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 ((__PIObject__*)__o__)->name(n0, n1, n2, n3);} \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2, a3 n3) {return ((__PIObject__*)__o__)->name(n0, n1, n2, n3);} \
static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2, const PIVariant & v3) { \
__PTYPE(a0) tv0 = __VVALUE(a0, v0); \
__PTYPE(a1) tv1 = __VVALUE(a1, v1); \
__PTYPE(a2) tv2 = __VVALUE(a2, v2); \
__PTYPE(a3) tv3 = __VVALUE(a3, v3); \
return ((__PIObject__*)__o__)->name(tv0, tv1, tv2, tv3);} \
ret name(a0 n0, a1 n1, a2 n2, a3 n3) ret name(a0 n0, a1 n1, a2 n2, a3 n3)
#define EVENT_HANDLER EVENT_HANDLER0 #define EVENT_HANDLER EVENT_HANDLER0
@@ -352,21 +382,25 @@
#define EVENT_VHANDLER1(ret, name, a0, n0) \ #define EVENT_VHANDLER1(ret, name, a0, n0) \
EH_INIT1(ret, name, a0, n0) \ EH_INIT1(ret, name, a0, n0) \
static ret __stat_eh_##name##__(void * __o__, a0 n0) {return ((__PIObject__*)__o__)->name(n0);} \ static ret __stat_eh_##name##__(void * __o__, a0 n0) {return ((__PIObject__*)__o__)->name(n0);} \
static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0));} \
virtual ret name(a0 n0) virtual ret name(a0 n0)
#define EVENT_VHANDLER2(ret, name, a0, n0, a1, n1) \ #define EVENT_VHANDLER2(ret, name, a0, n0, a1, n1) \
EH_INIT2(ret, name, a0, n0, a1, n1) \ EH_INIT2(ret, name, a0, n0, a1, n1) \
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) {return ((__PIObject__*)__o__)->name(n0, n1);} \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) {return ((__PIObject__*)__o__)->name(n0, n1);} \
static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1));} \
virtual ret name(a0 n0, a1 n1) virtual ret name(a0 n0, a1 n1)
#define EVENT_VHANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \ #define EVENT_VHANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \
EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \ EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) {return ((__PIObject__*)__o__)->name(n0, n1, n2);} \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) {return ((__PIObject__*)__o__)->name(n0, n1, n2);} \
static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2));} \
virtual ret name(a0 n0, a1 n1, a2 n2) virtual ret name(a0 n0, a1 n1, a2 n2)
#define EVENT_VHANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ #define EVENT_VHANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \
EH_INIT4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ EH_INIT4(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 ((__PIObject__*)__o__)->name(n0, n1, n2, n3);} \ static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2, a3 n3) {return ((__PIObject__*)__o__)->name(n0, n1, n2, n3);} \
static ret __stat_eh_v_##name##__(void * __o__, const PIVariant & v0, const PIVariant & v1, const PIVariant & v2, const PIVariant & v3) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2), __VVALUE(a3, v3));} \
virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3) virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)
#define EVENT_VHANDLER EVENT_VHANDLER0 #define EVENT_VHANDLER EVENT_VHANDLER0

View File

@@ -54,6 +54,34 @@ struct __PIVariantInfo__ {
bool simple; bool simple;
}; };
template<typename T>
struct __PIVariantTypeInfo__ {
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 __PIVariantTypeInfo__<T> { \
typedef PT PureType; \
typedef const PT ConstPureType; \
typedef PT * PointerType; \
typedef const PT * ConstPointerType; \
typedef PT & ReferenceType; \
typedef const PT & ConstReferenceType; \
};
#define REGISTER_VARIANT_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 *)
class __PIVariantInfoStorage__ { class __PIVariantInfoStorage__ {
public: public:
__PIVariantInfoStorage__() {if (!map) map = new PIMap<PIString, __PIVariantInfo__ * >();} __PIVariantInfoStorage__() {if (!map) map = new PIMap<PIString, __PIVariantInfo__ * >();}
@@ -63,10 +91,12 @@ public:
#define REGISTER_VARIANT_H(classname) \ #define REGISTER_VARIANT_H(classname) \
template<> inline PIString __PIVariantFunctions__< classname >::typeNameHelper() {static PIString tn = PIStringAscii(#classname); return tn;} template<> inline PIString __PIVariantFunctions__< classname >::typeNameHelper() {static PIString tn = PIStringAscii(#classname); return tn;} \
REGISTER_VARIANT_TYPEINFO(classname)
#define REGISTER_NS_VARIANT_H(ns, classname) \ #define REGISTER_NS_VARIANT_H(ns, classname) \
template<> inline PIString __PIVariantFunctions__< ns::classname >::typeNameHelper() {static PIString tn = PIStringAscii(#ns"::"#classname); return tn;} template<> inline PIString __PIVariantFunctions__< ns::classname >::typeNameHelper() {static PIString tn = PIStringAscii(#ns"::"#classname); return tn;} \
REGISTER_VARIANT_TYPEINFO(ns::classname)
#define REGISTER_VARIANT_CPP(classname) \ #define REGISTER_VARIANT_CPP(classname) \
template <typename T> \ template <typename T> \
@@ -149,6 +179,7 @@ classname_to __PIVariantFunctions__<classname_from>::castVariant<classname_to>(c
#else #else
#define REGISTER_VARIANT_TYPEINFO(classname)
#define REGISTER_VARIANT_H(classname) #define REGISTER_VARIANT_H(classname)
#define REGISTER_VARIANT_CPP(classname) #define REGISTER_VARIANT_CPP(classname)
#define INIT_VARIANT(classname) #define INIT_VARIANT(classname)

View File

@@ -37,6 +37,27 @@
* */ * */
PIDiagnostics::State::State() {
immediate_freq = integral_freq = 0.f;
received_packets_per_sec = 0ull;
received_packets = 0ull;
received_packets_wrong = 0ull;
received_bytes_per_sec = 0ull;
received_bytes = 0ull;
received_bytes_wrong = 0ull;
sended_packets_per_sec = 0ull;
sended_packets = 0ull;
sended_bytes_per_sec = 0ull;
sended_bytes = 0ull;
receive_speed = send_speed = PIString::readableSize(0) + "/s";
quality = PIDiagnostics::Unknown;
}
PIDiagnostics::PIDiagnostics(bool start_): PITimer(PITimer::Pool) { PIDiagnostics::PIDiagnostics(bool start_): PITimer(PITimer::Pool) {
disconn_ = 0.; disconn_ = 0.;
setInterval(100); setInterval(100);
@@ -47,13 +68,33 @@ PIDiagnostics::PIDiagnostics(bool start_): PITimer(PITimer::Pool) {
} }
PIDiagnostics::State PIDiagnostics::state() const {
constLock();
State ret = cur_state;
constUnlock();
return ret;
}
PIString PIDiagnostics::receiveSpeed() const {
constLock();
PIString ret = cur_state.receive_speed;
constUnlock();
return ret;
}
PIString PIDiagnostics::sendSpeed() const {
constLock();
PIString ret = cur_state.send_speed;
constUnlock();
return ret;
}
void PIDiagnostics::reset() { void PIDiagnostics::reset() {
lock(); lock();
qual = PIDiagnostics::Unknown; cur_state = State();
speedRecv = speedSend = PIString::readableSize(0) + "/s";
immediate_freq = integral_freq = 0.f;
count_wrong = count_recv = count_send = bytes_wrong = bytes_recv = bytes_send = 0;
packets_recv_sec = packets_send_sec = bytes_recv_sec = bytes_send_sec = 0;
if (disconn_ != 0.) { if (disconn_ != 0.) {
int hist_size = history_rec.size(); int hist_size = history_rec.size();
history_rec.clear(); history_rec.clear();
@@ -71,13 +112,13 @@ void PIDiagnostics::received(int size, bool correct) {
if (correct) { if (correct) {
e.cnt_ok++; e.cnt_ok++;
e.bytes_ok += size; e.bytes_ok += size;
count_recv++; cur_state.received_packets++;
bytes_recv += size; cur_state.received_bytes += size;
} else { } else {
e.cnt_fail++; e.cnt_fail++;
e.bytes_fail += size; e.bytes_fail += size;
count_wrong++; cur_state.received_packets_wrong++;
bytes_wrong += size; cur_state.received_bytes_wrong += size;
} }
e.empty = false; e.empty = false;
unlock(); unlock();
@@ -89,8 +130,8 @@ void PIDiagnostics::sended(int size) {
Entry & e(history_send.front()); Entry & e(history_send.front());
e.cnt_ok++; e.cnt_ok++;
e.bytes_ok += size; e.bytes_ok += size;
count_send++; cur_state.sended_packets++;
bytes_send += size; cur_state.sended_bytes += size;
e.empty = false; e.empty = false;
unlock(); unlock();
} }
@@ -106,25 +147,25 @@ void PIDiagnostics::tick(void * , int ) {
float its = disconn_ * (float(tcnt_send) / history_send.size()); float its = disconn_ * (float(tcnt_send) / history_send.size());
float hz = interval() / 1000.f; float hz = interval() / 1000.f;
if (tcnt_recv == 0) { if (tcnt_recv == 0) {
integral_freq = immediate_freq = 0; cur_state.integral_freq = cur_state.immediate_freq = 0;
packets_recv_sec = bytes_recv_sec = 0; cur_state.received_packets_per_sec = cur_state.received_bytes_per_sec = 0;
} else { } else {
integral_freq = recv.cnt_ok / itr; cur_state.integral_freq = recv.cnt_ok / itr;
packets_recv_sec = ullong(float(recv.cnt_ok) / itr); cur_state.received_packets_per_sec = ullong(float(recv.cnt_ok) / itr);
bytes_recv_sec = ullong(double(recv.bytes_ok) / itr); cur_state.received_bytes_per_sec = ullong(double(recv.bytes_ok) / itr);
immediate_freq = double(history_rec.front().cnt_ok) / hz; cur_state.immediate_freq = double(history_rec.front().cnt_ok) / hz;
} }
if (tcnt_send == 0) { if (tcnt_send == 0) {
packets_send_sec = bytes_send_sec = 0; cur_state.sended_packets_per_sec = cur_state.sended_bytes_per_sec = 0;
} else { } else {
packets_send_sec = ullong(float(send.cnt_ok) / its); cur_state.sended_packets_per_sec = ullong(float(send.cnt_ok) / its);
bytes_send_sec = ullong(double(send.bytes_ok) / its); cur_state.sended_bytes_per_sec = ullong(double(send.bytes_ok) / its);
} }
// piCoutObj << "tick" << recv.cnt_ok << send.cnt_ok; // piCoutObj << "tick" << recv.cnt_ok << send.cnt_ok;
// speedRecv = PIString::readableSize(ullong(double(history_rec.front().bytes_ok) / hz)) + "/s"; // speedRecv = PIString::readableSize(ullong(double(history_rec.front().bytes_ok) / hz)) + "/s";
// speedSend = PIString::readableSize(ullong(double(history_send.front().bytes_ok) / hz)) + "/s"; // speedSend = PIString::readableSize(ullong(double(history_send.front().bytes_ok) / hz)) + "/s";
speedRecv = PIString::readableSize(bytes_recv_sec) + "/s"; cur_state.receive_speed = PIString::readableSize(cur_state.received_bytes_per_sec) + "/s";
speedSend = PIString::readableSize(bytes_send_sec) + "/s"; cur_state.send_speed = PIString::readableSize(cur_state.sended_bytes_per_sec) + "/s";
int arc = recv.cnt_ok + recv.cnt_fail; int arc = recv.cnt_ok + recv.cnt_fail;
float good_percents = 0.f; float good_percents = 0.f;
if (arc > 0) good_percents = (float)recv.cnt_ok / arc * 100.f; if (arc > 0) good_percents = (float)recv.cnt_ok / arc * 100.f;
@@ -147,9 +188,9 @@ void PIDiagnostics::tick(void * , int ) {
history_rec.enqueue(e); history_rec.enqueue(e);
history_send.enqueue(e); history_send.enqueue(e);
} }
if (diag != qual) { if (diag != cur_state.quality) {
qualityChanged(diag, qual); qualityChanged(diag, cur_state.quality);
qual = diag; cur_state.quality = diag;
} }
unlock(); unlock();
} }
@@ -193,3 +234,12 @@ void PIDiagnostics::changeDisconnectTimeout(float disct) {
unlock(); unlock();
} }
void PIDiagnostics::constLock() const {
const_cast<PIDiagnostics*>(this)->lock();
}
void PIDiagnostics::constUnlock() const {
const_cast<PIDiagnostics*>(this)->unlock();
}

View File

@@ -46,7 +46,30 @@ public:
Average /** Average connection, correct packets received > 20% and <= 80% */ = 4, Average /** Average connection, correct packets received > 20% and <= 80% */ = 4,
Good /** Good connection, correct packets received > 80% */ = 5 Good /** Good connection, correct packets received > 80% */ = 5
}; };
//! Information about current diagnostics state
struct State {
State();
float immediate_freq;
float integral_freq;
ullong received_packets_per_sec;
ullong received_packets;
ullong received_packets_wrong;
ullong received_bytes_per_sec;
ullong received_bytes;
ullong received_bytes_wrong;
ullong sended_packets_per_sec;
ullong sended_packets;
ullong sended_bytes_per_sec;
ullong sended_bytes;
PIString receive_speed;
PIString send_speed;
PIDiagnostics::Quality quality;
};
//! Returns current state
PIDiagnostics::State state() const;
//! Returns period of full disconnect in seconds and period of averaging frequency //! Returns period of full disconnect in seconds and period of averaging frequency
float disconnectTimeout() const {return disconn_;} float disconnectTimeout() const {return disconn_;}
@@ -55,95 +78,95 @@ public:
void setDisconnectTimeout(float s) {setProperty("disconnectTimeout", s);} void setDisconnectTimeout(float s) {setProperty("disconnectTimeout", s);}
//! Returns immediate receive frequency, packets/s //! Returns immediate receive frequency, packets/s
float immediateFrequency() const {return immediate_freq;} float immediateFrequency() const {return cur_state.immediate_freq;}
//! Returns integral receive frequency for \a disconnectTimeout() seconds, packets/s //! Returns integral receive frequency for \a disconnectTimeout() seconds, packets/s
float integralFrequency() const {return integral_freq;} float integralFrequency() const {return cur_state.integral_freq;}
//! Returns correct received packets per second //! Returns correct received packets per second
ullong receiveCountPerSec() const {return packets_recv_sec;} ullong receiveCountPerSec() const {return cur_state.received_packets_per_sec;}
//! Returns sended packets per second //! Returns sended packets per second
ullong sendCountPerSec() const {return packets_send_sec;} ullong sendCountPerSec() const {return cur_state.sended_packets_per_sec;}
//! Returns correct received bytes per second //! Returns correct received bytes per second
ullong receiveBytesPerSec() const {return bytes_recv_sec;} ullong receiveBytesPerSec() const {return cur_state.received_bytes_per_sec;}
//! Returns sended bytes per second //! Returns sended bytes per second
ullong sendBytesPerSec() const {return bytes_send_sec;} ullong sendBytesPerSec() const {return cur_state.sended_bytes_per_sec;}
//! Returns overall correct received bytes //! Returns overall correct received bytes
ullong receiveBytes() const {return bytes_recv;} ullong receiveBytes() const {return cur_state.received_bytes;}
//! Returns overall wrong received bytes //! Returns overall wrong received bytes
ullong wrongBytes() const {return bytes_wrong;} ullong wrongBytes() const {return cur_state.received_bytes_wrong;}
//! Returns overall sended bytes //! Returns overall sended bytes
ullong sendBytes() const {return bytes_send;} ullong sendBytes() const {return cur_state.sended_bytes;}
//! Returns overall correct received packets count //! Returns overall correct received packets count
ullong receiveCount() const {return count_recv;} ullong receiveCount() const {return cur_state.received_packets;}
//! Returns overall wrong received packets count //! Returns overall wrong received packets count
ullong wrongCount() const {return count_wrong;} ullong wrongCount() const {return cur_state.received_packets_wrong;}
//! Returns overall sended packets count //! Returns overall sended packets count
ullong sendCount() const {return count_send;} ullong sendCount() const {return cur_state.sended_packets;}
//! Returns connection quality //! Returns connection quality
PIDiagnostics::Quality quality() const {return qual;} PIDiagnostics::Quality quality() const {return cur_state.quality;}
//! Returns receive speed in format "n {B|kB|MB|GB|TB}/s" //! Returns receive speed in format "n {B|kB|MB|GB|TB}/s"
PIString receiveSpeed() const {return speedRecv;} PIString receiveSpeed() const;
//! Returns send speed in format "n {B|kB|MB|GB|TB}/s" //! Returns send speed in format "n {B|kB|MB|GB|TB}/s"
PIString sendSpeed() const {return speedSend;} PIString sendSpeed() const;
//! Returns immediate receive frequency pointer, packets/s. Useful for output to PIConsole //! Returns immediate receive frequency pointer, packets/s. Useful for output to PIConsole
const float * immediateFrequency_ptr() const {return &immediate_freq;} const float * immediateFrequency_ptr() const {return &cur_state.immediate_freq;}
//! Returns integral receive frequency pointer for period, packets/s. Useful for output to PIConsole //! Returns integral receive frequency pointer for period, packets/s. Useful for output to PIConsole
const float * integralFrequency_ptr() const {return &integral_freq;} const float * integralFrequency_ptr() const {return &cur_state.integral_freq;}
//! Returns correct received packets per second pointer. Useful for output to PIConsole //! Returns correct received packets per second pointer. Useful for output to PIConsole
const ullong * receiveCountPerSec_ptr() const {return &packets_recv_sec;} const ullong * receiveCountPerSec_ptr() const {return &cur_state.received_packets_per_sec;}
//! Returns sended packets per second pointer. Useful for output to PIConsole //! Returns sended packets per second pointer. Useful for output to PIConsole
const ullong * sendCountPerSec_ptr() const {return &packets_send_sec;} const ullong * sendCountPerSec_ptr() const {return &cur_state.sended_packets_per_sec;}
//! Returns correct received bytes per second pointer. Useful for output to PIConsole //! Returns correct received bytes per second pointer. Useful for output to PIConsole
const ullong * receiveBytesPerSec_ptr() const {return &bytes_recv_sec;} const ullong * receiveBytesPerSec_ptr() const {return &cur_state.received_bytes_per_sec;}
//! Returns sended bytes per second pointer. Useful for output to PIConsole //! Returns sended bytes per second pointer. Useful for output to PIConsole
const ullong * sendBytesPerSec_ptr() const {return &bytes_send_sec;} const ullong * sendBytesPerSec_ptr() const {return &cur_state.sended_bytes_per_sec;}
//! Returns overall correct received bytes pointer. Useful for output to PIConsole //! Returns overall correct received bytes pointer. Useful for output to PIConsole
const ullong * receiveBytes_ptr() const {return &bytes_recv;} const ullong * receiveBytes_ptr() const {return &cur_state.received_bytes;}
//! Returns overall wrong received bytes pointer. Useful for output to PIConsole //! Returns overall wrong received bytes pointer. Useful for output to PIConsole
const ullong * wrongBytes_ptr() const {return &bytes_wrong;} const ullong * wrongBytes_ptr() const {return &cur_state.received_bytes_wrong;}
//! Returns overall sended bytes pointer. Useful for output to PIConsole //! Returns overall sended bytes pointer. Useful for output to PIConsole
const ullong * sendBytes_ptr() const {return &bytes_send;} const ullong * sendBytes_ptr() const {return &cur_state.sended_bytes;}
//! Returns overall correct received packets count pointer. Useful for output to PIConsole //! Returns overall correct received packets count pointer. Useful for output to PIConsole
const ullong * receiveCount_ptr() const {return &count_recv;} const ullong * receiveCount_ptr() const {return &cur_state.received_packets;}
//! Returns overall wrong received packets count pointer. Useful for output to PIConsole //! Returns overall wrong received packets count pointer. Useful for output to PIConsole
const ullong * wrongCount_ptr() const {return &count_wrong;} const ullong * wrongCount_ptr() const {return &cur_state.received_packets_wrong;}
//! Returns overall sended packets count pointer. Useful for output to PIConsole //! Returns overall sended packets count pointer. Useful for output to PIConsole
const ullong * sendCount_ptr() const {return &count_send;} const ullong * sendCount_ptr() const {return &cur_state.sended_packets;}
//! Returns connection quality pointer. Useful for output to PIConsole //! Returns connection quality pointer. Useful for output to PIConsole
const int * quality_ptr() const {return (int * )&qual;} const int * quality_ptr() const {return (int * )&cur_state.quality;}
//! Returns receive speed pointer in format "n {B|kB|MB|GB|TB}/s". Useful for output to PIConsole //! Returns receive speed pointer in format "n {B|kB|MB|GB|TB}/s". Useful for output to PIConsole
const PIString * receiveSpeed_ptr() const {return &speedRecv;} const PIString * receiveSpeed_ptr() const {return &cur_state.receive_speed;}
//! Returns send speed pointer in format "n {B|kB|MB|GB|TB}/s". Useful for output to PIConsole //! Returns send speed pointer in format "n {B|kB|MB|GB|TB}/s". Useful for output to PIConsole
const PIString * sendSpeed_ptr() const {return &speedSend;} const PIString * sendSpeed_ptr() const {return &cur_state.send_speed;}
EVENT_HANDLER0(void, start) {start(100.); changeDisconnectTimeout(disconn_);} EVENT_HANDLER0(void, start) {start(100.); changeDisconnectTimeout(disconn_);}
EVENT_HANDLER1(void, start, double, msecs) {if (msecs > 0.) {PITimer::start(msecs); changeDisconnectTimeout(disconn_);}} EVENT_HANDLER1(void, start, double, msecs) {if (msecs > 0.) {PITimer::start(msecs); changeDisconnectTimeout(disconn_);}}
@@ -194,14 +217,12 @@ private:
Entry calcHistory(PIQueue<Entry> & hist, int & cnt); Entry calcHistory(PIQueue<Entry> & hist, int & cnt);
void propertyChanged(const PIString &); void propertyChanged(const PIString &);
void changeDisconnectTimeout(float disct); void changeDisconnectTimeout(float disct);
void constLock() const;
void constUnlock() const;
PIDiagnostics::Quality qual;
PIString speedRecv, speedSend;
float immediate_freq, integral_freq;
PIQueue<Entry> history_rec, history_send; PIQueue<Entry> history_rec, history_send;
float disconn_; float disconn_;
ullong count_wrong, count_recv, count_send, bytes_wrong, bytes_recv, bytes_send; State cur_state;
ullong packets_recv_sec, packets_send_sec, bytes_recv_sec, bytes_send_sec;
}; };

View File

@@ -237,8 +237,8 @@ public:
EVENT_HANDLER(bool, open) {if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;} EVENT_HANDLER(bool, open) {if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
EVENT_HANDLER1(bool, open, const PIString &, _path) {setPath(_path); if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;} EVENT_HANDLER1(bool, open, const PIString &, _path) {setPath(_path); if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
bool open(const DeviceMode & _mode) {mode_ = _mode; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;} bool open(DeviceMode _mode) {mode_ = _mode; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
EVENT_HANDLER2(bool, open, const PIString &, _path, const DeviceMode &, _mode) {setPath(_path); mode_ = _mode; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;} EVENT_HANDLER2(bool, open, const PIString &, _path, DeviceMode, _mode) {setPath(_path); mode_ = _mode; if (!init_) init(); opened_ = openDevice(); if (opened_) opened(); return opened_;}
EVENT_HANDLER(bool, close) {opened_ = !closeDevice(); if (!opened_) closed(); return !opened_;} EVENT_HANDLER(bool, close) {opened_ = !closeDevice(); if (!opened_) closed(); return !opened_;}
EVENT_VHANDLER(void, flush) {;} EVENT_VHANDLER(void, flush) {;}
@@ -374,4 +374,5 @@ private:
}; };
#endif // PIIODEVICE_H #endif // PIIODEVICE_H

View File

@@ -69,7 +69,7 @@ public:
void setEnvironmentVariable(const PIString & variable, const PIString & value); void setEnvironmentVariable(const PIString & variable, const PIString & value);
EVENT_HANDLER1(void, exec, const PIString & , program) {args.clear(); args << program; exec_();} EVENT_HANDLER1(void, exec, const PIString & , program) {args.clear(); args << program; exec_();}
EVENT_HANDLER2(void, exec, const PIString & , program, const PIString & , arg) {args.clear(); args << program << arg; exec_();} void exec(const PIString & program, const PIString & arg) {args.clear(); args << program << arg; exec_();}
EVENT_HANDLER2(void, exec, const PIString & , program, const PIStringList & , args_) {args << program << args_; exec_();} EVENT_HANDLER2(void, exec, const PIString & , program, const PIStringList & , args_) {args << program << args_; exec_();}
EVENT_HANDLER(void, terminate); EVENT_HANDLER(void, terminate);
EVENT_HANDLER(bool, waitForFinish) {return waitForFinish(60000);} EVENT_HANDLER(bool, waitForFinish) {return waitForFinish(60000);}