Tulip  4.3.0
Better Visualization Through Research
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Groups Pages
PropertyWrapper.h
1 /*
2  *
3  * This file is part of Tulip (www.tulip-software.org)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux 1 and Inria Bordeaux - Sud Ouest
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 
20 #ifndef PROPERTYWRAPPER_H
21 #define PROPERTYWRAPPER_H
22 
23 #include <tulip/DoubleProperty.h>
24 #include <tulip/IntegerProperty.h>
25 #include <tulip/LayoutProperty.h>
26 #include <tulip/BooleanProperty.h>
27 #include <tulip/ColorProperty.h>
28 #include <tulip/StringProperty.h>
29 #include <tulip/SizeProperty.h>
30 
31 /**
32  * @brief simple implementation of the copy-on-write idiom.
33  */
34 template<typename PROPERTYTYPE, typename Type>
35 class ValueWrapper {
36 public:
37  ValueWrapper(PROPERTYTYPE* prop, tlp::node n) : _prop(prop), _n(n) {
38  }
39 
40  ValueWrapper(PROPERTYTYPE* prop, tlp::edge e) : _prop(prop), _e(e) {
41  }
42 
43  void operator=(Type other) {
44  if(_n.isValid())
45  _prop->setNodeValue(_n, other);
46 
47  if(_e.isValid())
48  _prop->setEdgeValue(_e, other);
49  }
50 
51  /**
52  * @brief Implicit conversion to Type
53  */
54  operator Type() const {
55  if(_n.isValid())
56  return _prop->getNodeValue(_n);
57 
58  if(_e.isValid())
59  return _prop->getEdgeValue(_e);
60 
61  std::cout << "WTF!?" << std::endl;
62  return Type();
63  }
64 
65  /**
66  * @brief operator= when prop[n] = prop[n2]
67  * @param other
68  */
70  if(_n.isValid())
71  _prop->setNodeValue(_n, Type(other));
72 
73  if(_e.isValid())
74  _prop->setEdgeValue(_e, Type(other));
75  }
76 
77 private:
78  PROPERTYTYPE* _prop;
79  tlp::node _n;
80  tlp::edge _e;
81 };
82 
83 template<typename PROPERTYTYPE, typename Type>
84 class PropertyWrapper {
85 public:
86  PropertyWrapper(tlp::PropertyInterface* internal) {
87  PROPERTYTYPE* castedInternal = dynamic_cast<PROPERTYTYPE*>(internal);
88 
89  if(castedInternal == nullptr) {
90  tlp::error() << "error: could not convert tulip property to " << tlp::demangleTlpClassName(typeid(PROPERTYTYPE).name()) << std::endl;
91  }
92 
93  _internal = castedInternal;
94  }
95  PropertyWrapper() : _internal(nullptr) {}
96 
97  bool isValid() const {
98  return _internal != nullptr;
99  }
100 
101  void setAllNodeValue(Type value) {
102  _internal->setAllNodeValue(value);
103  }
104 
105  void setAllEdgeValue(Type value) {
106  _internal->setAllEdgeValue(value);
107  }
108 
109  Type getNodeValue(tlp::node n) const {
110  return _internal->getNodeValue(n);
111  }
112  void setNodeValue(tlp::node n, Type value) {
113  _internal->setNodeValue(n, value);
114  }
115 
116  Type getEdgeValue(tlp::edge e) const {
117  return _internal->getEdgeValue(e);
118  }
119  void setEdgeValue(tlp::edge e, Type value) {
120  _internal->setEdgeValue(e, value);
121  }
122 
123  Type operator[](tlp::node n) const {
124  return _internal->getNodeValue(n);
125  }
126  Type operator[](tlp::edge e) const {
127  return _internal->getEdgeValue(e);
128  }
130  return ValueWrapper<PROPERTYTYPE, Type>(_internal, n);
131  }
132 
134  return ValueWrapper<PROPERTYTYPE, Type>(_internal, e);
135  }
136 
137  PROPERTYTYPE* internal() const {
138  return _internal;
139  }
140 
141  operator PROPERTYTYPE*() {
142  return _internal;
143  }
144 
145 private:
146  PROPERTYTYPE* _internal;
147 };
148 
149 template<typename PROPERTYTYPE, typename NodeType, typename EdgeType>
150 class ComplexValueWrapper {
151 public:
152  ComplexValueWrapper(PROPERTYTYPE* prop, tlp::node n) : _prop(prop), _n(n) {
153  }
154 
155  ComplexValueWrapper(PROPERTYTYPE* prop, tlp::edge e) : _prop(prop), _e(e) {
156  }
157 
158  void operator=(NodeType other) {
159  if(_n.isValid())
160  _prop->setNodeValue(_n, other);
161  }
162 
163  void operator=(EdgeType other) {
164  if(_e.isValid())
165  _prop->setEdgeValue(_e, other);
166  }
167 
168  operator NodeType() const {
169  if(_n.isValid())
170  return _prop->getNodeValue(_n);
171  }
172  operator EdgeType() const {
173  if(_e.isValid())
174  return _prop->getEdgeValue(_e);
175  }
176 
177 private:
178  PROPERTYTYPE* _prop;
179  tlp::node _n;
180  tlp::edge _e;
181 };
182 
183 template<typename PROPERTYTYPE, typename NodeType, typename EdgeType>
184 class ComplexPropertyWrapper {
185 public:
186  ComplexPropertyWrapper(tlp::PropertyInterface* internal) {
187  PROPERTYTYPE* castedInternal = dynamic_cast<PROPERTYTYPE*>(internal);
188 
189  if(castedInternal == nullptr) {
190  tlp::error() << "error: could not convert tulip property to " << tlp::demangleTlpClassName(typeid(PROPERTYTYPE).name()) << std::endl;
191  }
192 
193  _internal = castedInternal;
194  }
195  ComplexPropertyWrapper() : _internal(nullptr) {}
196 
197  bool isValid() const {
198  return _internal != nullptr;
199  }
200 
201  void setAllNodeValue(NodeType value) {
202  _internal->setAllNodeValue(value);
203  }
204 
205  void setAllEdgeValue(EdgeType value) {
206  _internal->setAllEdgeValue(value);
207  }
208 
209  NodeType getNodeValue(tlp::node n) const {
210  return _internal->getNodeValue(n);
211  }
212  void setNodeValue(tlp::node n, EdgeType value) {
213  _internal->setNodeValue(n, value);
214  }
215 
216  NodeType getEdgeValue(tlp::edge e) const {
217  return _internal->getEdgeValue(e);
218  }
219  void setEdgeValue(tlp::edge e, NodeType value) {
220  _internal->setEdgeValue(e, value);
221  }
222 
223  NodeType operator[](tlp::node n) const {
224  return _internal->getNodeValue(n);
225  }
226  EdgeType operator[](tlp::edge e) const {
227  return _internal->getEdgeValue(e);
228  }
229  ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType> operator[](tlp::node n) {
230  return ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType>(_internal, n);
231  }
232 
233  ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType> operator[](tlp::edge e) {
234  return ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType>(_internal, e);
235  }
236 
237  PROPERTYTYPE* internal() const;
238 
239  operator PROPERTYTYPE*() {
240  return _internal;
241  }
242 
243 private:
244  PROPERTYTYPE* _internal;
245 };
246 
247 typedef PropertyWrapper<tlp::DoubleProperty, double> DoublePropertyWrapper;
248 typedef PropertyWrapper<tlp::IntegerProperty, int> IntegerPropertyWrapper;
249 typedef PropertyWrapper<tlp::BooleanProperty, bool> BooleanPropertyWrapper;
250 typedef PropertyWrapper<tlp::ColorProperty, tlp::Color> ColorPropertyWrapper;
251 typedef PropertyWrapper<tlp::StringProperty, std::string> StringPropertyWrapper;
252 typedef PropertyWrapper<tlp::SizeProperty, tlp::Size> SizePropertyWrapper;
253 typedef ComplexPropertyWrapper<tlp::LayoutProperty, tlp::Coord, tlp::LineType> LayoutPropertyWrapper;
254 
255 #endif // PROPERTYWRAPPER_H