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