Tulip  4.6.0
Better Visualization Through Research
library/tulip-core/include/tulip/AbstractProperty.h
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 ABSTRACT_PROPERTY_H
00021 #define ABSTRACT_PROPERTY_H
00022 
00023 #include <typeinfo>
00024 #include <string>
00025 #include <cstdlib>
00026 #include <tulip/tulipconf.h>
00027 #include <tulip/StoredType.h>
00028 #include <tulip/MutableContainer.h>
00029 #include <tulip/PropertyInterface.h>
00030 #include <tulip/Iterator.h>
00031 #include <tulip/PropertyAlgorithm.h>
00032 #include <tulip/DataSet.h>
00033 #include <tulip/Graph.h>
00034 
00035 namespace tlp {
00036 
00037 class GraphView;
00038 
00039 //==============================================================
00040 
00041 /**
00042  * @ingroup Graph
00043  * @brief This class extends upon PropertyInterface, and adds type-safe methods to
00044  * get and set the node and edge values, through the magic of template programming.
00045  *
00046  * Nodes and Edges can have different types (e.g. tlp::LayoutProperty has tlp::PointType as node type and tlp::LineType as edge type),
00047  * but most of the time they have the same type (e.g. tlp::DoubleProperty, tlp::IntegerProperty).
00048  *
00049  * Some of the pure virtual functions of PropertyInterface are implemented in this class (e.g. erase()).
00050  *
00051  * The actual data is stored in this class, and it manages the default values.
00052  */
00053 template <class Tnode, class Tedge, class Tprop=PropertyInterface>
00054 class TLP_SCOPE AbstractProperty : public Tprop {
00055   friend class Graph;
00056   friend class GraphView;
00057 
00058 public:
00059   AbstractProperty(Graph *, const std::string& n = "");
00060 
00061   /**
00062    * @brief Gets the default node value of the property.
00063    * @return The default value of nodes.
00064    */
00065   virtual typename Tnode::RealType getNodeDefaultValue() const;
00066 
00067   /**
00068    * @brief Gets the default edge value of the property.
00069    * @return The default value of edges.
00070    **/
00071   virtual typename Tedge::RealType getEdgeDefaultValue() const;
00072 
00073   /**
00074    * @brief Returns the value associated with the node n in this property.
00075    * If there is no value, it returns the default node value.
00076    *
00077    * @param n The node for which we want to get the value of the property.
00078    * @return :StoredType< Tnode::RealType >::ReturnedConstValue The value of the property for this node.
00079    **/
00080   virtual typename tlp::StoredType<typename Tnode::RealType>::ReturnedConstValue getNodeValue(const node n ) const;
00081 
00082   /**
00083    * @brief Returns the value associated to the edge e in this property.
00084    * If there is no value, it returns the default edge value.
00085    *
00086    * @param e The edge for which we want to get the value of the property.
00087    * @return :StoredType< Tedge::RealType >::ReturnedConstValue The value of the property for this edge.
00088    **/
00089   virtual typename tlp::StoredType<typename Tedge::RealType>::ReturnedConstValue getEdgeValue(const edge e) const;
00090 
00091   /**
00092    * @brief Sets the value of a node and notify the observers of a modification.
00093    *
00094    * @param n The node to set the value of.
00095    * @param v The value to affect for this node.
00096    **/
00097   virtual void setNodeValue(const node n, const typename Tnode::RealType &v);
00098 
00099   /**
00100    * @brief Set the value of an edge and notify the observers of a modification.
00101    *
00102    * @param e The edge to set the value of.
00103    * @param v The value to affect for this edge.
00104    **/
00105   virtual void setEdgeValue(const edge e, const typename Tedge::RealType &v);
00106 
00107   /**
00108    * @brief Sets the value of all nodes and notify the observers.
00109    *
00110    * @param v The value to set to all nodes.
00111    *
00112    **/
00113   virtual void setAllNodeValue(const typename Tnode::RealType &v);
00114 
00115   /**
00116    * @brief Sets the value of all edges and notify the observers.
00117    *
00118    * @param v The value to set to all edges.
00119    *
00120    **/
00121   virtual void setAllEdgeValue(const typename Tedge::RealType &v);
00122   //=================================================================================
00123 
00124   /**
00125    * @brief Resets the value of a node to the default value.
00126    *
00127    * @param n The node to reset the value of.
00128    *
00129    **/
00130   virtual void erase(const node n) {
00131     setNodeValue(n, nodeDefaultValue);
00132   }
00133   //=================================================================================
00134 
00135   /**
00136    * @brief Resets the value of an edge to the default value.
00137    *
00138    * @param e The edge to reset the value of.
00139    *
00140    **/
00141   virtual void erase(const edge e) {
00142     setEdgeValue(e, edgeDefaultValue);
00143   }
00144   //=================================================================================
00145   /**
00146    * @brief This operator overload allows to copy a property using the following syntax :
00147    *
00148    * @code
00149    * IntegerProperty* shape = graph->getProperty<IntegerProperty>("viewShape");
00150    * IntegerProperty* backup = graph->getProperty<IntegerProperty>("shapeBackup");
00151    * *backup = *shape; // all the values from 'shape' will be copied into 'backup'.
00152    * @endcode
00153    * @param prop The property nto copy the values from.
00154    * @return This property with the values copied.
00155    */
00156   virtual AbstractProperty<Tnode,Tedge,Tprop>& operator =(AbstractProperty<Tnode,Tedge,Tprop> &prop) {
00157     if (this!= &prop) {
00158       if (Tprop::graph == NULL) Tprop::graph = prop.Tprop::graph;
00159 
00160       if (Tprop::graph == prop.Tprop::graph) {
00161         setAllNodeValue(prop.getNodeDefaultValue());
00162         setAllEdgeValue(prop.getEdgeDefaultValue());
00163         Iterator<node> *itN = prop.getNonDefaultValuatedNodes();
00164 
00165         while (itN->hasNext()) {
00166           node itn = itN->next();
00167           setNodeValue(itn, prop.getNodeValue(itn));
00168         }
00169 
00170         delete itN;
00171         Iterator<edge> *itE = prop.getNonDefaultValuatedEdges();
00172 
00173         while (itE->hasNext()) {
00174           edge ite = itE->next();
00175           setEdgeValue(ite, prop.getEdgeValue(ite));
00176         }
00177 
00178         delete itE;
00179       }
00180       else {
00181         //==============================================================*
00182         Iterator<node>* itN = Tprop::graph->getNodes();
00183 
00184         while (itN->hasNext()) {
00185           node itn=itN->next();
00186 
00187           if (prop.Tprop::graph->isElement(itn))
00188             setNodeValue(itn, prop.getNodeValue(itn));
00189         }
00190 
00191         delete itN;
00192         Iterator<edge>*itE = Tprop::graph->getEdges();
00193 
00194         while (itE->hasNext()) {
00195           edge ite=itE->next();
00196 
00197           if (prop.Tprop::graph->isElement(ite))
00198             setEdgeValue(ite, prop.getEdgeValue(ite));
00199         }
00200 
00201         delete itE;
00202       }
00203 
00204       clone_handler(prop);
00205     }
00206 
00207     return *this;
00208   }
00209   //=================================================================================
00210   // Untyped accessors inherited from PropertyInterface, documentation is inherited
00211   virtual std::string getNodeDefaultStringValue() const {
00212     typename Tnode::RealType v = getNodeDefaultValue();
00213     return Tnode::toString( v );
00214   }
00215   virtual std::string getEdgeDefaultStringValue() const {
00216     typename Tedge::RealType v = getEdgeDefaultValue();
00217     return Tedge::toString( v );
00218   }
00219   virtual std::string getNodeStringValue( const node n ) const {
00220     typename Tnode::RealType v = getNodeValue( n );
00221     return Tnode::toString( v );
00222   }
00223   virtual std::string getEdgeStringValue( const edge e ) const {
00224     typename Tedge::RealType v = getEdgeValue( e );
00225     return Tedge::toString( v );
00226   }
00227   virtual bool setNodeStringValue( const node inN, const std::string & inV ) {
00228     typename Tnode::RealType v;
00229 
00230     if( !Tnode::fromString(v,inV) )
00231       return false;
00232 
00233     setNodeValue( inN, v );
00234     return true;
00235   }
00236   virtual bool setEdgeStringValue( const edge inE, const std::string & inV ) {
00237     typename Tedge::RealType v;
00238 
00239     if( !Tedge::fromString(v,inV) )
00240       return false;
00241 
00242     setEdgeValue( inE, v );
00243     return true;
00244   }
00245   virtual bool setAllNodeStringValue( const std::string & inV ) {
00246     typename Tnode::RealType v;
00247 
00248     if( !Tnode::fromString(v,inV) )
00249       return false;
00250 
00251     setAllNodeValue( v );
00252     return true;
00253   }
00254   virtual bool setAllEdgeStringValue( const std::string & inV ) {
00255     typename Tedge::RealType v;
00256 
00257     if( !Tedge::fromString(v,inV) )
00258       return false;
00259 
00260     setAllEdgeValue( v );
00261     return true;
00262   }
00263   virtual tlp::Iterator<node>* getNonDefaultValuatedNodes(const Graph* g = NULL) const;
00264   virtual unsigned int numberOfNonDefaultValuatedNodes() const;
00265   virtual unsigned int nodeValueSize() const;
00266   virtual void writeNodeDefaultValue(std::ostream&) const;
00267   virtual void writeNodeValue(std::ostream&, node) const;
00268   virtual bool readNodeDefaultValue(std::istream&);
00269   virtual bool readNodeValue(std::istream&, node);
00270   virtual tlp::Iterator<edge>* getNonDefaultValuatedEdges(const Graph* g = NULL) const;
00271   virtual unsigned int numberOfNonDefaultValuatedEdges() const;
00272   virtual unsigned int edgeValueSize() const;
00273   virtual void writeEdgeDefaultValue(std::ostream&) const;
00274   virtual void writeEdgeValue(std::ostream&, edge) const;
00275   virtual bool readEdgeDefaultValue(std::istream&);
00276   virtual bool readEdgeValue(std::istream&, edge);
00277   virtual bool copy(const node destination, const node source, PropertyInterface *property,
00278                     bool ifNotDefault = false) {
00279     if (property == NULL)
00280       return false;
00281 
00282     tlp::AbstractProperty<Tnode,Tedge,Tprop>* tp =
00283       dynamic_cast<tlp::AbstractProperty<Tnode,Tedge,Tprop>*>(property);
00284     assert(tp);
00285     bool notDefault;
00286     typename StoredType<typename Tnode::RealType>::ReturnedValue value =
00287       tp->nodeProperties.get(source.id, notDefault);
00288 
00289     if (ifNotDefault && !notDefault)
00290       return false;
00291 
00292     setNodeValue(destination, value);
00293     return true;
00294   }
00295   virtual bool copy(const edge destination, const edge source, PropertyInterface *property,
00296                     bool ifNotDefault = false) {
00297     if (property == NULL)
00298       return false;
00299 
00300     tlp::AbstractProperty<Tnode,Tedge,Tprop>* tp =
00301       dynamic_cast<tlp::AbstractProperty<Tnode,Tedge,Tprop>*>(property);
00302     assert(tp);
00303     bool notDefault;
00304     typename StoredType<typename Tedge::RealType>::ReturnedValue value =
00305       tp->edgeProperties.get(source.id, notDefault);
00306 
00307     if (ifNotDefault && !notDefault)
00308       return false;
00309 
00310     setEdgeValue(destination, value);
00311     return true;
00312   }
00313   virtual void copy(PropertyInterface* property) {
00314     tlp::AbstractProperty<Tnode,Tedge,Tprop>* prop =
00315       dynamic_cast<typename tlp::AbstractProperty<Tnode,Tedge,Tprop>*>(property);
00316     assert(prop != NULL);
00317     *this = *prop;
00318   }
00319   // for performance reason and use in GraphUpdatesRecorder
00320   virtual DataMem* getNodeDefaultDataMemValue() const {
00321     return new TypedValueContainer<typename Tnode::RealType>(getNodeDefaultValue());
00322   }
00323   virtual DataMem* getEdgeDefaultDataMemValue() const {
00324     return new TypedValueContainer<typename Tedge::RealType>(getEdgeDefaultValue());
00325   }
00326   virtual DataMem* getNodeDataMemValue(const node n) const {
00327     return new TypedValueContainer<typename Tnode::RealType>(getNodeValue(n));
00328   }
00329   virtual DataMem* getEdgeDataMemValue(const edge e) const {
00330     return new TypedValueContainer<typename Tedge::RealType>(getEdgeValue(e));
00331   }
00332   virtual DataMem* getNonDefaultDataMemValue( const node n ) const {
00333     bool notDefault;
00334     typename StoredType<typename Tnode::RealType>::ReturnedValue value = nodeProperties.get(n.id, notDefault);
00335 
00336     if (notDefault)
00337       return new TypedValueContainer<typename Tnode::RealType>(value);
00338 
00339     return NULL;
00340   }
00341   virtual DataMem* getNonDefaultDataMemValue( const edge e ) const {
00342     bool notDefault;
00343     typename StoredType<typename Tedge::RealType>::ReturnedValue value = edgeProperties.get(e.id, notDefault);
00344 
00345     if (notDefault)
00346       return new TypedValueContainer<typename Tedge::RealType>(value);
00347 
00348     return NULL;
00349   }
00350   virtual void setNodeDataMemValue( const node n, const DataMem* v) {
00351     setNodeValue(n, ((TypedValueContainer<typename Tnode::RealType> *) v)->value);
00352   }
00353   virtual void setEdgeDataMemValue( const edge e, const DataMem* v) {
00354     setEdgeValue(e, ((TypedValueContainer<typename Tedge::RealType> *) v)->value);
00355   }
00356   virtual void setAllNodeDataMemValue(const DataMem* v) {
00357     setAllNodeValue(((TypedValueContainer<typename Tnode::RealType> *) v)->value);
00358   }
00359   virtual void setAllEdgeDataMemValue(const DataMem* v) {
00360     setAllEdgeValue(((TypedValueContainer<typename Tedge::RealType> *) v)->value);
00361   }
00362 
00363   // PropertyInterface methods
00364   // mN is the meta node, sg is the corresponding subgraph
00365   // and mg is the graph owning mN
00366   virtual void computeMetaValue(node n, Graph* sg, Graph* mg) {
00367     if (Tprop::metaValueCalculator)
00368       ((typename tlp::AbstractProperty<Tnode,Tedge,Tprop>::MetaValueCalculator *)
00369        Tprop::metaValueCalculator)->computeMetaValue(this, n, sg, mg);
00370   }
00371   // mE is the meta edge, itE is an iterator on the underlying edges
00372   // mg is the graph owning mE
00373   virtual void computeMetaValue(edge e, tlp::Iterator<edge>* itE, Graph* mg) {
00374     if (Tprop::metaValueCalculator)
00375       ((typename tlp::AbstractProperty<Tnode,Tedge,Tprop>::MetaValueCalculator *) Tprop::metaValueCalculator)->computeMetaValue(this, e, itE, mg);
00376   }
00377   virtual void setMetaValueCalculator(PropertyInterface::MetaValueCalculator *mvCalc) {
00378     if (mvCalc && !dynamic_cast<typename tlp::AbstractProperty<Tnode,Tedge,Tprop>::MetaValueCalculator *>(mvCalc)) {
00379       tlp::warning() << "Warning : "  << __PRETTY_FUNCTION__ << " ... invalid conversion of " << typeid(mvCalc).name() << "into " << typeid(typename tlp::AbstractProperty<Tnode,Tedge,Tprop>::MetaValueCalculator *).name() << std::endl;
00380       abort();
00381     }
00382 
00383     Tprop::metaValueCalculator = mvCalc;
00384   }
00385 
00386   int compare(const node n1, const node n2) const;
00387   int compare(const edge e1, const edge e2) const;
00388 
00389 
00390   /**
00391    * @brief This class is used to delegate the computation of the values associated to meta nodes or edges.
00392    **/
00393   class MetaValueCalculator :public PropertyInterface::MetaValueCalculator {
00394   public:
00395     // computes the value of the meta node mN of the graph mg
00396     // for the property prop, according to the values associated
00397     // to the underlying nodes i.e the nodes of the subgraph sg.
00398     virtual void computeMetaValue(AbstractProperty<Tnode,Tedge,Tprop>*,
00399                                   node,
00400                                   Graph*, Graph*) {}
00401     // computes the value of the meta node mE of the graph mg
00402     // for the property prop, according to the values associated
00403     // to the underlying edges given by the iterator itE.
00404     // The method do not have to delete the iterator
00405     virtual void computeMetaValue(AbstractProperty<Tnode,Tedge,Tprop>*,
00406                                   edge, tlp::Iterator<edge>*,
00407                                   Graph*) {}
00408   };
00409 
00410 protected:
00411   //=================================================================================
00412   ///Enable to clone part of sub_class
00413   virtual void clone_handler(AbstractProperty<Tnode,Tedge,Tprop> &) {}
00414 
00415   MutableContainer<typename Tnode::RealType> nodeProperties;
00416   MutableContainer<typename Tedge::RealType> edgeProperties;
00417   typename Tnode::RealType nodeDefaultValue;
00418   typename Tedge::RealType edgeDefaultValue;
00419 };
00420 
00421 template <typename vectType,typename eltType,typename propType=VectorPropertyInterface>
00422 class TLP_SCOPE AbstractVectorProperty : public AbstractProperty<vectType, vectType, propType> {
00423 public:
00424   AbstractVectorProperty(Graph *, const std::string& name = "");
00425 
00426   // 2 methods inherited from VectorPropertyInterface
00427   bool setNodeStringValueAsVector(const node, const std::string&,
00428                                   char, char, char);
00429 
00430   bool setEdgeStringValueAsVector(const edge, const std::string&,
00431                                   char, char, char);
00432 
00433   /**
00434    * @brief Sets the value for node n, at index i, to v, and notify the observers of a modification.
00435    *
00436    * @param n The node to set a value of.
00437    * @param i The index at which the value should be set.
00438    * @param v The value to set.
00439    *
00440    **/
00441   void setNodeEltValue(const node n, unsigned int i, typename tlp::StoredType<typename eltType::RealType>::ReturnedConstValue v);
00442   /**
00443    * @brief Gets the value associated to node n, at index i.
00444    *
00445    * @param n The node to set a value of.
00446    * @param i The index at which to set the value.
00447    * @return const eltType& The value at index i in the vector for node n.
00448    **/
00449   typename tlp::StoredType<typename eltType::RealType>::ReturnedConstValue getNodeEltValue(const node n, unsigned int i) const;
00450   /**
00451    * @brief Appends a new value at the end of the vector associated to node n, and notify the observers of a modification.
00452    *
00453    * @param n The node to add a value to.
00454    * @param v The value to append at the end of the vector.
00455    *
00456    **/
00457   void pushBackNodeEltValue(const node n, typename tlp::StoredType<typename eltType::RealType>::ReturnedConstValue v);
00458   /**
00459    * @brief Removes the value at the end of the vector associated to node n, and notify the observers of a modification.
00460    *
00461    * @param n The node to remove a value from.
00462    *
00463    **/
00464   void popBackNodeEltValue(const node n);
00465   /**
00466    * @brief Resizes the vector associated to node n, and notify the observers of a modification.
00467    *
00468    * @param n The node associated to the vector to resize.
00469    * @param size The new size of the vector.
00470    * @param elt The default value to set at indices where there was no value before. Defaults to eltType().
00471    *
00472    **/
00473   void resizeNodeValue(const node n, size_t size, typename eltType::RealType elt = eltType::defaultValue());
00474   /**
00475    * @brief Sets the value for edge e, at index i, to v, and notify the observers of a modification.
00476    *
00477    * @param e The edge to set the value of.
00478    * @param i The index at which the value should be set.
00479    * @param v The value to set.
00480    *
00481    **/
00482   void setEdgeEltValue(const edge e, unsigned int i, typename tlp::StoredType<typename eltType::RealType>::ReturnedConstValue v);
00483   /**
00484    * @brief Gets the value associated to edge e, at index i.
00485    *
00486    * @param e The edge to set a value of.
00487    * @param i The index at which to set the value.
00488    * @return const eltType& The value at index i in the vector for node n.
00489    **/
00490   typename tlp::StoredType<typename eltType::RealType>::ReturnedConstValue getEdgeEltValue(const edge n, unsigned int i) const;
00491   /**
00492    * @brief Appends a new value at the end of the vector associated to edge e, and notify the observers of a modification.
00493    *
00494    * @param e The node to add a value to.
00495    * @param v The value to append at the end of the vector.
00496    *
00497    **/
00498   void pushBackEdgeEltValue(const edge e, typename tlp::StoredType<typename eltType::RealType>::ReturnedConstValue v);
00499   /**
00500    * @brief Removes the value at the end of the vector associated to edge e, and notify the observers of a modification.
00501    *
00502    * @param e The edge to remove a value from.
00503    *
00504    **/
00505   void popBackEdgeEltValue(const edge e);
00506   /**
00507    * @brief Resizes the vector associated to edge e, and notify the observers of a modification.
00508    *
00509    * @param e The edge associated to the vector to resize.
00510    * @param size The new size of the vector.
00511    * @param elt The default value to set at indices where there was no value before. Defaults to eltType().
00512    *
00513    **/
00514   void resizeEdgeValue(const edge e, size_t size, typename eltType::RealType elt = eltType::defaultValue());
00515 };
00516 
00517 
00518 }
00519 #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
00520 # include "cxx/AbstractProperty.cxx"
00521 #endif
00522 #endif
 All Classes Files Functions Variables Enumerations Enumerator Properties