diff --git a/libs/main/core/pibase.h b/libs/main/core/pibase.h index d015620e..bd720e26 100644 --- a/libs/main/core/pibase.h +++ b/libs/main/core/pibase.h @@ -367,9 +367,9 @@ name& operator=(const name&) = delete; -#define _PIP_ADD_COUNTER_WS(a, cnt) a##cnt -#define _PIP_ADD_COUNTER_WF(a, cnt) _PIP_ADD_COUNTER_WS(a, cnt) -#define _PIP_ADD_COUNTER(a) _PIP_ADD_COUNTER_WF(a, __COUNTER__) +#define _PIP_ADD_COUNTER_WS(a, cnt, line) a##cnt##_##line +#define _PIP_ADD_COUNTER_WF(a, cnt, line) _PIP_ADD_COUNTER_WS(a, cnt, line) +#define _PIP_ADD_COUNTER(a) _PIP_ADD_COUNTER_WF(a, __COUNTER__, __LINE__) #define STATIC_INITIALIZER_BEGIN \ diff --git a/libs/main/types/pitypesmodule.h b/libs/main/types/pitypesmodule.h index 66ccf775..73febe31 100644 --- a/libs/main/types/pitypesmodule.h +++ b/libs/main/types/pitypesmodule.h @@ -57,5 +57,6 @@ #include "pitime.h" #include "pipropertystorage.h" #include "pivariantsimple.h" +#include "pivaluetree.h" #endif // PITYPESMODULE_H diff --git a/libs/main/types/pivaluetree.cpp b/libs/main/types/pivaluetree.cpp new file mode 100644 index 00000000..c1b2dbc1 --- /dev/null +++ b/libs/main/types/pivaluetree.cpp @@ -0,0 +1,125 @@ +/* + PIP - Platform Independent Primitives + Attributed values tree + Ivan Pelipenko peri4ko@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#include "pivaluetree.h" + + +//! \class PIValueTree pivaluetree.h +//! \details +//! \~english \section PIValueTree_sec0 Synopsis +//! \~russian \section PIValueTree_sec0 Краткий обзор +//! \~english +//! +//! \~russian +//! + + + +PIValueTree::PIValueTree() { +} + + +PIValueTree::PIValueTree(const PIVariant & v) { + setValue(v); +} + + +PIValueTree::PIValueTree(const PIString & n, const PIVariant & v) { + setName(n); + setValue(v); +} + + +void PIValueTree::setName(const PIString & n) { + if (_is_null) return; + _name = n; +} + + +void PIValueTree::setComment(const PIString & c) { + if (_is_null) return; + _comment = c; +} + + +void PIValueTree::setValue(const PIVariant & v) { + if (_is_null) return; + _value = v; +} + + +bool PIValueTree::contains(const PIString & name) const { + if (_is_null) return true; + for (const auto & c: _children) + if (c.name() == name) + return true; + return false; +} + + +PIValueTree PIValueTree::child(const PIString & name) const { + if (_is_null) return PIValueTree(); + for (const auto & c: _children) + if (c.name() == name) + return c; + return PIValueTree(); +} + + +PIValueTree & PIValueTree::child(const PIString & name) { + if (_is_null) return nullValue(); + for (auto & c: _children) + if (c.name() == name) + return c; + return nullValue(); +} + + +PIValueTree & PIValueTree::addChild(const PIValueTree & n) { + if (_is_null) return nullValue(); + for (auto & c: _children) + if (c.name() == n.name()) { + c = n; + return *this; + } + _children << n; + return *this; +} + + +PIValueTree & PIValueTree::addChildren(const PIVector & n) { + if (_is_null) return nullValue(); + for (const auto & c: n) + addChild(c); + return *this; +} + + +PIValueTree & PIValueTree::remove(const PIString & name) { + if (_is_null) return nullValue(); + _children.removeWhere([name](const PIValueTree & i){return i.name() == name;}); + return *this; +} + + +PIValueTree & PIValueTree::nullValue() { + static PIValueTree ret; + ret._is_null = true; + return ret; +} diff --git a/libs/main/types/pivaluetree.h b/libs/main/types/pivaluetree.h new file mode 100644 index 00000000..a4385594 --- /dev/null +++ b/libs/main/types/pivaluetree.h @@ -0,0 +1,148 @@ +/*! \file pivaluetree.h + * \ingroup Types + * \brief + * \~english Attributed values tree + * \~russian Дерево атрибутированных значений +*/ +/* + PIP - Platform Independent Primitives + Attributed values tree + Ivan Pelipenko peri4ko@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#ifndef PIVALUETREE_H +#define PIVALUETREE_H + +#include "pivariant.h" +#include "pichunkstream.h" + + +class PIP_EXPORT PIValueTree { + BINARY_STREAM_FRIEND(PIValueTree); +public: + PIValueTree(); + PIValueTree(const PIVariant & v); + PIValueTree(const PIString & n, const PIVariant & v); + + enum FlagsRole { + Standard, + Custom, + FlagsRoleCount + }; + + enum FlagStandard { + Hidden = 0x01, + Editable = 0x02, + Label = 0x04, + ArrayReorder = 0x1001, + ArrayResize = 0x1002, + }; + + static constexpr char attributeArrayType [] = "arrayType" ; + static constexpr char attributeArrayMinCount[] = "arrayMinCount"; + static constexpr char attributeArrayMaxCount[] = "arrayMaxCount"; + + static constexpr char attributeMinimum [] = "minimum" ; + static constexpr char attributeMaximum [] = "maximum" ; + static constexpr char attributeSingleStep [] = "singleStep" ; + static constexpr char attributeDecimals [] = "decimals" ; + static constexpr char attributePrefix [] = "prefix" ; + static constexpr char attributeSuffix [] = "suffix" ; + //static constexpr char attribute[] = ""; + + bool isNull() const {return _is_null;} + bool isValid() const {return _value.isValid();} + + const PIString & name() const {return _name;} + void setName(const PIString & n); + + const PIString & comment() const {return _comment;} + void setComment(const PIString & c); + + const PIVariant & value() const {return _value;} + void setValue(const PIVariant & v); + + const PIVariantMap & attributes() const {return _attributes;} + PIVariantMap & attributes() {return _attributes;} + + PIFlags flagsStandard() {return _flags[Standard];} + uint flags(FlagsRole role) {return _flags[role];} + + const PIVector & children() const {return _children;} + + bool contains(const PIString & name) const; + PIValueTree child(const PIString & name) const; + PIValueTree & child(const PIString & name); + PIValueTree & addChild(const PIValueTree & n); + PIValueTree & addChildren(const PIVector & n); + PIValueTree & remove(const PIString & name); + +private: + static PIValueTree & nullValue(); + + PIString _name; + PIString _comment; + PIVariantMap _attributes; + PIVariant _value; + PIVector _children; + uint _flags[FlagsRoleCount] = {Editable, 0}; + bool _is_null = false; + +}; + + +//! \relatesalso PIBinaryStream +//! \~english Store operator. +//! \~russian Оператор сохранения. +BINARY_STREAM_WRITE(PIValueTree) { + PIChunkStream cs; + cs.add(1, v._name) + .add(2, v._comment) + .add(3, v._attributes) + .add(4, v._value) + .add(5, v._name) + .add(6, v._children); + for (int i = 0; i < PIValueTree::FlagsRoleCount; ++i) + cs.add(100 + i, v._flags[i]); + s << cs.data(); + return s; +} + +//! \relatesalso PIBinaryStream +//! \~english Restore operator. +//! \~russian Оператор извлечения. +BINARY_STREAM_READ (PIValueTree) { + PIByteArray csba; s >> csba; + PIChunkStream cs(csba); + while (!cs.atEnd()) { + switch (cs.read()) { + case 1: cs.get(v._name); + case 2: cs.get(v._comment); + case 3: cs.get(v._attributes); + case 4: cs.get(v._value); + case 5: cs.get(v._name); + case 6: cs.get(v._children); + default: + if (cs.getID() >= 100 && cs.getID() < (100 + PIValueTree::FlagsRoleCount)) { + v._flags[cs.getID() - 100] = cs.getData(); + } + } + } + return s; +} + + +#endif // PIVALUETREE_H diff --git a/libs/main/types/pivariant.h b/libs/main/types/pivariant.h index 94e6842d..119fd14d 100644 --- a/libs/main/types/pivariant.h +++ b/libs/main/types/pivariant.h @@ -807,6 +807,9 @@ private: }; +typedef PIMap PIVariantMap; +typedef PIVector PIVariantVector; + template<> inline bool PIVariant::value() const {return toBool();} template<> inline char PIVariant::value() const {return (char)toInt();} template<> inline uchar PIVariant::value() const {return (uchar)toInt();} @@ -931,6 +934,8 @@ REGISTER_VARIANT(PIRectd) REGISTER_VARIANT(PILined) REGISTER_VARIANT(PIMathVectord) REGISTER_VARIANT(PIMathMatrixd) +REGISTER_VARIANT(PIVariantMap); +REGISTER_VARIANT(PIVariantVector); //! \relatesalso PIBinaryStream diff --git a/main.cpp b/main.cpp index 1d428d93..d61ba89f 100644 --- a/main.cpp +++ b/main.cpp @@ -3,151 +3,10 @@ #include "pibytearray.h" #include "pimathbase.h" #include "pijson.h" -#include "piwaitevent_p.h" +#include "pivaluetree.h" using namespace PICoutManipulators; -typedef PIMap PIVariantMap; -typedef PIVector PIVariantVector; - -REGISTER_VARIANT(PIVariantMap); -REGISTER_VARIANT(PIVariantVector); - - -class PIValueTree { -public: - PIValueTree(); - PIValueTree(const PIVariant & v); - PIValueTree(const PIString & n, const PIVariant & v); - - enum FlagStandard { - Hidden = 0x01, - Editable = 0x02, - Label = 0x04, - ArrayReorder = 0x1001, - ArrayResize = 0x1002, - }; - - bool isNull() const {return _is_null;} - bool isValid() const {return _value.isValid();} - - const PIString & name() const {return _name;} - void setName(const PIString & n); - - const PIVariant & value() const {return _value;} - void setValue(const PIVariant & v); - - const PIVector & children() const {return _children;} - - const PIVariantMap & attributes() const {return _attributes;} - PIVariantMap & attributes() {return _attributes;} - - PIFlags flagsStandard() {return _flags_standard;} - uint flagsCustom() {return _flags_custom;} - - bool contains(const PIString & name) const; - PIValueTree child(const PIString & name) const; - PIValueTree & child(const PIString & name); - PIValueTree & insert(const PIValueTree & n); - PIValueTree & remove(const PIString & name); - -private: - static PIValueTree & nullValue(); - PIString _name; - PIVariantMap _attributes; - PIVariant _value; - PIVector _children; - uint _flags_standard = Editable; - uint _flags_custom = 0u; - bool _is_null = false; -}; - - - - -PIValueTree::PIValueTree() { -} - - -PIValueTree::PIValueTree(const PIVariant & v) { - setValue(v); -} - - -PIValueTree::PIValueTree(const PIString & n, const PIVariant & v) { - setName(n); - setValue(v); -} - - -void PIValueTree::setName(const PIString & n) { - if (_is_null) return; - _name = n; -} - - -void PIValueTree::setValue(const PIVariant & v) { - if (_is_null) return; - _value = v; -} - - -bool PIValueTree::contains(const PIString & name) const { - if (_is_null) return true; - for (const auto & c: _children) - if (c.name() == name) - return true; - return false; -} - - -PIValueTree PIValueTree::child(const PIString & name) const { - if (_is_null) return PIValueTree(); - for (const auto & c: _children) - if (c.name() == name) - return c; - return PIValueTree(); -} - - -PIValueTree & PIValueTree::child(const PIString & name) { - if (_is_null) return nullValue(); - for (auto & c: _children) - if (c.name() == name) - return c; - return nullValue(); -} - - -PIValueTree & PIValueTree::insert(const PIValueTree & n) { - if (_is_null) return nullValue(); - for (auto & c: _children) - if (c.name() == n.name()) { - c = n; - return *this; - } - _children << n; - return *this; -} - - -PIValueTree & PIValueTree::remove(const PIString & name) { - if (_is_null) return nullValue(); - _children.removeWhere([name](const PIValueTree & i){return i.name() == name;}); - return *this; -} - - -PIValueTree & PIValueTree::nullValue() { - static PIValueTree ret; - ret._is_null = true; - return ret; -} - - - - - struct SomeType { int i; float f; @@ -169,18 +28,19 @@ REGISTER_VARIANT_CAST(PIString, SomeType) { int main(int argc, char * argv[]) { PIValueTree root; - root.insert({"bool", PIVariant(false)}); - root.insert({"integer", PIVariant(256)}); - root.insert({"string", PIVariant("str")}); - //for (auto it: root.children()) { - // piCout << it.name() << it.value(); - //} - PIVariant v = PIVariant::fromType("PIVariantTypes::IODevice"); - piCout << v; - piCout << v.toString(); - v.setValueFromString("2;-0.1"); - piCout << v.value(); - piCout << v.toString(); + root.addChild({"bool", PIVariant(false)}); + root.addChild({"integer", PIVariant(256)}); + root.addChild({"string", PIVariant("str")}); + for (auto it: root.children()) { + piCout << it.name() << it.value(); + } + piCout << piSerialize(root); + //PIVariant v = PIVariant::fromType(PIVariant::typeID()); + //piCout << v; + //piCout << v.toString(); + //v.setValueFromString("2E-3"); + //piCout << v.value(); + //piCout << v.toString(); return 0; }