Tulip  4.4.0
Better Visualization Through Research
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Groups Pages
AbstractProperty.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 ABSTRACT_PROPERTY_H
21 #define ABSTRACT_PROPERTY_H
22 
23 #include <typeinfo>
24 #include <string>
25 #include <cstdlib>
26 #include <tulip/tulipconf.h>
27 #include <tulip/StoredType.h>
28 #include <tulip/MutableContainer.h>
29 #include <tulip/PropertyInterface.h>
30 #include <tulip/Iterator.h>
31 #include <tulip/PropertyAlgorithm.h>
32 #include <tulip/DataSet.h>
33 #include <tulip/Graph.h>
34 
35 namespace tlp {
36 
37 class GraphView;
38 
39 //==============================================================
40 
41 /**
42  * @ingroup Graph
43  * @brief This class extends upon PropertyInterface, and adds type-safe methods to
44  * get and set the node and edge values, through the magic of template programming.
45  *
46  * Nodes and Edges can have different types (e.g. tlp::LayoutProperty has tlp::PointType as node type and tlp::LineType as edge type),
47  * but most of the time they have the same type (e.g. tlp::DoubleProperty, tlp::IntegerProperty).
48  *
49  * Some of the pure virtual functions of PropertyInterface are implemented in this class (e.g. erase()).
50  *
51  * The actual data is stored in this class, and it manages the default values.
52  */
53 template <class Tnode, class Tedge, class Tprop=PropertyInterface>
54 class TLP_SCOPE AbstractProperty : public Tprop {
55  friend class Graph;
56  friend class GraphView;
57 
58 public:
59  AbstractProperty(Graph *, std::string n = "");
60 
61  /**
62  * @brief Gets the default node value of the property.
63  * @return The default value of nodes.
64  */
65  virtual typename Tnode::RealType getNodeDefaultValue() const;
66 
67  /**
68  * @brief Gets the default edge value of the property.
69  * @return The default value of edges.
70  **/
71  virtual typename Tedge::RealType getEdgeDefaultValue() const;
72 
73  /**
74  * @brief Returns the value associated with the node n in this property.
75  * If there is no value, it returns the default node value.
76  *
77  * @param n The node for which we want to get the value of the property.
78  * @return :StoredType< Tnode::RealType >::ReturnedConstValue The value of the property for this node.
79  **/
80  virtual typename tlp::StoredType<typename Tnode::RealType>::ReturnedConstValue getNodeValue(const node n ) const;
81 
82  /**
83  * @brief Returns the value associated to the edge e in this property.
84  * If there is no value, it returns the default edge value.
85  *
86  * @param e The edge for which we want to get the value of the property.
87  * @return :StoredType< Tedge::RealType >::ReturnedConstValue The value of the property for this edge.
88  **/
89  virtual typename tlp::StoredType<typename Tedge::RealType>::ReturnedConstValue getEdgeValue(const edge e) const;
90 
91  /**
92  * @brief Sets the value of a node and notify the observers of a modification.
93  *
94  * @param n The node to set the value of.
95  * @param v The value to affect for this node.
96  **/
97  virtual void setNodeValue(const node n, const typename Tnode::RealType &v);
98 
99  /**
100  * @brief Set the value of an edge and notify the observers of a modification.
101  *
102  * @param e The edge to set the value of.
103  * @param v The value to affect for this edge.
104  **/
105  virtual void setEdgeValue(const edge e, const typename Tedge::RealType &v);
106 
107  /**
108  * @brief Sets the value of all nodes and notify the observers.
109  *
110  * @param v The value to set to all nodes.
111  *
112  **/
113  virtual void setAllNodeValue(const typename Tnode::RealType &v);
114 
115  /**
116  * @brief Sets the value of all edges and notify the observers.
117  *
118  * @param v The value to set to all edges.
119  *
120  **/
121  virtual void setAllEdgeValue(const typename Tedge::RealType &v);
122  //=================================================================================
123 
124  /**
125  * @brief Resets the value of a node to the default value.
126  *
127  * @param n The node to reset the value of.
128  *
129  **/
130  virtual void erase(const node n) {
131  setNodeValue(n, nodeDefaultValue);
132  }
133  //=================================================================================
134 
135  /**
136  * @brief Resets the value of an edge to the default value.
137  *
138  * @param e The edge to reset the value of.
139  *
140  **/
141  virtual void erase(const edge e) {
142  setEdgeValue(e, edgeDefaultValue);
143  }
144  //=================================================================================
145  /**
146  * @brief This operator overload allows to copy a property using the following syntax :
147  *
148  * @code
149  * IntegerProperty* shape = graph->getProperty<IntegerProperty>("viewShape");
150  * IntegerProperty* backup = graph->getProperty<IntegerProperty>("shapeBackup");
151  * *backup = *shape; // all the values from 'shape' will be copied into 'backup'.
152  * @endcode
153  * @param prop The property nto copy the values from.
154  * @return This property with the values copied.
155  */
157  if (this!= &prop) {
158  if (Tprop::graph == NULL) Tprop::graph = prop.Tprop::graph;
159 
160  if (Tprop::graph == prop.Tprop::graph) {
161  setAllNodeValue(prop.getNodeDefaultValue());
162  setAllEdgeValue(prop.getEdgeDefaultValue());
163  Iterator<node> *itN = prop.getNonDefaultValuatedNodes();
164 
165  while (itN->hasNext()) {
166  node itn = itN->next();
167  setNodeValue(itn, prop.getNodeValue(itn));
168  }
169 
170  delete itN;
171  Iterator<edge> *itE = prop.getNonDefaultValuatedEdges();
172 
173  while (itE->hasNext()) {
174  edge ite = itE->next();
175  setEdgeValue(ite, prop.getEdgeValue(ite));
176  }
177 
178  delete itE;
179  }
180  else {
181  //==============================================================*
182  Iterator<node>* itN = Tprop::graph->getNodes();
183 
184  while (itN->hasNext()) {
185  node itn=itN->next();
186 
187  if (prop.Tprop::graph->isElement(itn))
188  setNodeValue(itn, prop.getNodeValue(itn));
189  }
190 
191  delete itN;
192  Iterator<edge>*itE = Tprop::graph->getEdges();
193 
194  while (itE->hasNext()) {
195  edge ite=itE->next();
196 
197  if (prop.Tprop::graph->isElement(ite))
198  setEdgeValue(ite, prop.getEdgeValue(ite));
199  }
200 
201  delete itE;
202  }
203 
204  clone_handler(prop);
205  }
206 
207  return *this;
208  }
209  //=================================================================================
210  // Untyped accessors inherited from PropertyInterface, documentation is inherited
211  virtual std::string getNodeDefaultStringValue() const {
212  typename Tnode::RealType v = getNodeDefaultValue();
213  return Tnode::toString( v );
214  }
215  virtual std::string getEdgeDefaultStringValue() const {
216  typename Tedge::RealType v = getEdgeDefaultValue();
217  return Tedge::toString( v );
218  }
219  virtual std::string getNodeStringValue( const node n ) const {
220  typename Tnode::RealType v = getNodeValue( n );
221  return Tnode::toString( v );
222  }
223  virtual std::string getEdgeStringValue( const edge e ) const {
224  typename Tedge::RealType v = getEdgeValue( e );
225  return Tedge::toString( v );
226  }
227  virtual bool setNodeStringValue( const node inN, const std::string & inV ) {
228  typename Tnode::RealType v;
229 
230  if( !Tnode::fromString(v,inV) )
231  return false;
232 
233  setNodeValue( inN, v );
234  return true;
235  }
236  virtual bool setEdgeStringValue( const edge inE, const std::string & inV ) {
237  typename Tedge::RealType v;
238 
239  if( !Tedge::fromString(v,inV) )
240  return false;
241 
242  setEdgeValue( inE, v );
243  return true;
244  }
245  virtual bool setAllNodeStringValue( const std::string & inV ) {
246  typename Tnode::RealType v;
247 
248  if( !Tnode::fromString(v,inV) )
249  return false;
250 
251  setAllNodeValue( v );
252  return true;
253  }
254  virtual bool setAllEdgeStringValue( const std::string & inV ) {
255  typename Tedge::RealType v;
256 
257  if( !Tedge::fromString(v,inV) )
258  return false;
259 
260  setAllEdgeValue( v );
261  return true;
262  }
263  virtual tlp::Iterator<node>* getNonDefaultValuatedNodes(const Graph* g = NULL) const;
264  virtual tlp::Iterator<edge>* getNonDefaultValuatedEdges(const Graph* g = NULL) const;
265  virtual bool copy(const node destination, const node source, PropertyInterface *property,
266  bool ifNotDefault = false) {
267  if (property == NULL)
268  return false;
269 
271  dynamic_cast<tlp::AbstractProperty<Tnode,Tedge,Tprop>*>(property);
272  assert(tp);
273  bool notDefault;
274  typename StoredType<typename Tnode::RealType>::ReturnedValue value =
275  tp->nodeProperties.get(source.id, notDefault);
276 
277  if (ifNotDefault && !notDefault)
278  return false;
279 
280  setNodeValue(destination, value);
281  return true;
282  }
283  virtual bool copy(const edge destination, const edge source, PropertyInterface *property,
284  bool ifNotDefault = false) {
285  if (property == NULL)
286  return false;
287 
289  dynamic_cast<tlp::AbstractProperty<Tnode,Tedge,Tprop>*>(property);
290  assert(tp);
291  bool notDefault;
292  typename StoredType<typename Tedge::RealType>::ReturnedValue value =
293  tp->edgeProperties.get(source.id, notDefault);
294 
295  if (ifNotDefault && !notDefault)
296  return false;
297 
298  setEdgeValue(destination, value);
299  return true;
300  }
301  virtual void copy(PropertyInterface* property) {
303  dynamic_cast<typename tlp::AbstractProperty<Tnode,Tedge,Tprop>*>(property);
304  assert(prop != NULL);
305  *this = *prop;
306  }
307  // for performance reason and use in GraphUpdatesRecorder
308  virtual DataMem* getNodeDefaultDataMemValue() const {
309  return new TypedValueContainer<typename Tnode::RealType>(getNodeDefaultValue());
310  }
311  virtual DataMem* getEdgeDefaultDataMemValue() const {
312  return new TypedValueContainer<typename Tedge::RealType>(getEdgeDefaultValue());
313  }
314  virtual DataMem* getNodeDataMemValue(const node n) const {
315  return new TypedValueContainer<typename Tnode::RealType>(getNodeValue(n));
316  }
317  virtual DataMem* getEdgeDataMemValue(const edge e) const {
318  return new TypedValueContainer<typename Tedge::RealType>(getEdgeValue(e));
319  }
320  virtual DataMem* getNonDefaultDataMemValue( const node n ) const {
321  bool notDefault;
322  typename StoredType<typename Tnode::RealType>::ReturnedValue value = nodeProperties.get(n.id, notDefault);
323 
324  if (notDefault)
325  return new TypedValueContainer<typename Tnode::RealType>(value);
326 
327  return NULL;
328  }
329  virtual DataMem* getNonDefaultDataMemValue( const edge e ) const {
330  bool notDefault;
331  typename StoredType<typename Tedge::RealType>::ReturnedValue value = edgeProperties.get(e.id, notDefault);
332 
333  if (notDefault)
334  return new TypedValueContainer<typename Tedge::RealType>(value);
335 
336  return NULL;
337  }
338  virtual void setNodeDataMemValue( const node n, const DataMem* v) {
339  setNodeValue(n, ((TypedValueContainer<typename Tnode::RealType> *) v)->value);
340  }
341  virtual void setEdgeDataMemValue( const edge e, const DataMem* v) {
342  setEdgeValue(e, ((TypedValueContainer<typename Tedge::RealType> *) v)->value);
343  }
344  virtual void setAllNodeDataMemValue(const DataMem* v) {
345  setAllNodeValue(((TypedValueContainer<typename Tnode::RealType> *) v)->value);
346  }
347  virtual void setAllEdgeDataMemValue(const DataMem* v) {
348  setAllEdgeValue(((TypedValueContainer<typename Tedge::RealType> *) v)->value);
349  }
350 
351  // PropertyInterface methods
352  // mN is the meta node, sg is the corresponding subgraph
353  // and mg is the graph owning mN
354  virtual void computeMetaValue(node n, Graph* sg, Graph* mg) {
355  if (Tprop::metaValueCalculator)
357  Tprop::metaValueCalculator)->computeMetaValue(this, n, sg, mg);
358  }
359  // mE is the meta edge, itE is an iterator on the underlying edges
360  // mg is the graph owning mE
361  virtual void computeMetaValue(edge e, tlp::Iterator<edge>* itE, Graph* mg) {
362  if (Tprop::metaValueCalculator)
363  ((typename tlp::AbstractProperty<Tnode,Tedge,Tprop>::MetaValueCalculator *) Tprop::metaValueCalculator)->computeMetaValue(this, e, itE, mg);
364  }
365  virtual void setMetaValueCalculator(PropertyInterface::MetaValueCalculator *mvCalc) {
366  if (mvCalc && !dynamic_cast<typename tlp::AbstractProperty<Tnode,Tedge,Tprop>::MetaValueCalculator *>(mvCalc)) {
367  tlp::warning() << "Warning : " << __PRETTY_FUNCTION__ << " ... invalid conversion of " << typeid(mvCalc).name() << "into " << typeid(typename tlp::AbstractProperty<Tnode,Tedge,Tprop>::MetaValueCalculator *).name() << std::endl;
368  abort();
369  }
370 
371  Tprop::metaValueCalculator = mvCalc;
372  }
373 
374  int compare(const node n1, const node n2) const;
375  int compare(const edge e1, const edge e2) const;
376 
377 
378  /**
379  * @brief This class is used to delegate the computation of the values associated to meta nodes or edges.
380  **/
382  public:
383  // computes the value of the meta node mN of the graph mg
384  // for the property prop, according to the values associated
385  // to the underlying nodes i.e the nodes of the subgraph sg.
386  virtual void computeMetaValue(AbstractProperty<Tnode,Tedge,Tprop>*,
387  node,
388  Graph*, Graph*) {}
389  // computes the value of the meta node mE of the graph mg
390  // for the property prop, according to the values associated
391  // to the underlying edges given by the iterator itE.
392  // The method do not have to delete the iterator
393  virtual void computeMetaValue(AbstractProperty<Tnode,Tedge,Tprop>*,
394  edge, tlp::Iterator<edge>*,
395  Graph*) {}
396  };
397 
398 protected:
399  //=================================================================================
400  ///Enable to clone part of sub_class
402 
403  MutableContainer<typename Tnode::RealType> nodeProperties;
404  MutableContainer<typename Tedge::RealType> edgeProperties;
405  typename Tnode::RealType nodeDefaultValue;
406  typename Tedge::RealType edgeDefaultValue;
407 };
408 
409 template <typename vectType,typename eltType,typename propType=PropertyInterface>
410 class TLP_SCOPE AbstractVectorProperty : public AbstractProperty<vectType, vectType, propType> {
411 public:
412  AbstractVectorProperty(Graph *, std::string name = "");
413 
414  /**
415  * @brief Sets the value for node n, at index i, to v, and notify the observers of a modification.
416  *
417  * @param n The node to set a value of.
418  * @param i The index at which the value should be set.
419  * @param v The value to set.
420  *
421  **/
422  void setNodeEltValue(const node n, unsigned int i, typename tlp::StoredType<typename eltType::RealType>::ReturnedConstValue v);
423  /**
424  * @brief Gets the value associated to node n, at index i.
425  *
426  * @param n The node to set a value of.
427  * @param i The index at which to set the value.
428  * @return const eltType& The value at index i in the vector for node n.
429  **/
430  typename tlp::StoredType<typename eltType::RealType>::ReturnedConstValue getNodeEltValue(const node n, unsigned int i) const;
431  /**
432  * @brief Appends a new value at the end of the vector associated to node n, and notify the observers of a modification.
433  *
434  * @param n The node to add a value to.
435  * @param v The value to append at the end of the vector.
436  *
437  **/
438  void pushBackNodeEltValue(const node n, typename tlp::StoredType<typename eltType::RealType>::ReturnedConstValue v);
439  /**
440  * @brief Removes the value at the end of the vector associated to node n, and notify the observers of a modification.
441  *
442  * @param n The node to remove a value from.
443  *
444  **/
445  void popBackNodeEltValue(const node n);
446  /**
447  * @brief Resizes the vector associated to node n, and notify the observers of a modification.
448  *
449  * @param n The node associated to the vector to resize.
450  * @param size The new size of the vector.
451  * @param elt The default value to set at indices where there was no value before. Defaults to eltType().
452  *
453  **/
454  void resizeNodeValue(const node n, size_t size, typename eltType::RealType elt = eltType::defaultValue());
455  /**
456  * @brief Sets the value for edge e, at index i, to v, and notify the observers of a modification.
457  *
458  * @param e The edge to set the value of.
459  * @param i The index at which the value should be set.
460  * @param v The value to set.
461  *
462  **/
463  void setEdgeEltValue(const edge e, unsigned int i, typename tlp::StoredType<typename eltType::RealType>::ReturnedConstValue v);
464  /**
465  * @brief Gets the value associated to edge e, at index i.
466  *
467  * @param e The edge to set a value of.
468  * @param i The index at which to set the value.
469  * @return const eltType& The value at index i in the vector for node n.
470  **/
471  typename tlp::StoredType<typename eltType::RealType>::ReturnedConstValue getEdgeEltValue(const edge n, unsigned int i) const;
472  /**
473  * @brief Appends a new value at the end of the vector associated to edge e, and notify the observers of a modification.
474  *
475  * @param e The node to add a value to.
476  * @param v The value to append at the end of the vector.
477  *
478  **/
479  void pushBackEdgeEltValue(const edge e, typename tlp::StoredType<typename eltType::RealType>::ReturnedConstValue v);
480  /**
481  * @brief Removes the value at the end of the vector associated to edge e, and notify the observers of a modification.
482  *
483  * @param e The edge to remove a value from.
484  *
485  **/
486  void popBackEdgeEltValue(const edge e);
487  /**
488  * @brief Resizes the vector associated to edge e, and notify the observers of a modification.
489  *
490  * @param e The edge associated to the vector to resize.
491  * @param size The new size of the vector.
492  * @param elt The default value to set at indices where there was no value before. Defaults to eltType().
493  *
494  **/
495  void resizeEdgeValue(const edge e, size_t size, typename eltType::RealType elt = eltType::defaultValue());
496 };
497 
498 
499 }
500 #if !defined(_MSC_VER) || defined(DLL_TULIP) //When using VC++, we only want to include this when we are in the TULIP dll. With any other compiler, include it all the time
501 # include "cxx/AbstractProperty.cxx"
502 #endif
503 #endif