|
|
|
|
@@ -1,114 +1,259 @@
|
|
|
|
|
#include "pip.h"
|
|
|
|
|
/*#ifdef PIP_LUA
|
|
|
|
|
#include "piluaprogram.h"
|
|
|
|
|
|
|
|
|
|
static const char * script
|
|
|
|
|
= "-- script.lua \n"
|
|
|
|
|
"test()\n"
|
|
|
|
|
"testString = \"LuaBridge works ававава!\" \n"
|
|
|
|
|
"number = 42 \n";
|
|
|
|
|
PIMap<PIString, ullong> results;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void test() {
|
|
|
|
|
piCout << "C function test";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
PILuaProgram p;
|
|
|
|
|
p.getGlobalNamespace().addFunction("test", test);
|
|
|
|
|
if (!p.load(PIString::fromUTF8(script))) piCout << "error";
|
|
|
|
|
p.prepare();
|
|
|
|
|
luabridge::LuaRef s = p.getGlobal("testString");
|
|
|
|
|
luabridge::LuaRef n = p.getGlobal("number");
|
|
|
|
|
PIString luaString = s.cast<PIString>();
|
|
|
|
|
int answer = n.cast<int>();
|
|
|
|
|
piCout << luaString;
|
|
|
|
|
piCout << "And here's our number:" << answer;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
int main() {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
*/
|
|
|
|
|
class db {
|
|
|
|
|
public:
|
|
|
|
|
db() {
|
|
|
|
|
name = PIStringAscii("sflner;ljner.vjnrevsg;j35m4;gberjg2mnv");
|
|
|
|
|
for (int i=0; i<10000; ++i)
|
|
|
|
|
x << sin(double(i)/180.0);
|
|
|
|
|
//printf("jkfkhg\n");
|
|
|
|
|
}
|
|
|
|
|
PIString name;
|
|
|
|
|
PIVector<double> x;
|
|
|
|
|
template<typename T>
|
|
|
|
|
struct __VariantTypeInfo__ {
|
|
|
|
|
typedef T PureType;
|
|
|
|
|
typedef const T ConstPureType;
|
|
|
|
|
typedef T * PointerType;
|
|
|
|
|
typedef const T * ConstPointerType;
|
|
|
|
|
typedef T & ReferenceType;
|
|
|
|
|
typedef const T & ConstReferenceType;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
inline PIByteArray & operator <<(PIByteArray & ba, const db & v) {
|
|
|
|
|
PIChunkStream cs;
|
|
|
|
|
cs.add(1, v.name).add(2, v.x);
|
|
|
|
|
ba << cs.data();
|
|
|
|
|
return ba;
|
|
|
|
|
#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 &)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class __VariantFunctionsBase__ {
|
|
|
|
|
public:
|
|
|
|
|
virtual __VariantFunctionsBase__ * instance() {return 0;}
|
|
|
|
|
virtual PIString typeName() const {return PIString();}
|
|
|
|
|
virtual uint hash() const {return 0;}
|
|
|
|
|
virtual void newT(void *& ptr, const void * value) {;}
|
|
|
|
|
virtual void newNullT(void *& ptr) {;}
|
|
|
|
|
virtual void equalT(void *& ptr, const void * value) {;}
|
|
|
|
|
virtual void deleteT(void *& ptr) {;}
|
|
|
|
|
virtual PIByteArray toData(const void * ptr) const {return PIByteArray();}
|
|
|
|
|
virtual void fromData(void *& ptr, PIByteArray ba) {;}
|
|
|
|
|
//template<typename C> static PIByteArray castHelper(PIByteArray ba) {return PIByteArray();}
|
|
|
|
|
//template<typename C> static C castVariant(const T & v) {return C();}
|
|
|
|
|
static PIMap<uint, __VariantFunctionsBase__*> & registered() {static PIMap<uint, __VariantFunctionsBase__*> ret; return ret;}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
class __VariantFunctions__: public __VariantFunctionsBase__ {
|
|
|
|
|
public:
|
|
|
|
|
__VariantFunctionsBase__ * instance() override {static __VariantFunctions__<T> ret; return &ret;}
|
|
|
|
|
PIString typeName() const override {return PIString();}
|
|
|
|
|
uint hash() const override {static uint ret = typeName().hash(); return ret;}
|
|
|
|
|
void newT(void *& ptr, const void * value) override {ptr = (void*)(new T(*(const T*)value)); printf(" * new\n");}
|
|
|
|
|
void newNullT(void *& ptr) override {ptr = (void*)(new T()); printf(" * new null\n");}
|
|
|
|
|
void equalT(void *& ptr, const void * value) override {*(T*)ptr = *(const T*)value; printf(" * =\n");}
|
|
|
|
|
void deleteT(void *& ptr) override {delete (T*)(ptr); printf(" * del\n");}
|
|
|
|
|
PIByteArray toData(const void * ptr) const override {PIByteArray ret; ret << (*(const T* &)ptr); return ret;}
|
|
|
|
|
void fromData(void *& ptr, PIByteArray ba) override {ba >> *(T*)ptr;}
|
|
|
|
|
|
|
|
|
|
template<typename C> static PIByteArray castHelper(PIByteArray ba) {return PIByteArray();}
|
|
|
|
|
template<typename C> static C castVariant(const T & v) {return C();}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class Variant {
|
|
|
|
|
public:
|
|
|
|
|
Variant() {ptr = 0; f = 0;}
|
|
|
|
|
Variant(const Variant & v) {
|
|
|
|
|
ptr = 0;
|
|
|
|
|
f = v.f;
|
|
|
|
|
if (f && v.ptr)
|
|
|
|
|
f->newT(ptr, v.ptr);
|
|
|
|
|
}
|
|
|
|
|
inline PIByteArray & operator >>(PIByteArray & ba, db & v) {
|
|
|
|
|
PIByteArray src; ba >> src; PIChunkStream cs(src);
|
|
|
|
|
while (!cs.atEnd()) {
|
|
|
|
|
switch (cs.read()) {
|
|
|
|
|
case 1: cs.get(v.name); break;
|
|
|
|
|
case 2: cs.get(v.x); break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ba;
|
|
|
|
|
~Variant() {destroy();}
|
|
|
|
|
|
|
|
|
|
Variant & operator=(const Variant & v) {
|
|
|
|
|
destroy();
|
|
|
|
|
f = v.f;
|
|
|
|
|
if (f && v.ptr)
|
|
|
|
|
f->newT(ptr, v.ptr);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PIEthernet eth;
|
|
|
|
|
template <typename T>
|
|
|
|
|
void setValue(const T & v) {
|
|
|
|
|
if (f) {
|
|
|
|
|
if (isMyType<T>()) {
|
|
|
|
|
f->equalT(ptr, (const void *)&v);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
destroy();
|
|
|
|
|
f = __VariantFunctions__<T>().instance();
|
|
|
|
|
f->newT(ptr, (const void *)&v);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
T value() const {
|
|
|
|
|
if (!f) return T();
|
|
|
|
|
if (!isMyType<T>())
|
|
|
|
|
return T();
|
|
|
|
|
return *(T*)(ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PIByteArray save() const {
|
|
|
|
|
if (!ptr || !f) return PIByteArray();
|
|
|
|
|
PIByteArray ret;
|
|
|
|
|
ret << f->hash();
|
|
|
|
|
ret.append(f->toData(ptr));
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool load(PIByteArray ba) {
|
|
|
|
|
if (ba.size_s() < 4) return false;
|
|
|
|
|
uint h(0); ba >> h;
|
|
|
|
|
destroy();
|
|
|
|
|
f = __VariantFunctionsBase__::registered().value(h, 0);
|
|
|
|
|
if (!f) return false;
|
|
|
|
|
f->newNullT(ptr);
|
|
|
|
|
f->fromData(ptr, ba);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//private:
|
|
|
|
|
template <typename T>
|
|
|
|
|
bool isMyType() const {return f->hash() == __VariantFunctions__<T>().instance()->hash();}
|
|
|
|
|
|
|
|
|
|
void destroy() {
|
|
|
|
|
if (ptr && f)
|
|
|
|
|
f->deleteT(ptr);
|
|
|
|
|
ptr = 0;
|
|
|
|
|
f = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void * ptr;
|
|
|
|
|
__VariantFunctionsBase__ * f;
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int Acnt = 0;
|
|
|
|
|
|
|
|
|
|
class A {
|
|
|
|
|
public:
|
|
|
|
|
A() {i = "constructor"; /*piCout << "A()";*/ ++Acnt;}
|
|
|
|
|
A(const A & a): i(a.i) {/*piCout << "copy A()";*/ ++Acnt;}
|
|
|
|
|
~A() {/*piCout << "~A()";*/ --Acnt;}
|
|
|
|
|
A & operator =(const A & a) {i = a.i; /*piCout << "= A()";*/ return *this;}
|
|
|
|
|
PIString i;
|
|
|
|
|
};
|
|
|
|
|
PIByteArray & operator <<(PIByteArray & ba, const A & v) {ba << v.i; return ba;}
|
|
|
|
|
PIByteArray & operator >>(PIByteArray & ba, A & v) {ba >> v.i; return ba;}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <>
|
|
|
|
|
PIString __VariantFunctions__<int>::typeName() const {static PIString ret("int"); return ret;}
|
|
|
|
|
class _VariantRegistrator_int__ {
|
|
|
|
|
public:
|
|
|
|
|
_VariantRegistrator_int__() {
|
|
|
|
|
__VariantFunctionsBase__ * f = __VariantFunctions__<int>().instance();
|
|
|
|
|
__VariantFunctionsBase__::registered()[f->hash()] = f;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
_VariantRegistrator_int__ __reg_int__;
|
|
|
|
|
|
|
|
|
|
template <>
|
|
|
|
|
PIString __VariantFunctions__<A>::typeName() const {static PIString ret("A"); return ret;}
|
|
|
|
|
class _VariantRegistrator_A__ {
|
|
|
|
|
public:
|
|
|
|
|
_VariantRegistrator_A__() {
|
|
|
|
|
__VariantFunctionsBase__ * f = __VariantFunctions__<A>().instance();
|
|
|
|
|
__VariantFunctionsBase__::registered()[f->hash()] = f;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
_VariantRegistrator_A__ __reg_A__;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "picodeparser.h"
|
|
|
|
|
int main() {
|
|
|
|
|
//PICodeParser cp;
|
|
|
|
|
//cp.parseFile("SH_plugin_base.h");
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
PIMap<int, PIString> m;
|
|
|
|
|
m[1] = "one";
|
|
|
|
|
m[2] = "two";
|
|
|
|
|
Variant v, v2;
|
|
|
|
|
|
|
|
|
|
auto it = m.makeIterator();
|
|
|
|
|
while (it.next()) {
|
|
|
|
|
//it.next();
|
|
|
|
|
it.valueRef() << "_!";
|
|
|
|
|
piCout << it.key() << it.value();
|
|
|
|
|
/*{
|
|
|
|
|
A a, ra;
|
|
|
|
|
|
|
|
|
|
a.i = "main";
|
|
|
|
|
v.setValue(a);
|
|
|
|
|
|
|
|
|
|
ra = v.value<A>();
|
|
|
|
|
piCout << " 1 A.i =" << ra.i;
|
|
|
|
|
|
|
|
|
|
a.i = "main second";
|
|
|
|
|
v.setValue(a);
|
|
|
|
|
|
|
|
|
|
ra = v.value<A>();
|
|
|
|
|
piCout << " 2 A.i =" << ra.i;
|
|
|
|
|
|
|
|
|
|
piCout << "Acnt" << Acnt;
|
|
|
|
|
}
|
|
|
|
|
piCout << "Acnt" << Acnt;
|
|
|
|
|
|
|
|
|
|
v2 = v;
|
|
|
|
|
PIString ra = v2.value<PIString>();
|
|
|
|
|
piCout << " 3 A.i =" << ra;*/
|
|
|
|
|
|
|
|
|
|
A a, ra;
|
|
|
|
|
|
|
|
|
|
a.i = "main";
|
|
|
|
|
v.setValue(a);
|
|
|
|
|
PIByteArray ba = v.save();
|
|
|
|
|
|
|
|
|
|
piCout << v2.load(ba);
|
|
|
|
|
piCout << v2.value<A>().i;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
piCout << "Acnt" << Acnt;
|
|
|
|
|
//__VariantFunctionsBase__ * f = __VariantFunctions__<void*>().instance();
|
|
|
|
|
//piCout << f->typeName();
|
|
|
|
|
//f = __VariantFunctions__<int>().instance();
|
|
|
|
|
//piCout << f->typeName();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*eth.__meta_data
|
|
|
|
|
piForeachC (auto & i, cp.enums) {
|
|
|
|
|
i.
|
|
|
|
|
}*/
|
|
|
|
|
/*
|
|
|
|
|
template <typename T>
|
|
|
|
|
void test_var(const char * Tname) {
|
|
|
|
|
piCout << Tname << "...";
|
|
|
|
|
ullong cnt = 0;
|
|
|
|
|
PIVariant _v;
|
|
|
|
|
PITimeMeasurer tm1s;
|
|
|
|
|
while (tm1s.elapsed_m() < 500.) {
|
|
|
|
|
++cnt;
|
|
|
|
|
for (int j = 0; j < 1000; ++j) {
|
|
|
|
|
PIVariant v;
|
|
|
|
|
v = T();
|
|
|
|
|
v.setValue(T(j));
|
|
|
|
|
_v = v;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
PIVariant v;
|
|
|
|
|
results[Tname] = cnt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*piDebug = false;
|
|
|
|
|
double min = -1, max = -1, mean = 0;
|
|
|
|
|
const int iterations = 50;
|
|
|
|
|
db d, d2;
|
|
|
|
|
for (int i = 0; i < iterations; ++i) {
|
|
|
|
|
//PICodeParser cp;
|
|
|
|
|
PITimeMeasurer tm;
|
|
|
|
|
for (int j = 0; j < 100; ++j) {
|
|
|
|
|
PIByteArray ba;
|
|
|
|
|
ba << d;
|
|
|
|
|
}
|
|
|
|
|
//cp.parseFile("SH_plugin_base.h");
|
|
|
|
|
double ms = tm.elapsed_m();
|
|
|
|
|
if (min < 0) min = ms;
|
|
|
|
|
if (max < 0) max = ms;
|
|
|
|
|
min = piMin(min, ms);
|
|
|
|
|
max = piMax(max, ms);
|
|
|
|
|
mean += ms;
|
|
|
|
|
#define TEST_VAR(T) test_var<T>(#T)
|
|
|
|
|
|
|
|
|
|
PIByteArray ba;
|
|
|
|
|
ba << d;
|
|
|
|
|
d2.name.clear();
|
|
|
|
|
d2.x.clear();
|
|
|
|
|
ba >> d2;
|
|
|
|
|
}
|
|
|
|
|
piDebug = true;
|
|
|
|
|
piCout << d2.name << d2.x.size_s();
|
|
|
|
|
piCout << min << (mean / iterations) << max;*/
|
|
|
|
|
int main() {
|
|
|
|
|
TEST_VAR(int);
|
|
|
|
|
TEST_VAR(float);
|
|
|
|
|
TEST_VAR(ullong);
|
|
|
|
|
TEST_VAR(PIString);
|
|
|
|
|
int sz = 0;
|
|
|
|
|
auto i = results.makeIterator();
|
|
|
|
|
while (i.next()) sz = piMaxi(sz, i.key().length());
|
|
|
|
|
i.reset();
|
|
|
|
|
while (i.next())
|
|
|
|
|
piCout << i.key().expandedLeftTo(sz, ' ') << ":" << i.value();
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|