PIVariant, PIGPIO

This commit is contained in:
2023-01-09 15:22:51 +03:00
parent f355cfc05e
commit 5c16953d95
3 changed files with 59 additions and 62 deletions

View File

@@ -18,6 +18,8 @@
*/
#include "pigpio.h"
#include "pitime.h"
#ifdef LINUX
# define GPIO_SYS_CLASS
#endif

View File

@@ -65,7 +65,10 @@
#ifdef CUSTOM_PIVARIANT
PIMap<uint, __PIVariantInfo__ *> * __PIVariantInfoStorage__::map = nullptr;
PIMap<uint, __PIVariantInfo__ *> & __PIVariantInfoStorage__::get() {
static PIMap<uint, __PIVariantInfo__ *> ret;
return ret;
}
#endif
@@ -176,7 +179,7 @@ void PIVariant::setValueFromString(const PIString & v) {
} break;
case PIVariant::pivCustom: {
#ifdef CUSTOM_PIVARIANT
__PIVariantInfo__ * vi = __PIVariantInfoStorage__::get()->map->value(__PIVariantFunctions__<PIString>::typeIDHelper());
__PIVariantInfo__ * vi = __PIVariantInfoStorage__::get().value(__PIVariantFunctions__<PIString>::typeIDHelper());
if (vi) {
__PIVariantInfo__::castHelperFunc cf = vi->cast.value(_typeID);
if (cf) {
@@ -297,7 +300,7 @@ PIVariant::Type PIVariant::typeFromID(uint type_id) {
if (type_id == typeID<PILined>()) return PIVariant::pivLine;
if (type_id == typeID<PINetworkAddress>()) return PIVariant::pivNetworkAddress;
#ifdef CUSTOM_PIVARIANT
if (__PIVariantInfoStorage__::get()->map->contains(type_id)) return PIVariant::pivCustom;
if (__PIVariantInfoStorage__::get().contains(type_id)) return PIVariant::pivCustom;
#endif
return PIVariant::pivInvalid;
}
@@ -377,7 +380,7 @@ PIVariant PIVariant::fromValue(const PIByteArray & c, uint type_id) {
PIVariant::Type t = typeFromID(type_id);
if (t == pivInvalid || t == pivCustom) {
#ifdef CUSTOM_PIVARIANT
ret._info = __PIVariantInfoStorage__::get()->map->value(type_id, 0);
ret._info = __PIVariantInfoStorage__::get().value(type_id, 0);
if (ret._info) {
t = pivCustom;
} else
@@ -399,7 +402,7 @@ PIVariant PIVariant::fromValue(const PIByteArray & c, const PIString & type) {
PIVariant::Type t = typeFromName(type);
if (t == pivInvalid) {
#ifdef CUSTOM_PIVARIANT
ret._info = __PIVariantInfoStorage__::get()->map->value(type.hash(), 0);
ret._info = __PIVariantInfoStorage__::get().value(type.hash(), 0);
if (ret._info) {
t = pivCustom;
} else
@@ -418,7 +421,7 @@ PIVariant PIVariant::fromValue(const PIByteArray & c, const PIString & type) {
PIVariant PIVariant::fromType(uint type_id) {
#ifdef CUSTOM_PIVARIANT
__PIVariantInfo__ * vi = __PIVariantInfoStorage__::get()->map->value(type_id);
__PIVariantInfo__ * vi = __PIVariantInfoStorage__::get().value(type_id);
if (!vi) return PIVariant();
return PIVariant::fromValue(vi->empty, type_id);
#else
@@ -471,7 +474,7 @@ PIString PIVariant::typeName(PIVariant::Type type) {
PIString PIVariant::typeNameFromID(uint type_id) {
#ifdef CUSTOM_PIVARIANT
__PIVariantInfo__ * vi = __PIVariantInfoStorage__::get()->map->value(type_id);
__PIVariantInfo__ * vi = __PIVariantInfoStorage__::get().value(type_id);
if (!vi) return PIString();
return vi->typeName;
#else
@@ -483,7 +486,7 @@ PIString PIVariant::typeNameFromID(uint type_id) {
PIVector<uint> PIVariant::knownTypeIDs() {
PIVector<uint> ret;
#ifdef CUSTOM_PIVARIANT
auto it = __PIVariantInfoStorage__::get()->map->makeIterator();
auto it = __PIVariantInfoStorage__::get().makeIterator();
while (it.next())
ret << it.key();
#endif
@@ -493,7 +496,7 @@ PIVector<uint> PIVariant::knownTypeIDs() {
int PIVariant::knownTypeIDsCount() {
#ifdef CUSTOM_PIVARIANT
return __PIVariantInfoStorage__::get()->map->size_s();
return __PIVariantInfoStorage__::get().size_s();
#endif
return 0;
}
@@ -1393,7 +1396,7 @@ PIString PIVariant::toString() const {
PIStringList r;
ba >> r;
if (r.isEmpty()) return PIString();
return r.join(";");
return r.join("%|%");
}
case PIVariant::pivEnum: {
PIVariantTypes::Enum r;

View File

@@ -120,36 +120,29 @@ struct __PIVariantTypeInfo__ {
class PIP_EXPORT __PIVariantInfoStorage__ {
public:
__PIVariantInfoStorage__() {
if (!map) map = new PIMap<uint, __PIVariantInfo__ *>();
}
static __PIVariantInfoStorage__ * get() {
static __PIVariantInfoStorage__ * r = new __PIVariantInfoStorage__();
return r;
}
static PIMap<uint, __PIVariantInfo__ *> * map;
static PIMap<uint, __PIVariantInfo__ *> & get();
};
# define REGISTER_VARIANT(classname) \
template<> \
inline PIString __PIVariantFunctions__<classname>::typeNameHelper() { \
static PIString tn = PIStringAscii(#classname); \
return tn; \
} \
template<> \
inline uint __PIVariantFunctions__<classname>::typeIDHelper() { \
static uint ret = PIStringAscii(#classname).hash(); \
return ret; \
} \
REGISTER_VARIANT_TYPEINFO(classname) \
STATIC_INITIALIZER_BEGIN \
uint type_id = __PIVariantFunctions__<classname>::typeIDHelper(); \
PIString type_name = __PIVariantFunctions__<classname>::typeNameHelper(); \
if (__PIVariantInfoStorage__::get()->map->contains(type_id)) return; \
PIByteArray empty; \
empty << classname(); \
(*(__PIVariantInfoStorage__::get()->map))[type_id] = new __PIVariantInfo__(type_name, empty); \
# define REGISTER_VARIANT(classname) \
template<> \
inline PIString __PIVariantFunctions__<classname>::typeNameHelper() { \
static PIString tn = PIStringAscii(#classname); \
return tn; \
} \
template<> \
inline uint __PIVariantFunctions__<classname>::typeIDHelper() { \
static uint ret = PIStringAscii(#classname).hash(); \
return ret; \
} \
REGISTER_VARIANT_TYPEINFO(classname) \
STATIC_INITIALIZER_BEGIN \
uint type_id = __PIVariantFunctions__<classname>::typeIDHelper(); \
PIString type_name = __PIVariantFunctions__<classname>::typeNameHelper(); \
if (__PIVariantInfoStorage__::get().contains(type_id)) return; \
PIByteArray empty; \
empty << classname(); \
__PIVariantInfoStorage__::get()[type_id] = new __PIVariantInfo__(type_name, empty); \
STATIC_INITIALIZER_END
@@ -158,30 +151,29 @@ public:
template<> \
inline classname_to __PIVariantFunctions__<classname_from>::castVariant<classname_to>(const classname_from & v);
# define REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) \
template<> \
template<> \
inline PIByteArray __PIVariantFunctions__<classname_from>::castHelper<classname_to>(PIByteArray v) { \
classname_from f; \
v >> f; \
classname_to t = __PIVariantFunctions__<classname_from>::castVariant<classname_to>(f); \
PIByteArray ret; \
ret << t; \
return ret; \
} \
STATIC_INITIALIZER_BEGIN \
__PIVariantInfo__ * vi( \
__PIVariantInfoStorage__::get()->map->value(__PIVariantFunctions__<classname_from>::typeIDHelper(), nullptr)); \
if (!vi) { \
piCout << "Warning! Using REGISTER_VARIANT_CAST(" #classname_from ", " #classname_to \
") before REGISTER_VARIANT(" #classname_from "), ignore."; \
return; \
} \
vi->cast[__PIVariantFunctions__<classname_to>::typeIDHelper()] = \
__PIVariantFunctions__<classname_from>::castHelper<classname_to>; \
STATIC_INITIALIZER_END \
template<> \
template<> \
# define REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) \
template<> \
template<> \
inline PIByteArray __PIVariantFunctions__<classname_from>::castHelper<classname_to>(PIByteArray v) { \
classname_from f; \
v >> f; \
classname_to t = __PIVariantFunctions__<classname_from>::castVariant<classname_to>(f); \
PIByteArray ret; \
ret << t; \
return ret; \
} \
STATIC_INITIALIZER_BEGIN \
__PIVariantInfo__ * vi(__PIVariantInfoStorage__::get().value(__PIVariantFunctions__<classname_from>::typeIDHelper(), nullptr)); \
if (!vi) { \
piCout << "Warning! Using REGISTER_VARIANT_CAST(" #classname_from ", " #classname_to \
") before REGISTER_VARIANT(" #classname_from "), ignore."; \
return; \
} \
vi->cast[__PIVariantFunctions__<classname_to>::typeIDHelper()] = \
__PIVariantFunctions__<classname_from>::castHelper<classname_to>; \
STATIC_INITIALIZER_END \
template<> \
template<> \
classname_to __PIVariantFunctions__<classname_from>::castVariant<classname_to>(const classname_from & v)
# define REGISTER_VARIANT_CAST(classname_from, classname_to) \
@@ -945,7 +937,7 @@ private:
#ifdef CUSTOM_PIVARIANT
_typeID = typeID<T>();
if (_type == pivCustom) {
_info = __PIVariantInfoStorage__::get()->map->value(_typeID, 0);
_info = __PIVariantInfoStorage__::get().value(_typeID, 0);
if (!_info) {
_type = pivInvalid;
piCout << "Can`t initialize PIVariant from unregistered type!";