DeviceNode.hpp
1 #pragma once
2 #include <State/Address.hpp>
3 #include <State/Message.hpp>
4 
5 #include <Device/Address/AddressSettings.hpp>
6 #include <Device/Protocol/DeviceSettings.hpp>
7 
8 #include <score/config.hpp>
9 #include <score/model/tree/TreeNode.hpp>
10 #include <score/model/tree/TreePath.hpp>
11 #include <score/model/tree/VariantBasedNode.hpp>
12 
13 #include <QString>
14 #include <QStringList>
15 
16 #include <score_lib_device_export.h>
17 
18 class DataStream;
19 class JSONObject;
20 
21 namespace Device
22 {
23 struct AddressSettings;
24 struct DeviceSettings;
25 
26 class SCORE_LIB_DEVICE_EXPORT DeviceExplorerNode
27  : public score::VariantBasedNode<Device::DeviceSettings, Device::AddressSettings>
28 {
29  SCORE_SERIALIZE_FRIENDS
30 
31 public:
32  enum class Type
33  {
34  RootNode,
35  Device,
36  Address
37  };
38 
39  DeviceExplorerNode(const DeviceExplorerNode& t) = default;
41  DeviceExplorerNode& operator=(const DeviceExplorerNode& t) = default;
42  DeviceExplorerNode() = default;
43  template <typename T>
44  DeviceExplorerNode(const T& t)
45  : VariantBasedNode{t}
46  {
47  }
48  template <typename T>
49  DeviceExplorerNode(T&& t)
50  : VariantBasedNode{std::move(t)}
51  {
52  }
53 
54  bool operator==(const DeviceExplorerNode& other) const
55  {
56  return static_cast<const VariantBasedNode&>(*this)
57  == static_cast<const VariantBasedNode&>(other);
58  }
59 
60  //- accessors
61  const QString& displayName() const;
62 
63  bool isSelectable() const;
64  bool isEditable() const;
65 };
66 
75 using NodePath = TreePath;
76 
77 // TODO reflist may be a better name.
78 using FreeNode = std::pair<State::Address, Device::Node>;
79 using NodeList = std::vector<Device::Node*>;
80 using FreeNodeList = std::vector<FreeNode>;
81 
82 // TODO add specifications & tests to these functions
83 
84 SCORE_LIB_DEVICE_EXPORT QString deviceName(const Node& treeNode);
85 SCORE_LIB_DEVICE_EXPORT State::AddressAccessor address(const Node& treeNode);
86 
87 SCORE_LIB_DEVICE_EXPORT State::Message message(const Device::Node& node);
88 
95 SCORE_LIB_DEVICE_EXPORT void
96 parametersList(const Node& treeNode, State::MessageList& ml);
97 
98 // TODO have all these guys return references
99 SCORE_LIB_DEVICE_EXPORT Device::Node&
100 getNodeFromAddress(Device::Node& root, const State::Address&);
101 SCORE_LIB_DEVICE_EXPORT Device::Node* getNodeFromString(
102  Device::Node& n,
103  const QStringList& str); // Fails if not present.
104 
109 SCORE_LIB_DEVICE_EXPORT void dumpTree(const Device::Node& node, QString rec);
110 
111 SCORE_LIB_DEVICE_EXPORT Device::Node
112 merge(Device::Node base, const State::MessageList& other);
113 
114 SCORE_LIB_DEVICE_EXPORT void merge(Device::Node& base, const State::Message& message);
115 
116 inline auto findChildNode_it(const Device::Node& node, const QString& name)
117 {
118  return std::find_if(node.begin(), node.end(), [&](const Device::Node& n) {
119  return n.get<Device::AddressSettings>().name == name;
120  });
121 }
122 
123 inline const Device::Node* findChildNode(const Device::Node& node, const QString& name)
124 {
125  const Device::Node* res{};
126  auto it = findChildNode_it(node, name);
127  if(it != node.end())
128  res = &*it;
129  return res;
130 }
131 
132 // Generic algorithms for DeviceExplorerNode-like structures.
133 template <typename Node_T, typename It>
134 Node_T* try_getNodeFromString_impl(Node_T& n, It begin, It end)
135 {
136  if(begin == end)
137  return &n;
138 
139  for(auto& child : n)
140  {
141  if(child.displayName() == *begin)
142  {
143  return try_getNodeFromString_impl(child, ++begin, end);
144  }
145  }
146 
147  return nullptr;
148 }
149 
150 template <typename Node_T>
151 Node_T* try_getNodeFromString(Node_T& n, const QStringList& parts)
152 {
153  return try_getNodeFromString_impl(n, parts.cbegin(), parts.cend());
154 }
155 
156 template <typename Node_T>
157 Node_T* try_getNodeFromAddress(Node_T& root, const State::Address& addr)
158 {
159  if(addr.device.isEmpty())
160  return &root;
161 
162  auto dev = std::find_if(root.begin(), root.end(), [&](const Node_T& n) {
163  return n.template is<Device::DeviceSettings>()
164  && n.template get<Device::DeviceSettings>().name == addr.device;
165  });
166 
167  if(dev == root.end())
168  return nullptr;
169 
170  return try_getNodeFromString(*dev, addr.path);
171 }
172 
173 bool operator<(const Device::Node& lhs, const Device::Node& rhs);
174 }
175 
176 #if SCORE_EXTERN_TEMPLATES_IN_SHARED_LIBRARIES
177 extern template class SCORE_LIB_DEVICE_EXPORT TreeNode<Device::DeviceExplorerNode>;
178 #endif
179 W_REGISTER_ARGTYPE(Device::Node*)
Definition: VisitorInterface.hpp:53
Definition: DeviceNode.hpp:28
Definition: VisitorInterface.hpp:61
Path in a tree of QAbstractItemModel objects.
Definition: TreePath.hpp:34
The VariantBasedNode class.
Definition: VariantBasedNode.hpp:23
Manipulation of Devices from Qt.
Definition: AddressSettings.cpp:14
void dumpTree(const Node &node, QString rec)
dumpTree An utility to print trees of Device::Nodes
Definition: DeviceNode.cpp:246
void parametersList(const Node &n, State::MessageList &ml)
parametersList Recursive list of parameters in this node
Definition: DeviceNode.cpp:119
Definition: Address.hpp:108
The Address struct.
Definition: Address.hpp:58
The Message struct.
Definition: Message.hpp:15