TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/host/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 
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