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;
}