TuttleOFX
1
|
00001 #ifndef _TUTTLE_HOST_CORE_GRAPH_HPP_ 00002 #define _TUTTLE_HOST_CORE_GRAPH_HPP_ 00003 00004 #include "NodeListArg.hpp" 00005 #include "ComputeOptions.hpp" 00006 #include "Core.hpp" 00007 #include "INode.hpp" 00008 #include "InputBufferWrapper.hpp" 00009 #include "OutputBufferWrapper.hpp" 00010 #include "exceptions.hpp" 00011 00012 #include <tuttle/host/graph/InternalGraph.hpp> 00013 #include <tuttle/host/graph/UVertex.hpp> 00014 #include <tuttle/host/graph/UEdge.hpp> 00015 #include <tuttle/host/NodeAtTimeKey.hpp> 00016 #include <tuttle/host/NodeHashContainer.hpp> 00017 #include <tuttle/host/attribute/Attribute.hpp> 00018 #include <tuttle/host/memory/MemoryCache.hpp> 00019 #include <tuttle/common/utils/global.hpp> 00020 00021 #include <boost/ptr_container/ptr_map.hpp> 00022 00023 #include <stdexcept> 00024 #include <string> 00025 #include <sstream> 00026 #include <map> 00027 #include <list> 00028 00029 namespace tuttle { 00030 namespace host { 00031 00032 class NodeInit; 00033 00034 /** 00035 * @brief A user graph to manipulate OpenFX nodes. 00036 */ 00037 class Graph 00038 { 00039 public: 00040 typedef graph::UVertex Vertex; 00041 typedef graph::UEdge Edge; 00042 typedef INode Node; /// @todo tuttle INode... 00043 typedef attribute::Attribute Attribute; 00044 typedef graph::InternalGraph<Vertex, Edge> InternalGraphImpl; 00045 typedef InternalGraphImpl::vertex_descriptor vertex_descriptor; 00046 typedef InternalGraphImpl::edge_descriptor edge_descriptor; 00047 00048 typedef std::map<std::string, int> InstanceCountMap; 00049 typedef boost::ptr_map<std::string, Node> NodeMap; 00050 00051 00052 00053 public: 00054 Graph(); 00055 //Graph( const Graph& other ); 00056 ~Graph(); 00057 00058 /** 00059 * @brief Create a new input node in the current graph, 00060 * to give an input buffer. 00061 */ 00062 InputBufferWrapper createInputBuffer(); 00063 00064 /** 00065 * @brief Create a new output buffer node in the current graph, 00066 wrapped up for easy use 00067 */ 00068 OutputBufferWrapper createOutputBuffer(); 00069 00070 /** 00071 * @brief Create a new node in the graph. 00072 * @param id is the plugin unique string identification (e.g. "tuttle.blur"). 00073 */ 00074 Node& createNode( const std::string& id ); 00075 00076 /** 00077 * @brief Add a node to the graph. 00078 * It takes the ownership of the node object. 00079 * 00080 * @warning: The node will be renamed. 00081 */ 00082 Node& addNode( const NodeInit& node ); 00083 00084 /** 00085 * @brief Add a node to the graph. 00086 * It takes the ownership of the node object. 00087 * 00088 * @warning: The node will be renamed. 00089 */ 00090 Node& addNode( INode& node ); 00091 00092 /** 00093 * @brief Add nodes to the graph. 00094 * 00095 * @warning: Nodes will be renamed. 00096 */ 00097 std::vector<INode*> addNodes( const std::vector<NodeInit>& nodes ); 00098 00099 /** 00100 * @brief Add nodes to the graph and connect them linearly. 00101 * 00102 * @warning: Nodes will be renamed. 00103 */ 00104 std::vector<INode*> addConnectedNodes( const std::vector<NodeInit>& nodes ); 00105 00106 /** 00107 * @brief Rename a node in the current graph. 00108 * @param newUniqueName is the new unique node name. 00109 * 00110 * @warning you will loose all connections. 00111 */ 00112 void renameNode( Node& node, const std::string& newUniqueName ); 00113 00114 /** 00115 * @brief Delete a node from the current graph. 00116 * This will remove all the connections. 00117 */ 00118 void deleteNode( Node& node ); 00119 00120 /** 00121 * @brief Delete all unconnected nodes from the current graph. 00122 * @param node: delete all unconnected nodes from this node. 00123 * @return the number of nodes deleted. 00124 */ 00125 std::size_t deleteUnconnectedNodes( const Node& node ); 00126 00127 /** 00128 * @brief Delete all nodes from the current graph. 00129 * This will remove all the connections. 00130 */ 00131 void clear(); 00132 00133 /** 00134 * @brief Connect nodes (using there unique name in this graph). 00135 */ 00136 void connect( const std::string& outNode, const std::string& inNode, const std::string& inAttr = kOfxSimpleSourceAttributeName ); 00137 /** 00138 * @brief Connect nodes the list of nodes linearly. 00139 */ 00140 void connect( const std::list<std::string>& nodes ); 00141 void connect( const Node& outNode, const Node& inNode ); 00142 void connect( const std::list<Node*>& nodes ); 00143 void connect( const std::vector<Node*>& nodes ); 00144 void connect( const Node& outNode, const Attribute& inAttr ); 00145 void connect( const Attribute& outAttr, const Attribute& inAttr ); 00146 void unconnect( const Attribute& outAttr, const Attribute& inAttr ); 00147 00148 void unconnect( const Node& node ); 00149 00150 void replaceNodeConnections( const Node& fromNode, const Node& toNode ); 00151 00152 std::size_t getNbInputConnections( const Node& node ) const; 00153 std::size_t getNbOutputConnections( const Node& node ) const; 00154 00155 /** 00156 * @brief Temporary solution ! Prepare the user graph, so we can call getTimeDomain (and maybe others functions) on nodes. 00157 */ 00158 void init(); 00159 00160 void setup(); 00161 00162 void setupAtTime( const OfxTime time, const NodeListArg& nodes = NodeListArg() ); 00163 00164 void computeGlobalHashAtTime( NodeHashContainer& outNodesHash, const OfxTime time, const NodeListArg& nodes = NodeListArg() ); 00165 00166 bool compute( const ComputeOptions& options = ComputeOptions() ); 00167 00168 bool compute( const NodeListArg& nodes, const ComputeOptions& options = ComputeOptions() ); 00169 00170 bool compute( memory::IMemoryCache& memoryCache, const ComputeOptions& options ); 00171 00172 bool compute( 00173 memory::IMemoryCache& memoryCache, 00174 const NodeListArg& nodes = NodeListArg(), 00175 const ComputeOptions& options = ComputeOptions() ); 00176 00177 bool compute( 00178 memory::IMemoryCache& memoryCache, 00179 const NodeListArg& nodes, 00180 const ComputeOptions& options, 00181 memory::IMemoryCache& internMemoryCache ); 00182 00183 public: 00184 inline const InternalGraphImpl& getGraph() const { return _graph; } 00185 00186 inline const NodeMap& getNodesMap() const { return _nodesMap; } 00187 inline NodeMap& getNodesMap() { return _nodesMap; } 00188 00189 std::vector<const Node*> getNodes() const; 00190 std::vector<Node*> getNodes(); 00191 00192 std::vector<Node*> getConnectedNodes( const Node& node ); 00193 std::vector<Node*> getUnconnectedNodes( const Node& node ); 00194 00195 inline std::size_t getNbNodes() const { return _nodesMap.size(); } 00196 inline std::size_t getNbConnections() const { return _graph.getEdgeCount(); } 00197 00198 std::vector<Node*> getNodesByContext( const std::string& type ); 00199 std::vector<Node*> getNodesByPlugin( const std::string& pluginId ); 00200 00201 // const Node& getNode( const std::string& name ) const { return getNodesMap()[name]; } 00202 inline const Node& getNode( const std::string& name ) const { return _nodesMap.at( name ); } 00203 inline Node& getNode( const std::string& name ) { return getNodesMap().at( name ); } 00204 00205 inline const InstanceCountMap& getInstanceCount() const { return _instanceCount; } 00206 00207 public: 00208 enum EDotExportLevel { 00209 eDotExportLevelSimple, 00210 eDotExportLevelDetailed 00211 }; 00212 void exportDot( const std::string& filename, const EDotExportLevel level = eDotExportLevelSimple ) const; 00213 00214 friend std::ostream& operator<<( std::ostream& os, const Graph& g ); 00215 00216 private: 00217 InternalGraphImpl _graph; 00218 NodeMap _nodesMap; 00219 InstanceCountMap _instanceCount; ///< used to assign a unique name to each node 00220 00221 private: 00222 void addToInternalGraph( Node& node ); 00223 void removeFromInternalGraph( Node& node ); 00224 }; 00225 00226 } 00227 } 00228 00229 #endif 00230