This commit is contained in:
Andrey
2022-04-22 18:45:04 +03:00
6 changed files with 177 additions and 116 deletions

View File

@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
project(pip)
set(pip_MAJOR 2)
set(pip_MINOR 35)
set(pip_MINOR 36)
set(pip_REVISION 0)
set(pip_SUFFIX )
set(pip_COMPANY SHS)

View File

@@ -338,7 +338,7 @@ PICout PICout::operator <<(const PIFlags<PICoutManipulators::PICoutFormat> & v)
}
PICout PICout::operator <<(const char * v) {if (!act_) return *this; if (v[0] == '\0') return *this; space(); quote(); PICOUTTOTARGET(v) quote(); return *this;}
PICout PICout::operator <<(const char * v) {if (!act_ || !v) return *this; if (v[0] == '\0') return *this; space(); quote(); PICOUTTOTARGET(v) quote(); return *this;}
PICout PICout::operator <<(const bool v) {if (!act_) return *this; space(); if (v) PICOUTTOTARGET("true") else PICOUTTOTARGET("false") return *this;}

View File

@@ -110,22 +110,80 @@
//! \}
PIObject::__MetaFunc::__MetaFunc() {
for (int i = 0; i < __PIOBJECT_MAX_ARGS__; ++i) {
types[i] = names[i] = nullptr;
types_id[i] = 0;
}
}
int PIObject::__MetaFunc::argumentsCount() const {
for (int i = 0; i < __PIOBJECT_MAX_ARGS__; ++i)
if (!types[i])
return i;
return __PIOBJECT_MAX_ARGS__;
}
PIString PIObject::__MetaFunc::arguments() const {
return types.join(",");
PIString ret;
for (int i = 0; i < __PIOBJECT_MAX_ARGS__; ++i) {
if (!types[i]) break;
if (!ret.isEmpty()) ret += ',';
ret += PIStringAscii(types[i]);
}
return ret;
}
PIString PIObject::__MetaFunc::fullFormat() const {
PIString ret = type_ret + " " + scope + "::" + func_name +"(";
for (int i = 0; i < types.size_s(); ++i) {
PIString ret = PIStringAscii(type_ret) + " " +
PIStringAscii(scope) + "::" +
PIStringAscii(func_name) +"(";
for (int i = 0; i < __PIOBJECT_MAX_ARGS__; ++i) {
if (!types[i]) break;
if (i > 0) ret += ", ";
ret += types[i] + " " + names[i];
ret += PIStringAscii(types[i]) + " " + PIStringAscii(names[i]);
}
ret += ")";
return ret;
}
void PIObject::__MetaFunc::__setFuncName(const char * n) {
func_name = n;
func_name_id = PIStringAscii(n).hash();
}
void PIObject::__MetaFunc::__addArgument(const char * t, const char * n) {
for (int i = 0; i < __PIOBJECT_MAX_ARGS__; ++i) {
if (types[i]) continue;
types[i] = t;
names[i] = n;
types_id[i] = PIObject::simplifyType(t, false).hash();
break;
}
//PICout(PICoutManipulators::DefaultControls | PICoutManipulators::AddQuotes)
// << "__addArgument" << t << n << PIObject::simplifyType(t) << types_id.back();
}
bool PIObject::__MetaFunc::canConnectTo(const __MetaFunc & dst, int & args_count) const {
for (int i = 0; i < __PIOBJECT_MAX_ARGS__; ++i) {
//piCout << "canConnectTo" << i << types[i] << dst.types[i];
args_count = i;
if (!dst.types[i]) break;
if (!types[i]) return false;
if (types_id[i] != dst.types_id[i])
return false;
}
return true;
}
PIObject::PIObject(const PIString & name): _signature_(__PIOBJECT_SIGNATURE__), emitter_(0), thread_safe_(false), proc_event_queue(false) {
in_event_cnt = 0;
setName(name);
@@ -196,8 +254,13 @@ bool PIObject::executeQueued(PIObject * performer, const PIString & method, cons
PIStringList PIObject::scopeList() const {
PIStringList ret;
ret.reserve(2);
PIMutexLocker ml(__meta_mutex());
return __meta_data()[classNameID()].scope_list;
const PIVector<const char *> & scope(__meta_data()[classNameID()].scope_list);
for (const char * c: scope)
ret = PIStringAscii(c);
return ret;
}
@@ -212,10 +275,11 @@ PIStringList PIObject::methodsEH() const {
bool PIObject::isMethodEHContains(const PIString & name) const {
uint search_id = name.hash();
PIMutexLocker ml(__meta_mutex());
const __MetaData & ehd(__meta_data()[classNameID()]);
for (auto eh = ehd.eh_func.constBegin(); eh != ehd.eh_func.constEnd(); eh++) {
if (eh.value().func_name == name)
if (eh.value().func_name_id == search_id)
return true;
}
return false;
@@ -223,10 +287,11 @@ bool PIObject::isMethodEHContains(const PIString & name) const {
PIString PIObject::methodEHArguments(const PIString & name) const {
uint search_id = name.hash();
PIMutexLocker ml(__meta_mutex());
const __MetaData & ehd(__meta_data()[classNameID()]);
for (auto eh = ehd.eh_func.constBegin(); eh != ehd.eh_func.constEnd(); eh++) {
if (eh.value().func_name == name)
if (eh.value().func_name_id == search_id)
return eh.value().arguments();
}
return PIString();
@@ -234,10 +299,11 @@ PIString PIObject::methodEHArguments(const PIString & name) const {
PIString PIObject::methodEHFullFormat(const PIString & name) const {
uint search_id = name.hash();
PIMutexLocker ml(__meta_mutex());
const __MetaData & ehd(__meta_data()[classNameID()]);
for (auto eh = ehd.eh_func.constBegin(); eh != ehd.eh_func.constEnd(); eh++) {
if (eh.value().func_name == name)
if (eh.value().func_name_id == search_id)
return eh.value().fullFormat();
}
return PIString();
@@ -250,10 +316,11 @@ PIString PIObject::methodEHFromAddr(const void * addr) const {
PIVector<PIObject::__MetaFunc> PIObject::findEH(const PIString & name) const {
uint search_id = name.hash();
PIVector<__MetaFunc> ret;
const __MetaData & ehd(__meta_data()[classNameID()]);
for (auto eh = ehd.eh_func.constBegin(); eh != ehd.eh_func.constEnd(); eh++) {
if (eh.value().func_name == name)
if (eh.value().func_name_id == search_id)
ret << eh.value();
}
return ret;
@@ -313,10 +380,9 @@ PIObject::Connection PIObject::piConnectU(PIObject * src, const PIString & sig,
if (addr_src != 0) break;
piForeachC (__MetaFunc & fd, m_dest) {
if (addr_src != 0) break;
if (fs.arguments().startsWith(fd.arguments()) || fd.arguments().isEmpty()) {
if (fs.canConnectTo(fd, args)) {
addr_src = fs.addr;
addr_dest = que ? fd.addrV : fd.addr;
args = fd.names.size_s();
}
}
}
@@ -528,7 +594,7 @@ bool PIObject::findSuitableMethodV(const PIString & method, int args, int & ret_
int mfi = -1, ac = -1, mac = -1;
for (int i = 0; i < ml.size_s(); ++i) {
__MetaFunc & m(ml[i]);
int j = m.names.size_s();
int j = m.argumentsCount();
if (mac < 0 || mac > j) mac = j;
if ((j <= args) && (ac < j)) {
ac = j;
@@ -570,30 +636,46 @@ void PIObject::callAddrV(void * slot, void * obj, int args, const PIVector<PIVar
}
PIString PIObject::simplifyType(const char * a) {
PIString PIObject::simplifyType(const char * a, bool readable) {
PIString ret = PIStringAscii(a).trim();
int white = -1;
for (int i = 0; i < ret.size_s(); ++i) {
bool iw = ret[i] == ' ' || ret[i] == '\t' || ret[i] == '\r' || ret[i] == '\n';
//piCout << i << iw << white;
if (white < 0) {
if (iw) {
white = i;
continue;
}
} else {
if (!iw) {
ret.replace(white, i - white, " ");
i = white;
white = -1;
//piCout << i;
if (readable) {
int white = -1;
for (int i = 0; i < ret.size_s(); ++i) {
bool iw = ret[i] == ' ' || ret[i] == '\t' || ret[i] == '\r' || ret[i] == '\n';
//piCout << i << iw << white;
if (white < 0) {
if (iw) {
white = i;
continue;
}
} else {
if (!iw) {
ret.replace(white, i - white, " ");
i = white;
white = -1;
//piCout << i;
}
}
}
ret.replaceAll(" [", '[');
ret.replaceAll(" ]", ']');
ret.replaceAll(" <", '<');
ret.replaceAll(" >", '>');
ret.replaceAll(" &", '&');
ret.replaceAll(" *", '*');
ret.replaceAll("[ ", '[');
ret.replaceAll("] ", ']');
ret.replaceAll("< ", '<');
ret.replaceAll("> ", '>');
ret.replaceAll("& ", '&');
ret.replaceAll("* ", '*');
if (ret.startsWith("const ") && ret.endsWith("&"))
ret.cutLeft(6).cutRight(1).trim();
} else {
if (ret.startsWith("const ") && ret.endsWith("&"))
ret.cutLeft(6).cutRight(1).trim();
ret.removeAll(' ').removeAll('\t').removeAll('\r').removeAll('\n');
}
ret.replaceAll(" &", "&");
ret.replaceAll(" *", "*");
if (ret.startsWith("const ") && ret.endsWith("&"))
ret.cutLeft(6).cutRight(1).trim();
return ret;
}
@@ -632,13 +714,14 @@ void PIObject::dump(const PIString & line_prefix) const {
PIObject * dst = c.dest_o;
__MetaFunc ef = methodEH(c.signal);
PIString src(c.event);
if (!ef.func_name.isEmpty())
src = ef.func_name + "(" + ef.arguments() + ")";
if (ef.func_name)
src = PIStringAscii(ef.func_name) + "(" + ef.arguments() + ")";
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;
PIString hf_fn;
if (!hf.func_name) hf_fn = "[BROKEN]";
else hf_fn = PIStringAscii(hf.func_name) + "(" + hf.arguments() + ")";
PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << src << " -> " << dst->className() << " (" << c.dest << ", \"" << dst->name() << "\")::" << hf_fn;
} else {
PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << src << " -> " << "[lambda]";
}
@@ -693,7 +776,7 @@ bool dumpApplicationToFile(const PIString & path) {
#endif
void PIObject::__MetaData::addScope(const PIString & s, uint shash) {
void PIObject::__MetaData::addScope(const char * s, uint shash) {
if (!scope_id.contains(shash)) {
scope_list << s;
scope_id << shash;

View File

@@ -34,7 +34,6 @@
#include "piqueue.h"
#include "piobject_macros.h"
typedef void (*Handler)(void * );
class PIP_EXPORT PIObject {
@@ -123,6 +122,7 @@ public:
virtual uint classNameID() const {static uint ret = PIStringAscii("PIObject").hash(); return ret;}
static const PIString __classNameS() {return PIStringAscii("PIObject");}
static const char * __classNameCC() {return "PIObject";}
static uint __classNameIDS() {static uint ret = PIStringAscii("PIObject").hash(); return ret;}
//! \~english Returns parent class name
@@ -437,7 +437,8 @@ public:
template<typename T>
bool isTypeOf() const {
if (!isPIObject()) return false;
return scopeList().contains(T::__classNameS());
PIMutexLocker ml(__meta_mutex());
return __meta_data()[classNameID()].scope_id.contains(T::__classNameIDS());
}
//! \~english Returns cast to T if this is valid subclass "T" (check by \a isTypeOf()) or "nullptr"
@@ -459,26 +460,32 @@ public:
static bool isTypeOf(const PIObject * o) {return o->isTypeOf<T>();}
template<typename T>
static bool isTypeOf(const void * o) {return isTypeOf<T>((PIObject*)o);}
static PIString simplifyType(const char * a);
static PIString simplifyType(const char * a, bool readable = true);
struct PIP_EXPORT __MetaFunc {
__MetaFunc(): addr(0), addrV(0) {;}
bool isNull() const {return addr == 0;}
__MetaFunc();
bool isNull() const {return addr == nullptr;}
int argumentsCount() const;
PIString arguments() const;
PIString fullFormat() const;
void * addr;
void * addrV;
PIString func_name;
PIString type_ret;
PIString scope;
PIStringList types;
PIStringList names;
void __setFuncName(const char * n);
void __addArgument(const char * t, const char * n);
bool canConnectTo(const __MetaFunc & dst, int & args_count) const;
void * addr = nullptr;
void * addrV = nullptr;
uint func_name_id = 0;
const char * func_name = nullptr;
const char * type_ret = nullptr;
const char * scope = nullptr;
const char * types[__PIOBJECT_MAX_ARGS__];
const char * names[__PIOBJECT_MAX_ARGS__];
uint types_id[__PIOBJECT_MAX_ARGS__];
};
struct PIP_EXPORT __MetaData {
__MetaData() {scope_list << PIStringAscii("PIObject"); scope_id << PIStringAscii("PIObject").hash();}
void addScope(const PIString & s, uint shash);
PIStringList scope_list;
__MetaData() {scope_list << "PIObject"; scope_id << PIStringAscii("PIObject").hash();}
void addScope(const char * s, uint shash);
PIVector<const char *> scope_list;
PISet<uint> scope_id;
PISet<const void * > eh_set;
PIMap<const void * , __MetaFunc> eh_func;

View File

@@ -385,6 +385,7 @@
# define __PTYPE(t) __PIVariantTypeInfo__<t>::PureType
#endif
#define __VVALUE(t, v) v.value< __PTYPE(t) >()
#define __PIOBJECT_MAX_ARGS__ 4
#define PIOBJECT(name) \
@@ -392,6 +393,7 @@
typedef name __PIObject__; \
public: \
static const PIString __classNameS() {static PIString ret = PIStringAscii(#name); return ret;} \
static const char * __classNameCC() {return #name;} \
static uint __classNameIDS() {static uint ret = PIStringAscii(#name).hash(); return ret;} \
virtual const char * className() const {return #name;} \
virtual uint classNameID() const {static uint ret = PIStringAscii(#name).hash(); return ret;} \
@@ -411,7 +413,7 @@
__MetaData & eh(__meta_data()[id]); \
eh.eh_set << ehp.eh_set; \
eh.eh_func << ehp.eh_func; \
eh.addScope(__classNameS(), id); \
eh.addScope(__classNameCC(), id); \
} \
}; \
__BaseInitializer__ __base_init__;
@@ -431,7 +433,7 @@
eh.eh_func << ehp.eh_func; \
eh.scope_id = ehp.scope_id; \
eh.scope_list = ehp.scope_list; \
eh.addScope(__classNameS(), id); \
eh.addScope(__classNameCC(), id); \
} \
}; \
__ParentInitializer__ __parent_init__; \
@@ -443,92 +445,61 @@
#define PIOBJECT_SUBCLASS(name, parent) PIOBJECT(name) PIOBJECT_PARENT(parent)
#define __EH_INIT_BASE__(ret, name) \
PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameIDS()]); \
if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \
__MetaFunc & f(eh.eh_func[fp]); \
f.scope = __classNameCC(); \
f.__setFuncName(#name); \
f.addr = fp; \
f.addrV = fpV; \
f.type_ret = #ret;
#define EH_INIT0(ret, name) \
STATIC_INITIALIZER_BEGIN \
PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameIDS()]); \
void * fp = (void*)(ret(*)(void*))__stat_eh_##name##__; \
void * fpV = fp; \
if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \
__MetaFunc & f(eh.eh_func[fp]); \
f.scope = __classNameS(); \
f.func_name = PIStringAscii(#name); \
f.addr = fp; \
f.addrV = fpV; \
f.type_ret = PIStringAscii(#ret); \
__EH_INIT_BASE__(ret, name) \
STATIC_INITIALIZER_END
#define EH_INIT1(ret, name, a0, n0) \
STATIC_INITIALIZER_BEGIN \
PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameIDS()]); \
void * fp = (void*)(ret(*)(void*, a0))__stat_eh_##name##__; \
void * fpV = (void*)(ret(*)(void*, const PIVariantSimple &))__stat_eh_v_##name##__; \
if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \
__MetaFunc & f(eh.eh_func[fp]); \
f.scope = __classNameS(); \
f.func_name = PIStringAscii(#name); \
f.addr = fp; \
f.addrV = fpV; \
f.type_ret = PIStringAscii(#ret); \
f.types << PIObject::simplifyType(#a0); \
f.names << PIStringAscii(#n0); \
__EH_INIT_BASE__(ret, name) \
f.__addArgument(#a0, #n0); \
STATIC_INITIALIZER_END
#define EH_INIT2(ret, name, a0, n0, a1, n1) \
STATIC_INITIALIZER_BEGIN \
PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameIDS()]); \
void * fp = (void*)(ret(*)(void*, a0, a1))__stat_eh_##name##__; \
void * fpV = (void*)(ret(*)(void*, const PIVariantSimple &, const PIVariantSimple &))__stat_eh_v_##name##__; \
if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \
__MetaFunc & f(eh.eh_func[fp]); \
f.scope = __classNameS(); \
f.func_name = PIStringAscii(#name); \
f.addr = fp; \
f.addrV = fpV; \
f.type_ret = PIStringAscii(#ret); \
f.types << PIObject::simplifyType(#a0) << PIObject::simplifyType(#a1); \
f.names << PIStringAscii(#n0) << PIStringAscii(#n1); \
__EH_INIT_BASE__(ret, name) \
f.__addArgument(#a0, #n0); \
f.__addArgument(#a1, #n1); \
STATIC_INITIALIZER_END
#define EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \
STATIC_INITIALIZER_BEGIN \
PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameIDS()]); \
void * fp = (void*)(ret(*)(void*, a0, a1, a2))__stat_eh_##name##__; \
void * fpV = (void*)(ret(*)(void*, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &))__stat_eh_v_##name##__; \
if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \
__MetaFunc & f(eh.eh_func[fp]); \
f.scope = __classNameS(); \
f.func_name = PIStringAscii(#name); \
f.addr = fp; \
f.addrV = fpV; \
f.type_ret = PIStringAscii(#ret); \
f.types << PIObject::simplifyType(#a0) << PIObject::simplifyType(#a1) << PIObject::simplifyType(#a2); \
f.names << PIStringAscii(#n0) << PIStringAscii(#n1) << PIStringAscii(#n2); \
__EH_INIT_BASE__(ret, name) \
f.__addArgument(#a0, #n0); \
f.__addArgument(#a1, #n1); \
f.__addArgument(#a2, #n2); \
STATIC_INITIALIZER_END
#define EH_INIT4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \
STATIC_INITIALIZER_BEGIN \
PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameIDS()]); \
void * fp = (void*)(ret(*)(void*, a0, a1, a2, a3))__stat_eh_##name##__; \
void * fpV = (void*)(ret(*)(void*, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &))__stat_eh_v_##name##__; \
if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \
__MetaFunc & f(eh.eh_func[fp]); \
f.scope = __classNameS(); \
f.func_name = PIStringAscii(#name); \
f.addr = fp; \
f.addrV = fpV; \
f.type_ret = PIStringAscii(#ret); \
f.types << PIObject::simplifyType(#a0) << PIObject::simplifyType(#a1) << PIObject::simplifyType(#a2) << PIObject::simplifyType(#a3); \
f.names << PIStringAscii(#n0) << PIStringAscii(#n1) << PIStringAscii(#n2) << PIStringAscii(#n3); \
__EH_INIT_BASE__(ret, name) \
f.__addArgument(#a0, #n0); \
f.__addArgument(#a1, #n1); \
f.__addArgument(#a2, #n2); \
f.__addArgument(#a3, #n3); \
STATIC_INITIALIZER_END

View File

@@ -376,7 +376,7 @@ TEST(PIMathMatrixT_Test, invert) {
d2 = matrix2.determinant();
matrix3 = matrix1;
matrix1.invert();
ASSERT_TRUE((matrix1 == matrix3) && (d1 == 1/d2));
ASSERT_TRUE((matrix1 == matrix3) && piCompare(d1, 1/d2));
}
TEST(PIMathMatrixT_Test, inverted) {