TuttleOFX  1
Graph.hpp
Go to the documentation of this file.
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