TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/host/INode.hpp
Go to the documentation of this file.
00001 #ifndef _TUTTLE_HOST_INODE_HPP_
00002 #define _TUTTLE_HOST_INODE_HPP_
00003 
00004 #include <tuttle/host/exceptions.hpp>
00005 
00006 #include <ofxCore.h>
00007 #include <ofxAttribute.h>
00008 #include <tuttle/host/Callback.hpp>
00009 
00010 #include <boost/noncopyable.hpp>
00011 
00012 #include <iostream>
00013 #include <string>
00014 #include <vector>
00015 #include <set>
00016 #include <map>
00017 
00018 namespace tuttle {
00019 namespace host {
00020 
00021 class Callback;
00022 
00023 namespace ofx {
00024 namespace attribute {
00025 class OfxhParam;
00026 class OfxhParamSet;
00027 class OfxhClipImageSet;
00028 }
00029 namespace property{
00030 class OfxhSet;
00031 }
00032 }
00033 namespace attribute {
00034 class Attribute;
00035 class Clip;
00036 class ClipImage;
00037 }
00038 namespace graph {
00039 class ProcessVertexAtTimeData;
00040 class ProcessVertexData;
00041 class ProcessVertexAtTimeInfo;
00042 }
00043 
00044 class ImageEffectNode;
00045 
00046 
00047 class INode : private boost::noncopyable
00048 {
00049 public:
00050         typedef INode This;
00051         
00052         typedef std::set<OfxTime> TimesSet;
00053         typedef std::map<std::string, TimesSet> ClipTimesSetMap;
00054         
00055         enum ENodeType
00056         {
00057                 eNodeTypeUnknown,
00058                 eNodeTypeImageEffect,
00059                 eNodeTypeParam,
00060                 eNodeTypeGraph,
00061                 eNodeTypeBuffer,
00062         };
00063         
00064 public:
00065         INode()
00066                 : _data(NULL)
00067                 , _beforeRenderCallback(0)
00068         {}
00069         INode( const INode& e )
00070                 : _data(NULL)
00071                 , _beforeRenderCallback(0)
00072         {}
00073         
00074         virtual ~INode();
00075         virtual INode* clone() const = 0;
00076         virtual bool operator==( const INode& ) const = 0;
00077         
00078         virtual const std::string& getName() const = 0;
00079         virtual void setName( const std::string& name ) = 0;
00080         virtual const ENodeType    getNodeType() const = 0;
00081 
00082         ImageEffectNode& asImageEffectNode();
00083         const ImageEffectNode& asImageEffectNode() const;
00084 
00085         virtual std::vector<int> getVersion() const = 0;
00086         std::string getVersionStr() const;
00087         
00088         virtual std::string getLabel() const = 0;
00089 
00090         virtual const ofx::property::OfxhSet& getProperties() const = 0;
00091         virtual ofx::property::OfxhSet&       getEditableProperties() = 0;
00092 
00093         virtual attribute::Attribute& getAttribute( const std::string& name ) = 0;
00094         const attribute::Attribute& getAttribute( const std::string& name ) const { return const_cast<INode*>(this)->getAttribute( name ); }
00095         virtual attribute::Attribute&       getSingleInputAttribute()       = 0;
00096         virtual const attribute::Attribute& getSingleInputAttribute() const = 0;
00097         
00098         virtual std::size_t getNbParams() const = 0;
00099         virtual const ofx::attribute::OfxhParam& getParam( const std::string& name ) const = 0;
00100         virtual ofx::attribute::OfxhParam&       getParam( const std::string& name ) = 0;
00101         virtual const ofx::attribute::OfxhParam& getParamByScriptName( const std::string& name, const bool acceptPartialName = false ) const = 0;
00102         virtual ofx::attribute::OfxhParam&       getParamByScriptName( const std::string& name, const bool acceptPartialName = false ) = 0;
00103         virtual const ofx::attribute::OfxhParam& getParam( const std::size_t  index ) const = 0;
00104         virtual ofx::attribute::OfxhParam&       getParam( const std::size_t  index ) = 0;
00105 
00106         virtual attribute::ClipImage&       getClip( const std::string& name, const bool acceptPartialName = false ) = 0;
00107         virtual const attribute::ClipImage& getClip( const std::string& name, const bool acceptPartialName = false ) const = 0;
00108 
00109         attribute::ClipImage&       getOutputClip()       { return getClip( kOfxImageEffectOutputClipName ); }
00110         const attribute::ClipImage& getOutputClip() const { return getClip( kOfxImageEffectOutputClipName ); }
00111 
00112         virtual ofx::attribute::OfxhParamSet& getParamSet() = 0;
00113         virtual const ofx::attribute::OfxhParamSet& getParamSet() const = 0;
00114 
00115         virtual ofx::attribute::OfxhClipImageSet& getClipImageSet() = 0;
00116         virtual const ofx::attribute::OfxhClipImageSet& getClipImageSet() const = 0;
00117 
00118         virtual std::size_t getLocalHashAtTime( const OfxTime time ) const = 0;
00119 
00120 
00121 
00122 #ifndef SWIG
00123         virtual void connect( const INode&, attribute::Attribute& ) = 0;
00124 
00125         virtual void setup1() = 0;
00126         virtual void setup2_reverse() = 0;
00127         virtual void setup3() = 0;
00128         
00129         virtual OfxRangeD computeTimeDomain() = 0;
00130 
00131 //      virtual OfxTime mapInputTime( const OfxTime time ) const = 0;
00132         
00133         virtual OfxRangeD getTimeDomain() const = 0;
00134         
00135         /**
00136          * @brief Begin of the a new frame range to process. Initilize this node.
00137          * @param[in] processData
00138          * @remark called on each node without predefined order.
00139          */
00140         virtual void beginSequence( graph::ProcessVertexData& processData ) = 0;
00141 
00142         /**
00143          * @brief Asks the plugin all times it needs for each of it's input clips.
00144          * @param[in] time
00145          */
00146         virtual ClipTimesSetMap getTimesNeeded( const OfxTime time ) const = 0;
00147 
00148         /**
00149          * @brief Initialization pass to propagate informations from inputs to outputs.
00150          * @param[in] processData
00151          * @remark Called on each node in a depth first search order. So you have the guarantee that it has been called on each input nodes before.
00152          */
00153         virtual void preProcess1( graph::ProcessVertexAtTimeData& processData ) {}
00154         
00155         /**
00156          * @brief Initialization pass to propagate informations from outputs to inputs.
00157          * @param[in] processData
00158          * @remark Called on each node in a REVERSE depth first search order. So you have the guarantee that it has been called on each output nodes before. Output nodes are those who used the result of the current node.
00159          */
00160         virtual void preProcess2_reverse( graph::ProcessVertexAtTimeData& processData ) {}
00161 
00162         /**
00163          * @brief The node can declare to be an identity operation.
00164          * In this case, the node is not processed and the rendering engine direcly use the indicated input clip at a particular time.
00165          *
00166          * @param[in] processData
00167          * @param[out] clip the input clip to use as identity
00168          * @param[out] time the time to use as identity
00169          * @return if the node is an identity operation
00170          */
00171         virtual bool isIdentity( const graph::ProcessVertexAtTimeData& processData, std::string& clip, OfxTime& time ) const = 0;
00172         
00173         /**
00174          * @brief Fill ProcessInfo to compute statistics for the current process,
00175          *        like memory used by this node, by all input nodes, etc.
00176          * @param[in] processData
00177          * @remark Called on each node in a depth first search order. So you have the guarantee that it has been called on each input nodes before.
00178          */
00179         virtual void preProcess_infos( const graph::ProcessVertexAtTimeData& processData, const OfxTime time, graph::ProcessVertexAtTimeInfo& nodeInfos ) const = 0;
00180 
00181         /**
00182          * @brief Process this node. All inputs are compute.
00183          * @param[in] processData
00184          * @remark Called on each node in a depth first search order. So you have the guarantee that it has been called on each input nodes before.
00185          */
00186         virtual void process( graph::ProcessVertexAtTimeData& processData ) = 0;
00187 
00188         /**
00189          * @brief The process of all nodes is done for one frame, now finalize this node.
00190          * @param[in] processData
00191          * @remark Called on each node in a depth first search order. So you have the guarantee that it has been called on each input nodes before.
00192          */
00193         virtual void postProcess( graph::ProcessVertexAtTimeData& processData ) = 0;
00194 
00195         /**
00196          * @brief End of the whole frame range process, now finalize this node.
00197          * @param[in] processData
00198          * @remark called on each node without predefined order.
00199          */
00200         virtual void endSequence( graph::ProcessVertexData& processData ) = 0;
00201 
00202 
00203 
00204 #endif
00205 
00206     /** 
00207      * Callback triggered before the render. The Node does not own the callback
00208      * so the client has to set the callback to null and destroy it.
00209      */
00210     void setBeforeRenderCallback(Callback *cb);
00211 
00212         virtual std::ostream& print( std::ostream& os ) const = 0;
00213 
00214         friend std::ostream& operator<<( std::ostream& os, const This& v );
00215 
00216 #ifndef SWIG
00217         typedef graph::ProcessVertexData Data;
00218         typedef graph::ProcessVertexAtTimeData DataAtTime;
00219         typedef std::map<OfxTime,DataAtTime*> DataAtTimeMap;
00220 
00221     // Callbacks hidden from Swig and with the DataAtTime definition available
00222     void beforeRenderCallback(INode &, DataAtTime &);
00223     Callback *_beforeRenderCallback;
00224 
00225 protected:
00226         Data* _data; ///< link to external datas
00227         DataAtTimeMap _dataAtTime; ///< link to external datas at each time
00228 
00229 public:
00230         void setProcessData( Data* data );
00231         void setProcessDataAtTime( DataAtTime* dataAtTime );
00232         void clearProcessDataAtTime();
00233         
00234         Data& getData();
00235         const Data& getData() const;
00236         
00237         bool hasData( const OfxTime time ) const;
00238         const DataAtTime& getData( const OfxTime time ) const;
00239         const DataAtTime& getFirstData() const;
00240         const DataAtTime& getLastData() const; 
00241         DataAtTime& getData( const OfxTime time );
00242         DataAtTime& getFirstData();
00243         DataAtTime& getLastData();
00244 #endif
00245 };
00246 
00247 
00248 #ifndef SWIG
00249 /**
00250  * @brief to make clonable for use in boost::ptr_container.
00251  */
00252 inline INode* new_clone( const INode& a )
00253 {
00254         return a.clone();
00255 }
00256 
00257 #endif
00258 
00259 inline std::string mapNodeTypeEnumToString( const INode::ENodeType e )
00260 {
00261         switch( e )
00262         {
00263                 case INode::eNodeTypeUnknown:
00264                         return "Unknown";
00265                 case INode::eNodeTypeImageEffect:
00266                         return "ImageEffect";
00267                 case INode::eNodeTypeParam:
00268                         return "Param";
00269                 case INode::eNodeTypeGraph:
00270                         return "Graph";
00271                 case INode::eNodeTypeBuffer:
00272                         return "Buffer";
00273         }
00274         BOOST_THROW_EXCEPTION( exception::Bug()
00275                 << exception::dev() + "Unrecognized ENodeType enum. (" + e + ")." );
00276 }
00277 
00278 
00279 }
00280 }
00281 
00282 #endif
00283