Tulip
4.6.0
Better Visualization Through Research
|
00001 /* 00002 * 00003 * This file is part of Tulip (www.tulip-software.org) 00004 * 00005 * Authors: David Auber and the Tulip development Team 00006 * from LaBRI, University of Bordeaux 00007 * 00008 * Tulip is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License 00010 * as published by the Free Software Foundation, either version 3 00011 * of the License, or (at your option) any later version. 00012 * 00013 * Tulip is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00016 * See the GNU General Public License for more details. 00017 * 00018 */ 00019 00020 #ifndef PROPERTYWRAPPER_H 00021 #define PROPERTYWRAPPER_H 00022 00023 #include <tulip/DoubleProperty.h> 00024 #include <tulip/IntegerProperty.h> 00025 #include <tulip/LayoutProperty.h> 00026 #include <tulip/BooleanProperty.h> 00027 #include <tulip/ColorProperty.h> 00028 #include <tulip/StringProperty.h> 00029 #include <tulip/SizeProperty.h> 00030 00031 /** 00032 * @brief simple implementation of the copy-on-write idiom. 00033 */ 00034 template<typename PROPERTYTYPE, typename Type> 00035 class ValueWrapper { 00036 public: 00037 ValueWrapper(PROPERTYTYPE* prop, tlp::node n) : _prop(prop), _n(n) { 00038 } 00039 00040 ValueWrapper(PROPERTYTYPE* prop, tlp::edge e) : _prop(prop), _e(e) { 00041 } 00042 00043 void operator=(Type other) { 00044 if(_n.isValid()) 00045 _prop->setNodeValue(_n, other); 00046 00047 if(_e.isValid()) 00048 _prop->setEdgeValue(_e, other); 00049 } 00050 00051 /** 00052 * @brief Implicit conversion to Type 00053 */ 00054 operator Type() const { 00055 if(_n.isValid()) 00056 return _prop->getNodeValue(_n); 00057 00058 if(_e.isValid()) 00059 return _prop->getEdgeValue(_e); 00060 00061 std::cout << "WTF!?" << std::endl; 00062 return Type(); 00063 } 00064 00065 /** 00066 * @brief operator= when prop[n] = prop[n2] 00067 * @param other 00068 */ 00069 void operator=(ValueWrapper<PROPERTYTYPE, Type> other) { 00070 if(_n.isValid()) 00071 _prop->setNodeValue(_n, Type(other)); 00072 00073 if(_e.isValid()) 00074 _prop->setEdgeValue(_e, Type(other)); 00075 } 00076 00077 private: 00078 PROPERTYTYPE* _prop; 00079 tlp::node _n; 00080 tlp::edge _e; 00081 }; 00082 00083 template<typename PROPERTYTYPE, typename Type> 00084 class PropertyWrapper { 00085 public: 00086 PropertyWrapper(tlp::PropertyInterface* internal) { 00087 PROPERTYTYPE* castedInternal = dynamic_cast<PROPERTYTYPE*>(internal); 00088 00089 if(castedInternal == nullptr) { 00090 tlp::error() << "error: could not convert tulip property to " << tlp::demangleTlpClassName(typeid(PROPERTYTYPE).name()) << std::endl; 00091 } 00092 00093 _internal = castedInternal; 00094 } 00095 PropertyWrapper() : _internal(nullptr) {} 00096 00097 bool isValid() const { 00098 return _internal != nullptr; 00099 } 00100 00101 void setAllNodeValue(Type value) { 00102 _internal->setAllNodeValue(value); 00103 } 00104 00105 void setAllEdgeValue(Type value) { 00106 _internal->setAllEdgeValue(value); 00107 } 00108 00109 Type getNodeValue(tlp::node n) const { 00110 return _internal->getNodeValue(n); 00111 } 00112 void setNodeValue(tlp::node n, Type value) { 00113 _internal->setNodeValue(n, value); 00114 } 00115 00116 Type getEdgeValue(tlp::edge e) const { 00117 return _internal->getEdgeValue(e); 00118 } 00119 void setEdgeValue(tlp::edge e, Type value) { 00120 _internal->setEdgeValue(e, value); 00121 } 00122 00123 Type operator[](tlp::node n) const { 00124 return _internal->getNodeValue(n); 00125 } 00126 Type operator[](tlp::edge e) const { 00127 return _internal->getEdgeValue(e); 00128 } 00129 ValueWrapper<PROPERTYTYPE, Type> operator[](tlp::node n) { 00130 return ValueWrapper<PROPERTYTYPE, Type>(_internal, n); 00131 } 00132 00133 ValueWrapper<PROPERTYTYPE, Type> operator[](tlp::edge e) { 00134 return ValueWrapper<PROPERTYTYPE, Type>(_internal, e); 00135 } 00136 00137 PROPERTYTYPE* internal() const { 00138 return _internal; 00139 } 00140 00141 operator PROPERTYTYPE*() { 00142 return _internal; 00143 } 00144 00145 private: 00146 PROPERTYTYPE* _internal; 00147 }; 00148 00149 template<typename PROPERTYTYPE, typename NodeType, typename EdgeType> 00150 class ComplexValueWrapper { 00151 public: 00152 ComplexValueWrapper(PROPERTYTYPE* prop, tlp::node n) : _prop(prop), _n(n) { 00153 } 00154 00155 ComplexValueWrapper(PROPERTYTYPE* prop, tlp::edge e) : _prop(prop), _e(e) { 00156 } 00157 00158 void operator=(NodeType other) { 00159 if(_n.isValid()) 00160 _prop->setNodeValue(_n, other); 00161 } 00162 00163 void operator=(EdgeType other) { 00164 if(_e.isValid()) 00165 _prop->setEdgeValue(_e, other); 00166 } 00167 00168 operator NodeType() const { 00169 if(_n.isValid()) 00170 return _prop->getNodeValue(_n); 00171 } 00172 operator EdgeType() const { 00173 if(_e.isValid()) 00174 return _prop->getEdgeValue(_e); 00175 } 00176 00177 private: 00178 PROPERTYTYPE* _prop; 00179 tlp::node _n; 00180 tlp::edge _e; 00181 }; 00182 00183 template<typename PROPERTYTYPE, typename NodeType, typename EdgeType> 00184 class ComplexPropertyWrapper { 00185 public: 00186 ComplexPropertyWrapper(tlp::PropertyInterface* internal) { 00187 PROPERTYTYPE* castedInternal = dynamic_cast<PROPERTYTYPE*>(internal); 00188 00189 if(castedInternal == nullptr) { 00190 tlp::error() << "error: could not convert tulip property to " << tlp::demangleTlpClassName(typeid(PROPERTYTYPE).name()) << std::endl; 00191 } 00192 00193 _internal = castedInternal; 00194 } 00195 ComplexPropertyWrapper() : _internal(nullptr) {} 00196 00197 bool isValid() const { 00198 return _internal != nullptr; 00199 } 00200 00201 void setAllNodeValue(NodeType value) { 00202 _internal->setAllNodeValue(value); 00203 } 00204 00205 void setAllEdgeValue(EdgeType value) { 00206 _internal->setAllEdgeValue(value); 00207 } 00208 00209 NodeType getNodeValue(tlp::node n) const { 00210 return _internal->getNodeValue(n); 00211 } 00212 void setNodeValue(tlp::node n, EdgeType value) { 00213 _internal->setNodeValue(n, value); 00214 } 00215 00216 NodeType getEdgeValue(tlp::edge e) const { 00217 return _internal->getEdgeValue(e); 00218 } 00219 void setEdgeValue(tlp::edge e, NodeType value) { 00220 _internal->setEdgeValue(e, value); 00221 } 00222 00223 NodeType operator[](tlp::node n) const { 00224 return _internal->getNodeValue(n); 00225 } 00226 EdgeType operator[](tlp::edge e) const { 00227 return _internal->getEdgeValue(e); 00228 } 00229 ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType> operator[](tlp::node n) { 00230 return ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType>(_internal, n); 00231 } 00232 00233 ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType> operator[](tlp::edge e) { 00234 return ComplexValueWrapper<PROPERTYTYPE, NodeType, EdgeType>(_internal, e); 00235 } 00236 00237 PROPERTYTYPE* internal() const; 00238 00239 operator PROPERTYTYPE*() { 00240 return _internal; 00241 } 00242 00243 private: 00244 PROPERTYTYPE* _internal; 00245 }; 00246 00247 typedef PropertyWrapper<tlp::DoubleProperty, double> DoublePropertyWrapper; 00248 typedef PropertyWrapper<tlp::IntegerProperty, int> IntegerPropertyWrapper; 00249 typedef PropertyWrapper<tlp::BooleanProperty, bool> BooleanPropertyWrapper; 00250 typedef PropertyWrapper<tlp::ColorProperty, tlp::Color> ColorPropertyWrapper; 00251 typedef PropertyWrapper<tlp::StringProperty, std::string> StringPropertyWrapper; 00252 typedef PropertyWrapper<tlp::SizeProperty, tlp::Size> SizePropertyWrapper; 00253 typedef ComplexPropertyWrapper<tlp::LayoutProperty, tlp::Coord, tlp::LineType> LayoutPropertyWrapper; 00254 00255 #endif // PROPERTYWRAPPER_H