TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/host/ofx/attribute/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 #ifndef SWIG
00151         /// clone this parameter
00152         virtual This* clone() const = 0;
00153 #endif
00154 
00155         virtual bool paramTypeHasData() const = 0;
00156 
00157         virtual std::size_t getHashAtTime( const OfxTime time ) const = 0;
00158 
00159         /**
00160          * @todo tuttle: check values !!!
00161          */
00162         bool operator==( const This& p ) const { return true; }
00163 
00164         /// grab a handle on the parameter for passing to the C API
00165         OfxParamHandle getParamHandle() const
00166         {
00167                 return ( OfxParamHandle ) this;
00168         }
00169 
00170         friend std::ostream& operator<<( std::ostream& os, const This& g );
00171         virtual std::ostream& displayValues( std::ostream& os ) const { return os; }
00172 
00173         #ifdef SWIG
00174         %extend
00175         {
00176                 ofx::property::OfxhProperty& __getitem__( const std::string& name )
00177                 {
00178                         return self->getEditableProperties().fetchLocalProperty( name );
00179                 }
00180 
00181                 std::string __str__() const
00182                 {
00183                         std::stringstream s;
00184 
00185                         s << *self;
00186                         return s.str();
00187                 }
00188 
00189         }
00190         #endif
00191 
00192         void paramChanged( const EChange change );
00193 
00194         #ifndef SWIG
00195         void changedActionBegin()            { _avoidRecursion = true; }
00196         void changedActionEnd()              { _avoidRecursion = false; }
00197         bool changedActionInProgress() const { return _avoidRecursion; }
00198 
00199         // get the param instance
00200         OfxhParamSet* getParamSetInstance()                         { return _paramSetInstance; }
00201         void          setParamSetInstance( OfxhParamSet* instance ) { _paramSetInstance = instance; }
00202 
00203         // set/get parent instance
00204         void       setParentInstance( OfxhParam* instance );
00205         OfxhParam* getParentInstance();
00206 
00207         // copy one parameter to another
00208         virtual void copy( const OfxhParam& instance ) OFX_EXCEPTION_SPEC = 0;
00209 
00210         // copy one parameter to another
00211         virtual void copy( const OfxhParam& instance, OfxTime offset ) OFX_EXCEPTION_SPEC;
00212 
00213         // copy one parameter to another, with a range
00214         virtual void copy( const OfxhParam& instance, OfxTime offset, OfxRangeD range ) OFX_EXCEPTION_SPEC;
00215 
00216         // callback which should set enabled state as appropriate
00217         virtual void setEnabled();
00218 
00219         // callback which should set secret state as appropriate
00220         virtual void setSecret();
00221 
00222         /// callback which should update label
00223         virtual void setLabel();
00224 
00225         /// callback which should set
00226         virtual void setDisplayRange();
00227 
00228         // va list calls below turn the var args (oh what a mistake)
00229         // suite functions into virtual function calls on instances
00230         // they are not to be overridden by host implementors by
00231         // by the various typeed param instances so that they can
00232         // deconstruct the var args lists
00233 
00234         #endif
00235         inline virtual std::size_t getSize() const
00236         {
00237                 return 1;
00238         }
00239 
00240         TUTTLE_DEFINE_OFXHPARAM_ACCESSORS( String, std::string );
00241         TUTTLE_DEFINE_OFXHPARAM_ACCESSORS( Double, double );
00242         TUTTLE_DEFINE_OFXHPARAM_ACCESSORS( Int, int );
00243         TUTTLE_DEFINE_OFXHPARAM_ACCESSORS( Bool, bool );
00244 
00245 #ifndef SWIG
00246         TUTTLE_DEFINE_OFXHPARAM_MULTIDIM_ACCESSORS( String, std::string );
00247         TUTTLE_DEFINE_OFXHPARAM_MULTIDIM_ACCESSORS( Double, double );
00248         TUTTLE_DEFINE_OFXHPARAM_MULTIDIM_ACCESSORS( Int, int );
00249         TUTTLE_DEFINE_OFXHPARAM_MULTIDIM_ACCESSORS( Bool, bool );
00250 #endif
00251 
00252         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 ) + ")." ) ); }
00253         inline void setValueFromExpression( const std::string& value ) OFX_EXCEPTION_SPEC { setValueFromExpression( value, eChangeUserEdited ); }
00254 
00255         inline void setValue( const char* value, const EChange change ) OFX_EXCEPTION_SPEC                                      { setValue( std::string( value ), change ); }
00256         inline void setValue( const char* value ) OFX_EXCEPTION_SPEC                                                            { setValue( value, eChangeUserEdited ); }
00257         inline void setValueAtTime( const OfxTime time, const char* value, const attribute::EChange change ) OFX_EXCEPTION_SPEC { setValueAtTime( time, std::string( value ), change ); }
00258         inline void setValueAtTime( const OfxTime time, const char* value ) OFX_EXCEPTION_SPEC                                  { setValueAtTime( time, value, eChangeUserEdited ); }
00259 
00260         /* TuttleOFX specific. This is not part of OFX.
00261 
00262            It must be in the OfxhParam base class in order to be exposed by the API. */
00263         virtual void setInterpolator(const enum EInterpolatorType etype) OFX_EXCEPTION_SPEC {
00264             BOOST_THROW_EXCEPTION( ofx::OfxhException( kOfxStatErrMissingHostFeature ) );
00265         }
00266 
00267         #ifndef SWIG
00268         /// get a value, implemented by instances to deconstruct var args
00269         virtual void getV( va_list arg ) const OFX_EXCEPTION_SPEC;
00270 
00271         /// get a value, implemented by instances to deconstruct var args
00272         virtual void getV( const OfxTime time, va_list arg ) const OFX_EXCEPTION_SPEC;
00273 
00274         /// set a value, implemented by instances to deconstruct var args
00275         virtual void setV( va_list arg, const EChange change ) OFX_EXCEPTION_SPEC;
00276 
00277         /// key a value, implemented by instances to deconstruct var args
00278         virtual void setV( const OfxTime time, va_list arg, const EChange change ) OFX_EXCEPTION_SPEC;
00279 
00280         /// derive a value, implemented by instances to deconstruct var args
00281         virtual void deriveV( const OfxTime time, va_list arg ) const OFX_EXCEPTION_SPEC;
00282 
00283         /// integrate a value, implemented by instances to deconstruct var args
00284         virtual void integrateV( const OfxTime time1, const OfxTime time2, va_list arg ) const OFX_EXCEPTION_SPEC;
00285 
00286         /// overridden from Property::NotifyHook
00287         virtual void notify( const std::string& name, bool single, int num ) OFX_EXCEPTION_SPEC;
00288         #endif
00289 };
00290 
00291 #ifndef SWIG
00292 /**
00293  * @brief to make ParamInstance clonable (for use in boost::ptr_container)
00294  */
00295 inline OfxhParam* new_clone( const OfxhParam& a )
00296 {
00297         return a.clone();
00298 }
00299 
00300 #endif
00301 
00302 }
00303 }
00304 }
00305 }
00306 
00307 #ifndef SWIG
00308 // force boost::is_virtual_base_of value (used by boost::serialization)
00309 namespace boost {
00310 template<>
00311 struct is_virtual_base_of<tuttle::host::ofx::attribute::OfxhAttribute, tuttle::host::ofx::attribute::OfxhParam>: public mpl::true_ {};
00312 }
00313 #endif
00314 
00315 #endif