TuttleOFX  1
OfxhParam.hpp
Go to the documentation of this file.
00001 #ifndef _TUTTLE_HOST_OFX_PARAM_HPP_
00002 #define _TUTTLE_HOST_OFX_PARAM_HPP_
00003 
00004 #include "OfxhAttribute.hpp"
00005 #include "OfxhParamAccessor.hpp"
00006 
00007 /* Definitions used by setInterpolator() for animated params
00008    These are TuttleOFX specific */
00009 #include <tuttle/host/attribute/ValueInterpolator.hpp>
00010 
00011 #include <tuttle/host/ofx/OfxhCore.hpp>
00012 #include <tuttle/host/ofx/OfxhException.hpp>
00013 #include <tuttle/host/ofx/OfxhIObject.hpp>
00014 
00015 #include <tuttle/host/ofx/property/OfxhSet.hpp>
00016 #include <tuttle/host/ofx/property/OfxhGetHook.hpp>
00017 #include <tuttle/host/ofx/property/OfxhNotifyHook.hpp>
00018 
00019 #include <string>
00020 
00021 #define TUTTLE_DEFINE_OFXHPARAM_ACCESSORS( NAME, TYPE ) \
00022         protected: \
00023                 inline virtual void getValue( TYPE& ) const OFX_EXCEPTION_SPEC \
00024                 { \
00025                         BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrBadHandle, "\"" + this->getName() + "\"" + " is not a " # NAME " parameter (" + this->getParamType() + ")." ) ); \
00026                 } \
00027                 inline virtual void getValueAtTime( const OfxTime, TYPE& ) const OFX_EXCEPTION_SPEC \
00028                 { \
00029                         BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrBadHandle, "\"" + this->getName() + "\"" + " is not a " # NAME " parameter (" + this->getParamType() + ")." ) ); \
00030                 } \
00031                 inline virtual void getValueAtIndex( const std::size_t, TYPE& ) const OFX_EXCEPTION_SPEC \
00032                 { \
00033                         BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrBadHandle, "\"" + this->getName() + "\"" + " is not a " # NAME " multidimentional parameter (" + this->getParamType() + ")." ) ); \
00034                 } \
00035                 inline virtual void getValueAtTimeAndIndex( const OfxTime, const std::size_t, TYPE& ) const OFX_EXCEPTION_SPEC \
00036                 { \
00037                         BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrBadHandle, "\"" + this->getName() + "\"" + " is not a " # NAME " multidimentional parameter (" + this->getParamType() + ")." ) ); \
00038                 } \
00039         public: \
00040                 inline TYPE get ## NAME ## ValueAtIndex( const std::size_t index ) const OFX_EXCEPTION_SPEC \
00041                 { \
00042                         TYPE dst; \
00043                         getValueAtIndex( index, dst ); \
00044                         return dst; \
00045                 } \
00046                 inline TYPE get ## NAME ## ValueAtTimeAndIndex( const OfxTime time, const std::size_t index ) const OFX_EXCEPTION_SPEC \
00047                 { \
00048                         TYPE dst; \
00049                         getValueAtTimeAndIndex( time, index, dst ); \
00050                         return dst; \
00051                 } \
00052                 inline TYPE get ## NAME ## Value() const OFX_EXCEPTION_SPEC \
00053                 { \
00054                         TYPE dst; \
00055                         getValue( dst ); \
00056                         return dst; \
00057                 } \
00058                 inline TYPE get ## NAME ## ValueAtTime( const OfxTime time ) const OFX_EXCEPTION_SPEC \
00059                 { \
00060                         TYPE dst; \
00061                         getValueAtTime( time, dst ); \
00062                         return dst; \
00063                 } \
00064                 inline virtual void setValue( const TYPE& value, const EChange change ) OFX_EXCEPTION_SPEC { BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrBadHandle, "\"" + this->getName() + "\"" + " is not a " # NAME " parameter (" + this->getParamType() + ", " + mapChangeEnumToString( change ) + ")." ) ); } \
00065                 inline virtual void setValue( const TYPE& value ) OFX_EXCEPTION_SPEC { setValue( value, eChangeUserEdited ); } \
00066                 inline virtual void setValueAtTime( const OfxTime time, const TYPE& value, const EChange change ) OFX_EXCEPTION_SPEC { BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrBadHandle, "\"" + this->getName() + "\"" + " is not a " # NAME " parameter (" + this->getParamType() + ", " + mapChangeEnumToString( change ) + ")." ) ); } \
00067                 inline virtual void setValueAtTime( const OfxTime time, const TYPE& value ) OFX_EXCEPTION_SPEC { setValueAtTime( time, value, eChangeUserEdited ); } \
00068                 inline virtual void setValueAtIndex( const std::size_t index, const TYPE& value, const EChange change ) OFX_EXCEPTION_SPEC { BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrBadHandle, "\"" + this->getName() + "\"" + " is not a multi-" # NAME " parameter (" + this->getParamType() + ", " + mapChangeEnumToString( change ) + ")." ) ); } \
00069                 inline virtual void setValueAtIndex( const std::size_t index, const TYPE& value ) OFX_EXCEPTION_SPEC { setValueAtIndex( index, value, eChangeUserEdited ); } \
00070                 inline virtual void setValueAtTimeAndIndex( const OfxTime time, const std::size_t index, const TYPE& value, const EChange change ) OFX_EXCEPTION_SPEC { BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrBadHandle, "\"" + this->getName() + "\"" + " is not a multi-" # NAME " parameter (" + this->getParamType() + ", " + mapChangeEnumToString( change ) + ")." ) ); } \
00071                 inline virtual void setValueAtTimeAndIndex( const OfxTime time, const std::size_t index, const TYPE& value ) OFX_EXCEPTION_SPEC { setValueAtTimeAndIndex( time, index, value, eChangeUserEdited ); } \
00072                 \
00073                 inline virtual void setValue( const std::vector<TYPE>& values, const EChange change ) OFX_EXCEPTION_SPEC \
00074                 { BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrBadHandle, "\"" + this->getName() + "\"" + " is not a multi-" # NAME " parameter (" + this->getParamType() + ", " + mapChangeEnumToString( change ) + ")." ) ); } \
00075                 inline virtual void setValue( const std::vector<TYPE>& values ) OFX_EXCEPTION_SPEC { setValue( values, eChangeUserEdited ); } \
00076                 inline virtual void setValueAtTime( const OfxTime time, const std::vector<TYPE>& values, const EChange change ) OFX_EXCEPTION_SPEC \
00077                 { BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrBadHandle, "\"" + this->getName() + "\"" + " is not a multi-" # NAME " parameter (" + this->getParamType() + ", " + mapChangeEnumToString( change ) + ")." ) ); } \
00078                 inline virtual void setValueAtTime( const OfxTime time, const std::vector<TYPE>& values ) OFX_EXCEPTION_SPEC { setValueAtTime( time, values, eChangeUserEdited ); } \
00079 //
00080 
00081 
00082 #define TUTTLE_DEFINE_OFXHPARAM_MULTIDIM_ACCESSORS( NAME, TYPE ) \
00083                 inline virtual void setValue( const TYPE& value1, const TYPE& value2, const EChange change ) OFX_EXCEPTION_SPEC { BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrBadHandle, "\"" + this->getName() + "\"" + " is not a multi-" # NAME " parameter (2) (" + this->getParamType() + ", " + mapChangeEnumToString( change ) + ")." ) ); } \
00084                 inline virtual void setValue( const TYPE& value1, const TYPE& value2 ) OFX_EXCEPTION_SPEC { setValue( value1, value2, eChangeUserEdited ); } \
00085                 inline virtual void setValueAtTime( const OfxTime time, const TYPE& value1, const TYPE& value2, const EChange change ) OFX_EXCEPTION_SPEC { BOOST_THROW_EXCEPTION( OfxhException( "\"" + this->getName() + "\"" + " is not a multi-" # NAME " parameter (2) (" + this->getParamType() + ", " + mapChangeEnumToString( change ) + ")." ) ); } \
00086                 inline virtual void setValueAtTime( const OfxTime time, const TYPE& value1, const TYPE& value2 ) OFX_EXCEPTION_SPEC { setValueAtTime( time, value1, value2, eChangeUserEdited ); } \
00087                 \
00088                 inline virtual void setValue( const TYPE& value1, const TYPE& value2, const TYPE& value3, const EChange change ) OFX_EXCEPTION_SPEC { BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrBadHandle, "\"" + this->getName() + "\"" + " is not a multi-" # NAME " parameter (3) (" + this->getParamType() + ", " + mapChangeEnumToString( change ) + ")." ) ); } \
00089                 inline virtual void setValue( const TYPE& value1, const TYPE& value2, const TYPE& value3 ) OFX_EXCEPTION_SPEC { setValue( value1, value2, value3, eChangeUserEdited ); } \
00090                 inline virtual void setValueAtTime( const OfxTime time, const TYPE& value1, const TYPE& value2, const TYPE& value3, const EChange change ) OFX_EXCEPTION_SPEC { BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrBadHandle, "\"" + this->getName() + "\"" + " is not a " # NAME " parameter (3) (" + this->getParamType() + ", " + mapChangeEnumToString( change ) + ")." ) ); } \
00091                 inline virtual void setValueAtTime( const OfxTime time, const TYPE& value1, const TYPE& value2, const TYPE& value3 ) OFX_EXCEPTION_SPEC { setValueAtTime( time, value1, value2, value3, eChangeUserEdited ); } \
00092                 \
00093                 inline virtual void setValue( const TYPE& value1, const TYPE& value2, const TYPE& value3, const TYPE& value4, const EChange change ) OFX_EXCEPTION_SPEC { BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrBadHandle, "\"" + this->getName() + "\"" + " is not a multi-" # NAME " parameter (4) (" + this->getParamType() + ", " + mapChangeEnumToString( change ) + ")." ) ); } \
00094                 inline virtual void setValue( const TYPE& value1, const TYPE& value2, const TYPE& value3, const TYPE& value4 ) OFX_EXCEPTION_SPEC { setValue( value1, value2, value3, value4, eChangeUserEdited ); } \
00095                 inline virtual void setValueAtTime( const OfxTime time, const TYPE& value1, const TYPE& value2, const TYPE& value3, const TYPE& value4, const EChange change ) OFX_EXCEPTION_SPEC { BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrBadHandle, "\"" + this->getName() + "\"" + " is not a " # NAME " parameter (4) (" + this->getParamType() + ", " + mapChangeEnumToString( change ) + ")." ) ); } \
00096                 inline virtual void setValueAtTime( const OfxTime time, const TYPE& value1, const TYPE& value2, const TYPE& value3, const TYPE& value4 ) OFX_EXCEPTION_SPEC { setValueAtTime( time, value1, value2, value3, value4, eChangeUserEdited ); } \
00097 //
00098 
00099 namespace tuttle {
00100 namespace host {
00101 namespace ofx {
00102 namespace attribute {
00103 
00104 
00105 /* Specify the type of interpolator to use with animated params */
00106 enum EInterpolatorType
00107 {
00108   eLinearInterpolator,
00109   eSmoothInterpolator,
00110   eFastInterpolator,
00111   eSlowInterpolator,
00112 };
00113 
00114 class OfxhParamDescriptor;
00115 class OfxhParamSet;
00116 
00117 /// plugin parameter instance
00118 class OfxhParam
00119         : public OfxhAttribute
00120         , virtual public OfxhParamAccessor
00121         , protected property::OfxhNotifyHook
00122         , private boost::noncopyable
00123 {
00124 OfxhParam();
00125 
00126 public:
00127         typedef OfxhParam This;
00128 
00129 protected:
00130         OfxhParamSet*  _paramSetInstance;
00131         OfxhParam*     _parentInstance;
00132         bool _avoidRecursion;               ///< Avoid recursion when updating with paramChangedAction
00133 
00134 protected:
00135         OfxhParam( const OfxhParam& other )
00136                 : OfxhAttribute( other )
00137                 , _paramSetInstance( other._paramSetInstance )
00138                 , _parentInstance( other._parentInstance )
00139                 , _avoidRecursion( false )
00140         {
00141                 /// @todo tuttle : copy content, not pointer ?
00142         }
00143 
00144 public:
00145         /// make a parameter, with the given type and name
00146         explicit OfxhParam( const OfxhParamDescriptor& descriptor, const std::string& name, OfxhParamSet& setInstance );
00147 
00148         virtual ~OfxhParam() = 0;
00149 
00150         /// clone this parameter
00151         virtual This* clone() const = 0;
00152 
00153         virtual bool paramTypeHasData() const = 0;
00154 
00155         virtual std::size_t getHashAtTime( const OfxTime time ) const = 0;
00156 
00157         /**
00158          * @todo tuttle: check values !!!
00159          */
00160         bool operator==( const This& p ) const { return true; }
00161 
00162         /// grab a handle on the parameter for passing to the C API
00163         OfxParamHandle getParamHandle() const
00164         {
00165                 return ( OfxParamHandle ) this;
00166         }
00167 
00168         friend std::ostream& operator<<( std::ostream& os, const This& g );
00169         virtual std::ostream& displayValues( std::ostream& os ) const { return os; }
00170 
00171         #ifdef SWIG
00172         %extend
00173         {
00174                 ofx::property::OfxhProperty& __getitem__( const std::string& name )
00175                 {
00176                         return self->getEditableProperties().fetchLocalProperty( name );
00177                 }
00178 
00179                 std::string __str__() const
00180                 {
00181                         std::stringstream s;
00182 
00183                         s << *self;
00184                         return s.str();
00185                 }
00186 
00187         }
00188         #endif
00189 
00190         void paramChanged( const EChange change );
00191 
00192         #ifndef SWIG
00193         void changedActionBegin()            { _avoidRecursion = true; }
00194         void changedActionEnd()              { _avoidRecursion = false; }
00195         bool changedActionInProgress() const { return _avoidRecursion; }
00196 
00197         // get the param instance
00198         OfxhParamSet* getParamSetInstance()                         { return _paramSetInstance; }
00199         void          setParamSetInstance( OfxhParamSet* instance ) { _paramSetInstance = instance; }
00200 
00201         // set/get parent instance
00202         void       setParentInstance( OfxhParam* instance );
00203         OfxhParam* getParentInstance();
00204 
00205         // copy one parameter to another
00206         virtual void copy( const OfxhParam& instance ) OFX_EXCEPTION_SPEC = 0;
00207 
00208         // copy one parameter to another
00209         virtual void copy( const OfxhParam& instance, OfxTime offset ) OFX_EXCEPTION_SPEC;
00210 
00211         // copy one parameter to another, with a range
00212         virtual void copy( const OfxhParam& instance, OfxTime offset, OfxRangeD range ) OFX_EXCEPTION_SPEC;
00213 
00214         // callback which should set enabled state as appropriate
00215         virtual void setEnabled();
00216 
00217         // callback which should set secret state as appropriate
00218         virtual void setSecret();
00219 
00220         /// callback which should update label
00221         virtual void setLabel();
00222 
00223         /// callback which should set
00224         virtual void setDisplayRange();
00225 
00226         // va list calls below turn the var args (oh what a mistake)
00227         // suite functions into virtual function calls on instances
00228         // they are not to be overridden by host implementors by
00229         // by the various typeed param instances so that they can
00230         // deconstruct the var args lists
00231 
00232         #endif
00233         inline virtual std::size_t getSize() const
00234         {
00235                 return 1;
00236         }
00237 
00238         TUTTLE_DEFINE_OFXHPARAM_ACCESSORS( String, std::string );
00239         TUTTLE_DEFINE_OFXHPARAM_ACCESSORS( Double, double );
00240         TUTTLE_DEFINE_OFXHPARAM_ACCESSORS( Int, int );
00241         TUTTLE_DEFINE_OFXHPARAM_ACCESSORS( Bool, bool );
00242 
00243 #ifndef SWIG
00244         TUTTLE_DEFINE_OFXHPARAM_MULTIDIM_ACCESSORS( String, std::string );
00245         TUTTLE_DEFINE_OFXHPARAM_MULTIDIM_ACCESSORS( Double, double );
00246         TUTTLE_DEFINE_OFXHPARAM_MULTIDIM_ACCESSORS( Int, int );
00247         TUTTLE_DEFINE_OFXHPARAM_MULTIDIM_ACCESSORS( Bool, bool );
00248 #endif
00249 
00250         virtual void setValueFromExpression( const std::string& value, const EChange change ) OFX_EXCEPTION_SPEC { BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrMissingHostFeature, "\"" + this->getName() + "Can't set value from expression on parameter \"" + this->getName() + "\", it's not supported for " + this->getParamType() + " parameters (" + this->getParamType() + ", " + mapChangeEnumToString( change ) + ")." ) ); }
00251         inline void setValueFromExpression( const std::string& value ) OFX_EXCEPTION_SPEC { setValueFromExpression( value, eChangeUserEdited ); }
00252 
00253         inline void setValue( const char* value, const EChange change ) OFX_EXCEPTION_SPEC                                      { setValue( std::string( value ), change ); }
00254         inline void setValue( const char* value ) OFX_EXCEPTION_SPEC                                                            { setValue( value, eChangeUserEdited ); }
00255         inline void setValueAtTime( const OfxTime time, const char* value, const attribute::EChange change ) OFX_EXCEPTION_SPEC { setValueAtTime( time, std::string( value ), change ); }
00256         inline void setValueAtTime( const OfxTime time, const char* value ) OFX_EXCEPTION_SPEC                                  { setValueAtTime( time, value, eChangeUserEdited ); }
00257 
00258         /* TuttleOFX specific. This is not part of OFX.
00259 
00260            It must be in the OfxhParam base class in order to be exposed by the API. */
00261         virtual void setInterpolator(const enum EInterpolatorType etype) OFX_EXCEPTION_SPEC {
00262             BOOST_THROW_EXCEPTION( ofx::OfxhException( kOfxStatErrMissingHostFeature ) );
00263         }
00264 
00265         #ifndef SWIG
00266         /// get a value, implemented by instances to deconstruct var args
00267         virtual void getV( va_list arg ) const OFX_EXCEPTION_SPEC;
00268 
00269         /// get a value, implemented by instances to deconstruct var args
00270         virtual void getV( const OfxTime time, va_list arg ) const OFX_EXCEPTION_SPEC;
00271 
00272         /// set a value, implemented by instances to deconstruct var args
00273         virtual void setV( va_list arg, const EChange change ) OFX_EXCEPTION_SPEC;
00274 
00275         /// key a value, implemented by instances to deconstruct var args
00276         virtual void setV( const OfxTime time, va_list arg, const EChange change ) OFX_EXCEPTION_SPEC;
00277 
00278         /// derive a value, implemented by instances to deconstruct var args
00279         virtual void deriveV( const OfxTime time, va_list arg ) const OFX_EXCEPTION_SPEC;
00280 
00281         /// integrate a value, implemented by instances to deconstruct var args
00282         virtual void integrateV( const OfxTime time1, const OfxTime time2, va_list arg ) const OFX_EXCEPTION_SPEC;
00283 
00284         /// overridden from Property::NotifyHook
00285         virtual void notify( const std::string& name, bool single, int num ) OFX_EXCEPTION_SPEC;
00286         #endif
00287 };
00288 
00289 #ifndef SWIG
00290 /**
00291  * @brief to make ParamInstance clonable (for use in boost::ptr_container)
00292  */
00293 inline OfxhParam* new_clone( const OfxhParam& a )
00294 {
00295         return a.clone();
00296 }
00297 
00298 #endif
00299 
00300 }
00301 }
00302 }
00303 }
00304 
00305 #ifndef SWIG
00306 // force boost::is_virtual_base_of value (used by boost::serialization)
00307 namespace boost {
00308 template<>
00309 struct is_virtual_base_of<tuttle::host::ofx::attribute::OfxhAttribute, tuttle::host::ofx::attribute::OfxhParam>: public mpl::true_ {};
00310 }
00311 #endif
00312 
00313 #endif