TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/host/ofx/property/OfxhPropertyTemplate.hpp
Go to the documentation of this file.
00001 /*
00002  * Software License :
00003  *
00004  * Copyright (c) 2007-2009, The Open Effects Association Ltd.  All Rights Reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  * Redistributions of source code must retain the above copyright notice,
00010  *    this list of conditions and the following disclaimer.
00011  * Redistributions in binary form must reproduce the above copyright notice,
00012  *    this list of conditions and the following disclaimer in the documentation
00013  *    and/or other materials provided with the distribution.
00014  * Neither the name The Open Effects Association Ltd, nor the names of its
00015  *    contributors may be used to endorse or promote products derived from this
00016  *    software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00019  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00020  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00021  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
00022  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00024  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00025  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00026  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00027  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 #ifndef _TUTTLE_HOST_OFX_PROPERTYTEMPLATE_HPP_
00030 #define _TUTTLE_HOST_OFX_PROPERTYTEMPLATE_HPP_
00031 
00032 #include "OfxhProperty.hpp"
00033 
00034 namespace tuttle {
00035 namespace host {
00036 namespace ofx {
00037 namespace property {
00038 
00039 /// type holder, for integers, used to template up int properties
00040 struct OfxhIntValue
00041 {
00042         typedef int APIType; ///< C type of the property that is passed across the raw API
00043         typedef int APITypeConstless;  ///< C type of the property that is passed across the raw API, without any const it
00044         typedef int Type; ///< Type we actually hold and deal with the propery in everything by the raw API
00045         typedef int ReturnType; ///< type to return from a function call
00046         static const EPropType typeCode = ePropTypeInt;
00047         static int kEmpty;
00048 };
00049 
00050 /// type holder, for doubles, used to template up double properties
00051 struct OfxhDoubleValue
00052 {
00053         typedef double APIType;
00054         typedef double APITypeConstless;
00055         typedef double Type;
00056         typedef double ReturnType; ///< type to return from a function call
00057         static const EPropType typeCode = ePropTypeDouble;
00058         static double kEmpty;
00059 };
00060 
00061 /// type holder, for pointers, used to template up pointer properties
00062 struct OfxhPointerValue
00063 {
00064         typedef void* APIType;
00065         typedef void* APITypeConstless;
00066         typedef void* Type;
00067         typedef void* ReturnType; ///< type to return from a function call
00068         static const EPropType typeCode = ePropTypePointer;
00069         static void* kEmpty;
00070 };
00071 
00072 /// type holder, for strings, used to template up string properties
00073 struct OfxhStringValue
00074 {
00075         typedef const char* APIType;
00076         typedef char* APITypeConstless;
00077         typedef std::string Type;
00078         typedef const std::string& ReturnType; ///< type to return from a function call
00079         static const EPropType typeCode = ePropTypeString;
00080         static std::string kEmpty;
00081 };
00082 
00083 /// this represents a generic property.
00084 /// template parameter T is the type descriptor of the
00085 /// type of property to model.  the class holds an internal _value vector which can be used
00086 /// to store the values.  if set and get hooks are installed, these will be called instead
00087 /// of using this variable.
00088 /// Make sure that T::ReturnType is const if appropriate, as no extra qualifiers are applied here.
00089 template<class T>
00090 class OfxhPropertyTemplate : public OfxhProperty
00091 {
00092 public:
00093         typedef OfxhPropertyTemplate<T> This;
00094         typedef typename T::Type Type;
00095         typedef typename T::ReturnType ReturnType;
00096         typedef typename T::APIType APIType;
00097         typedef typename T::APITypeConstless APITypeConstless;
00098 
00099 protected:
00100         /// this is the present value of the property
00101         std::vector<Type> _value;
00102 
00103         /// this is the default value of the property
00104         std::vector<Type> _defaultValue;
00105 
00106 public:
00107         OfxhPropertyTemplate();
00108 
00109         /// constructor
00110         OfxhPropertyTemplate( const std::string& name,
00111                               size_t             dimension,
00112                               bool               pluginReadOnly,
00113                               APIType            defaultValue );
00114 
00115         OfxhPropertyTemplate( const OfxhPropertyTemplate<T>& pt );
00116 
00117         OfxhPropertyTemplate<T>* clone() const
00118         {
00119                 return new OfxhPropertyTemplate( *this );
00120         }
00121 
00122         ~OfxhPropertyTemplate()
00123         {}
00124 
00125         bool operator==( const OfxhProperty& other ) const
00126         {
00127                 if( getType() != other.getType() )
00128                 {
00129                         //TUTTLE_TLOG( TUTTLE_INFO, "OfxhPropertyTemplate::operator== not same type : " << getType() << " != " << other.getType() );
00130                         return false;
00131                 }
00132                 return operator==( dynamic_cast<const This&>( other ) );
00133         }
00134 
00135         bool operator==( const This& other ) const
00136         {
00137                 if( OfxhProperty::operator!=( other ) )
00138                         return false;
00139                 if( getType() == ePropTypePointer )
00140                         return true; // we can't compare abstract pointer content, so assume true.
00141                 if( _value != other._value )
00142                 {
00143                         //TUTTLE_TLOG( TUTTLE_INFO, "OfxhPropertyTemplate::operator== not same value : " );
00144                         //for( typename std::vector<Type>::const_iterator it = _value.begin(), itEnd = _value.end(), ito = other._value.begin(), itoEnd = other._value.end();
00145                         //       it != itEnd && ito != itoEnd;
00146                         //     ++it, ++ito )
00147                         //{
00148                         //      TUTTLE_TLOG( TUTTLE_INFO, *it << " != " << *ito );
00149                         //}
00150                         return false;
00151                 }
00152                 //              if( _defaultValue != other._defaultValue )
00153                 //                      return false;
00154                 return true;
00155         }
00156 
00157         void copyValues( const OfxhProperty& other )
00158         {
00159                 if( getType() != other.getType() )
00160                 {
00161                         BOOST_THROW_EXCEPTION( exception::Bug()
00162                             << exception::dev( "You try to copy a property value, but it is not the same property type." ) );
00163                 }
00164                 copyValues( dynamic_cast<const This&>( other ) );
00165         }
00166 
00167         void copyValues( const This& other )
00168         {
00169                 if( OfxhProperty::operator!=( other ) )
00170                 {
00171                         BOOST_THROW_EXCEPTION( exception::Bug()
00172                             << exception::dev( "You try to copy a property value, but it is not the same property." ) );
00173                 }
00174                 _value      = other._value;
00175                 _modifiedBy = other._modifiedBy;
00176                 //_defaultValue = other._defaultValue;
00177         }
00178 
00179         /// get the vector
00180         const std::vector<Type>& getValues() const
00181         {
00182                 return _value;
00183         }
00184 
00185         // get multiple values
00186         void getValueN( APIType* value, int count ) const OFX_EXCEPTION_SPEC;
00187 
00188         #if defined( WINDOWS ) && !defined( __GNUC__ )
00189         #pragma warning( disable : 4181 )
00190         #endif
00191         /// get one value
00192         ReturnType getValue( int index = 0 ) const OFX_EXCEPTION_SPEC;
00193 
00194         /// get one value, without going through the getHook
00195         ReturnType getValueRaw( int index = 0 ) const OFX_EXCEPTION_SPEC;
00196 
00197         #if defined( WINDOWS ) && !defined( __GNUC__ )
00198         #pragma warning( default : 4181 )
00199         #endif
00200         // get multiple values, without going through the getHook
00201         void getValueNRaw( APIType* value, const int count ) const OFX_EXCEPTION_SPEC;
00202 
00203         /// set one value
00204         void setValue( const Type& value, const int index = 0, const EModifiedBy who = eModifiedByHost ) OFX_EXCEPTION_SPEC;
00205 
00206         /// set multiple values
00207         void setValueN( const APIType* value, const int count, const EModifiedBy who = eModifiedByHost ) OFX_EXCEPTION_SPEC;
00208 
00209         /// reset
00210         void reset() OFX_EXCEPTION_SPEC;
00211 
00212         /// get the size of the vector
00213         size_t getDimension() const OFX_EXCEPTION_SPEC;
00214 
00215         /// return the value as a string
00216         inline std::string getStringValueAt( int index = 0 ) const
00217         {
00218                 return boost::lexical_cast<std::string>( _value[index] );
00219         }
00220 
00221 public:
00222         /// @todo in private and friend function...
00223         ReturnType getConstlessValue( int index = 0 ) const OFX_EXCEPTION_SPEC;
00224         ReturnType getConstlessValueRaw( int index = 0 ) const OFX_EXCEPTION_SPEC;
00225         /// @todo tuttle remove ReturnType, only use Type
00226         inline APITypeConstless getAPIConstlessValue( int index = 0 ) const OFX_EXCEPTION_SPEC { return getConstlessValue( index ); }
00227 
00228 private:
00229         friend class boost::serialization::access;
00230         template<class Archive>
00231         void serialize( Archive& ar, const unsigned int version )
00232         {
00233                 ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP( OfxhProperty );
00234                 ar& BOOST_SERIALIZATION_NVP( _value );
00235                 ar& BOOST_SERIALIZATION_NVP( _defaultValue );
00236         }
00237 
00238 };
00239 
00240 typedef OfxhPropertyTemplate<OfxhIntValue>     Int;     /// Our int property
00241 typedef OfxhPropertyTemplate<OfxhDoubleValue>  Double;  /// Our double property
00242 typedef OfxhPropertyTemplate<OfxhStringValue>  String;  /// Our string property
00243 typedef OfxhPropertyTemplate<OfxhPointerValue> Pointer; /// Our pointer property
00244 
00245 template<>
00246 inline String::APITypeConstless String::getAPIConstlessValue( int index ) const OFX_EXCEPTION_SPEC { return const_cast<String::APITypeConstless>( getConstlessValue( index ).c_str() ); }
00247 
00248 template<>
00249 template<class Archive>
00250 void Pointer::serialize( Archive& ar, const unsigned int version )
00251 {
00252         ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP( OfxhProperty );
00253 }
00254 
00255 }
00256 }
00257 }
00258 }
00259 
00260 #ifndef SWIG
00261 // force boost::is_virtual_base_of value (used by boost::serialization)
00262 namespace boost {
00263 template<>
00264 struct is_virtual_base_of<tuttle::host::ofx::property::OfxhProperty, tuttle::host::ofx::property::Int>: public mpl::true_ {};
00265 template<>
00266 struct is_virtual_base_of<tuttle::host::ofx::property::OfxhProperty, tuttle::host::ofx::property::Double>: public mpl::true_ {};
00267 template<>
00268 struct is_virtual_base_of<tuttle::host::ofx::property::OfxhProperty, tuttle::host::ofx::property::String>: public mpl::true_ {};
00269 template<>
00270 struct is_virtual_base_of<tuttle::host::ofx::property::OfxhProperty, tuttle::host::ofx::property::Pointer>: public mpl::true_ {};
00271 }
00272 
00273 BOOST_CLASS_EXPORT_KEY( tuttle::host::ofx::property::Int )
00274 BOOST_CLASS_EXPORT_KEY( tuttle::host::ofx::property::Double )
00275 BOOST_CLASS_EXPORT_KEY( tuttle::host::ofx::property::Pointer )
00276 BOOST_CLASS_EXPORT_KEY( tuttle::host::ofx::property::String )
00277 #endif
00278 
00279 #endif
00280