TuttleOFX
1
|
00001 #include <tuttle/host/graph/InternalGraph.hpp> 00002 #include <tuttle/host/graph/IVertex.hpp> 00003 #include <tuttle/host/graph/IEdge.hpp> 00004 00005 #include <boost/graph/graphviz.hpp> 00006 #include <iostream> 00007 00008 namespace tuttle { 00009 namespace host { 00010 namespace graph { 00011 00012 namespace detail { 00013 template<class T> 00014 std::ostream& operator<<( std::ostream& os, const DotEntry<T>& d ) 00015 { 00016 // os << "[" << d._key << "=\"" << d._value << "\"]"; 00017 os << d._key << "=\"" << d._value << "\""; 00018 return os; 00019 } 00020 template<class T> 00021 std::ostream& operator<<( std::ostream& os, const SubDotEntry<T>& d ) 00022 { 00023 os << d._key << ":\'" << d._value << "\'\\n"; 00024 return os; 00025 } 00026 } 00027 00028 /** 00029 * @brief Use this function to force the correct syntax. 00030 * os << dotEntry( "label", "fooNode"); 00031 * output: [label="fooNode"] 00032 */ 00033 template<class T> 00034 detail::DotEntry<T> dotEntry( const std::string& key, const T& value ) 00035 { 00036 return detail::DotEntry<T>( key, value ); 00037 } 00038 template<class T> 00039 detail::SubDotEntry<T> subDotEntry( const std::string& key, const T& value ) 00040 { 00041 return detail::SubDotEntry<T>( key, value ); 00042 } 00043 00044 namespace detail { 00045 template <class Name> 00046 class simple_node_writer 00047 { 00048 public: 00049 simple_node_writer( Name _name ) : name( _name ) {} 00050 template <class VertexOrEdge> 00051 void operator()( std::ostream& out, const VertexOrEdge& v ) const 00052 { 00053 out << " [ " << get( name, v ) << " ]"; 00054 } 00055 00056 private: 00057 Name name; 00058 }; 00059 } 00060 00061 /** 00062 * @brief For simple export, don't use the real .dot syntax, just put the name. 00063 * like: [ fooNode ] 00064 * instead of: [label="fooNode"] 00065 */ 00066 template <class Name> 00067 inline detail::simple_node_writer<Name> make_simple_node_writer( Name n ) 00068 { 00069 return detail::simple_node_writer<Name>( n ); 00070 } 00071 00072 template<typename Vertex, typename ProcessEdge, typename OutEdgeList, typename VertexList, typename EdgeList> 00073 inline void exportSimple( std::ostream& os, const InternalGraph<Vertex, ProcessEdge, OutEdgeList, VertexList, EdgeList>& g ) 00074 { 00075 using namespace boost; 00076 boost::write_graphviz( os, g.getGraph(), 00077 make_simple_node_writer( get( &Vertex::_name, g.getGraph() ) ), 00078 make_simple_node_writer( get( &ProcessEdge::_name, g.getGraph() ) ) ); 00079 } 00080 00081 template<typename Vertex, typename ProcessEdge, typename OutEdgeList, typename VertexList, typename EdgeList> 00082 inline void exportAsDOT( std::ostream& os, const InternalGraph<Vertex, ProcessEdge, OutEdgeList, VertexList, EdgeList>& g ) 00083 { 00084 std::map<std::string, std::string> graph_attr, vertex_attr, edge_attr; 00085 graph_attr["size"] = "6,6"; 00086 graph_attr["rankdir"] = "LR"; 00087 graph_attr["ratio"] = "fill"; 00088 graph_attr["label"] = "TuttleOFX"; 00089 vertex_attr["shape"] = "circle"; 00090 vertex_attr["color"] = "dodgerblue4"; 00091 vertex_attr["fontcolor"] = "dodgerblue4"; 00092 edge_attr["style"] = "dashed"; 00093 edge_attr["minlen"] = "1"; 00094 edge_attr["color"] = "darkslategray"; 00095 edge_attr["fontcolor"] = "darkslategray"; 00096 00097 using namespace boost; 00098 boost::write_graphviz( os, 00099 g.getGraph(), 00100 boost::make_label_writer( get( &IVertex::_name, g.getGraph() ) ), 00101 boost::make_label_writer( get( &IEdge::_name, g.getGraph() ) ), 00102 boost::make_graph_attributes_writer( graph_attr, vertex_attr, edge_attr ) ); 00103 } 00104 00105 template<typename Vertex, typename ProcessEdge, typename OutEdgeList, typename VertexList, typename EdgeList> 00106 inline void exportAsDOT( const std::string& filename, const InternalGraph<Vertex, ProcessEdge, OutEdgeList, VertexList, EdgeList>& g ) 00107 { 00108 std::ofstream ofs( filename.c_str() ); 00109 00110 exportAsDOT( ofs, g ); 00111 } 00112 00113 namespace detail { 00114 template <class Graph> 00115 struct debug_node_writer 00116 { 00117 debug_node_writer( const Graph& graph ) : _graph( graph ) {} 00118 template <class VertexOrEdge> 00119 void operator()( std::ostream& out, const VertexOrEdge& vd ) const 00120 { 00121 _graph.instance(vd).exportDotDebug(out); 00122 } 00123 const Graph& _graph; 00124 }; 00125 } 00126 00127 template<class Graph> 00128 inline detail::debug_node_writer<Graph> make_debug_node_writer( const Graph g ) 00129 { 00130 return detail::debug_node_writer<Graph>( g ); 00131 } 00132 00133 template<typename Vertex, typename ProcessEdge, typename OutEdgeList, typename VertexList, typename EdgeList> 00134 inline void exportDebugAsDOT( std::ostream& os, const InternalGraph<Vertex, ProcessEdge, OutEdgeList, VertexList, EdgeList>& g ) 00135 { 00136 std::map<std::string, std::string> graph_attr, vertex_attr, edge_attr; 00137 graph_attr["size"] = "6,6"; 00138 graph_attr["rankdir"] = "LR"; 00139 graph_attr["ratio"] = "fill"; 00140 graph_attr["label"] = "TuttleOFX"; 00141 vertex_attr["shape"] = "circle"; 00142 vertex_attr["color"] = "dodgerblue4"; 00143 vertex_attr["fontcolor"] = "dodgerblue4"; 00144 edge_attr["style"] = "dashed"; 00145 edge_attr["minlen"] = "1"; 00146 edge_attr["color"] = "darkslategray"; 00147 edge_attr["fontcolor"] = "darkslategray"; 00148 00149 using namespace boost; 00150 boost::write_graphviz( os, 00151 g.getGraph(), 00152 make_debug_node_writer(g), 00153 make_debug_node_writer(g), 00154 boost::make_graph_attributes_writer( graph_attr, vertex_attr, edge_attr ) ); 00155 } 00156 00157 template<typename Vertex, typename ProcessEdge, typename OutEdgeList, typename VertexList, typename EdgeList> 00158 inline void exportDebugAsDOT( const std::string& filename, const InternalGraph<Vertex, ProcessEdge, OutEdgeList, VertexList, EdgeList>& g ) 00159 { 00160 std::ofstream ofs( filename.c_str() ); 00161 00162 exportDebugAsDOT( ofs, g ); 00163 } 00164 00165 } 00166 } 00167 } 00168