TuttleOFX
1
|
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