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_PROPERTY_SET_HPP_ 00030 #define _TUTTLE_HOST_OFX_PROPERTY_SET_HPP_ 00031 00032 #include "OfxhPropertyTemplate.hpp" 00033 00034 #include <boost/ptr_container/serialize_ptr_map.hpp> 00035 00036 namespace tuttle { 00037 namespace host { 00038 namespace ofx { 00039 namespace property { 00040 00041 /// A class that is used to initialize a property set. Feed in an array of these to 00042 /// a property and it will construct a bunch of properties. Terminate such an array 00043 /// with an empty (all zero) set. 00044 struct OfxhPropSpec 00045 { 00046 const char* name; ///< name of the property 00047 EPropType type; ///< type 00048 int dimension; ///< fixed dimension of the property, set to zero if variable dimension 00049 bool readonly; ///< is the property plug-in read only 00050 const char* defaultValue; ///< Default value as a string. Pointers are ignored and always null. 00051 }; 00052 00053 /// A std::map of properties by name 00054 typedef boost::ptr_map<std::string, OfxhProperty> PropertyMap; 00055 00056 /** 00057 * Class that holds a set of properties and manipulates them 00058 * The 'fetch' methods return a property object. 00059 * The 'get' methods return a property value 00060 */ 00061 class OfxhSet 00062 { 00063 public: 00064 typedef OfxhSet This; 00065 00066 private: 00067 static const int kMagic = 0x12082007; ///< magic number for property sets, and Connie's birthday :-) 00068 const int _magic; ///< to check for handles being nice 00069 00070 protected: 00071 PropertyMap _props; ///< Our properties. 00072 00073 /// chained property set, which is read only 00074 /// these are searched on a get if not found 00075 /// on a local search 00076 const OfxhSet* _chainedSet; 00077 00078 /// set a particular property 00079 template<class T> 00080 void setProperty( const std::string& property, int index, const typename T::Type& value ); 00081 00082 /// set the first N of a particular property 00083 template<class T> 00084 void setPropertyN( const std::string& property, int count, const typename T::APIType* value ); 00085 00086 /// get a particular property 00087 template<class T> 00088 typename T::ReturnType getProperty( const std::string& property, int index ) const; 00089 00090 /// get the first N of a particular property 00091 template<class T> 00092 void getPropertyN( const std::string & property, int index, typename T::APIType * v ) const; 00093 00094 /// get a particular property without going through any getHook 00095 template<class T> 00096 typename T::ReturnType getPropertyRaw( const std::string& property, int index ) const; 00097 00098 /// get a particular property without going through any getHook 00099 template<class T> 00100 void getPropertyRawN( const std::string & property, int count, typename T::APIType * v ) const; 00101 00102 public: 00103 /// take an array of of PropSpecs (which must be terminated with an entry in which 00104 /// ->name is null), and turn these into a Set 00105 OfxhSet( const OfxhPropSpec spec[] ); 00106 // explicit Set(const std::vector<const PropSpec*>& multipleSpec); 00107 00108 /// deep copies the property set 00109 OfxhSet( const OfxhSet& ); 00110 00111 /// empty ctor 00112 OfxhSet(); 00113 00114 /// destructor 00115 virtual ~OfxhSet(); 00116 00117 void clear(); 00118 00119 size_t getLocalSize() const { return _props.size(); } 00120 size_t getSize() const 00121 { 00122 if( _chainedSet == NULL ) 00123 return getLocalSize(); 00124 else 00125 return getLocalSize() + _chainedSet->getSize(); 00126 } 00127 00128 /// hide assignment 00129 void operator=( const This& ); 00130 00131 bool operator==( const This& ) const; 00132 bool operator!=( const This& other ) const { return !This::operator==( other ); } 00133 00134 void copyValues( const This& other ); 00135 00136 #ifndef SWIG 00137 friend std::ostream& operator<<( std::ostream& os, const This& g ); 00138 #endif 00139 00140 #ifdef SWIG 00141 %extend 00142 { 00143 // const OfxhProperty& __getitem__( const std::string& name ) const 00144 // { 00145 // return self->fetchProperty(name); 00146 // } 00147 OfxhProperty& __getitem__( const std::string& name ) 00148 { 00149 return self->fetchLocalProperty( name ); 00150 } 00151 00152 std::string __str__() const 00153 { 00154 std::stringstream s; 00155 00156 s << *self; 00157 return s.str(); 00158 } 00159 00160 } 00161 #endif 00162 00163 /// adds a bunch of properties from PropSpec 00164 void addProperties( const OfxhPropSpec* ); 00165 00166 void eraseProperty( const std::string& propName ); 00167 00168 bool hasProperty( const std::string& propName, bool followChain = true ) const; 00169 bool hasLocalProperty( const std::string& propName ) const; 00170 00171 inline OfxhSet& operator+( const OfxhPropSpec* p ) { addProperties( p ); return *this; } 00172 00173 /// add one new property 00174 void createProperty( const OfxhPropSpec& s ); 00175 00176 /// add one new property 00177 void addProperty( OfxhProperty* prop ); 00178 00179 /// set the chained property set 00180 void setChainedSet( const OfxhSet* const s ) { _chainedSet = s; } 00181 00182 /// grab the internal properties map 00183 const PropertyMap& getMap() const { return _props; } 00184 PropertyMap& getMap() { return _props; } 00185 00186 /// set the get hook for a particular property. users may need to call particular 00187 /// specialised versions of this. 00188 void setGetHook( const std::string& s, OfxhGetHook* ghook ); 00189 00190 /// add a set hook for a particular property. users may need to call particular 00191 /// specialised versions of this. 00192 void addNotifyHook( const std::string& name, OfxhNotifyHook* hook ); 00193 00194 /// Fetchs a reference to a property of the given name, following the property chain if the 00195 /// 'followChain' arg is not false. 00196 const OfxhProperty& fetchProperty( const std::string& name ) const; 00197 OfxhProperty& fetchLocalProperty( const std::string& name ); 00198 const OfxhProperty& fetchLocalProperty( const std::string& name ) const { return const_cast<OfxhSet*>( this )->fetchLocalProperty( name ); } 00199 00200 /// get property with the particular name and type. if the property is 00201 /// missing or is of the wrong type, return an error status. if this is a sloppy 00202 /// property set and the property is missing, a new one will be created of the right 00203 /// type 00204 template<class T> 00205 const T& fetchTypedProperty( const std::string& name ) const 00206 { 00207 return dynamic_cast<const T&>( fetchProperty( name ) ); 00208 } 00209 00210 template<class T> 00211 T& fetchLocalTypedProperty( const std::string& name ) 00212 { 00213 return dynamic_cast<T&>( fetchLocalProperty( name ) ); 00214 } 00215 00216 template<class T> 00217 const T& fetchLocalTypedProperty( const std::string& name ) const 00218 { 00219 return const_cast<OfxhSet*>( this )->fetchLocalTypedProperty<T>( name ); 00220 } 00221 00222 00223 const String& fetchStringProperty( const std::string& name ) const 00224 { 00225 return fetchTypedProperty<String>( name ); 00226 } 00227 00228 String& fetchLocalStringProperty( const std::string& name ) 00229 { 00230 return fetchLocalTypedProperty<String>( name ); 00231 } 00232 00233 const String& fetchLocalStringProperty( const std::string& name ) const { return const_cast<OfxhSet*>( this )->fetchLocalStringProperty( name ); } 00234 00235 const Int& fetchIntProperty( const std::string& name ) const 00236 { 00237 return fetchTypedProperty<Int>( name ); 00238 } 00239 00240 Int& fetchLocalIntProperty( const std::string& name ) 00241 { 00242 return fetchLocalTypedProperty<Int>( name ); 00243 } 00244 00245 const Int& fetchLocalIntProperty( const std::string& name ) const { return const_cast<OfxhSet*>( this )->fetchLocalIntProperty( name ); } 00246 00247 const Pointer& fetchPointerProperty( const std::string& name ) const 00248 { 00249 return fetchTypedProperty<Pointer>( name ); 00250 } 00251 00252 Pointer& fetchLocalPointerProperty( const std::string& name ) 00253 { 00254 return fetchLocalTypedProperty<Pointer>( name ); 00255 } 00256 00257 const Pointer& fetchLocalPointerProperty( const std::string& name ) const { return const_cast<OfxhSet*>( this )->fetchLocalPointerProperty( name ); } 00258 00259 const Double& fetchDoubleProperty( const std::string& name ) const 00260 { 00261 return fetchTypedProperty<Double>( name ); 00262 } 00263 00264 Double& fetchLocalDoubleProperty( const std::string& name ) 00265 { 00266 return fetchLocalTypedProperty<Double>( name ); 00267 } 00268 00269 const Double& fetchLocalDoubleProperty( const std::string& name ) const { return const_cast<OfxhSet*>( this )->fetchLocalDoubleProperty( name ); } 00270 00271 00272 /// get a particular int property without fetching via a get hook, useful for notifies 00273 int getIntPropertyRaw( const std::string& property, int index = 0 ) const; 00274 00275 /// get a particular double property without fetching via a get hook, useful for notifies 00276 double getDoublePropertyRaw( const std::string& property, int index = 0 ) const; 00277 00278 /// get a particular pointer property without fetching via a get hook, useful for notifies 00279 void* getPointerPropertyRaw( const std::string& property, int index = 0 ) const; /// @todo tuttle: return const no ? 00280 00281 /// get a particular string property 00282 const std::string& getStringPropertyRaw( const std::string& property, int index = 0 ) const; 00283 00284 /// get the value of a particular string property 00285 const std::string& getStringProperty( const std::string& property, int index = 0 ) const; 00286 00287 /// get the value of a particular int property 00288 int getIntProperty( const std::string& property, int index = 0 ) const; 00289 00290 /// get the value of a particular double property 00291 void getIntPropertyN( const std::string& property, int* v, int N ) const; 00292 00293 /// get the value of a particular double property 00294 double getDoubleProperty( const std::string& property, int index = 0 ) const; 00295 00296 /// get the value of a particular double property 00297 void getDoublePropertyN( const std::string& property, double* v, int N ) const; 00298 00299 /// get the value of a particular pointer property 00300 void* getPointerProperty( const std::string& property, int index = 0 ) const; 00301 00302 /// set a particular string property without fetching via a get hook, useful for notifies 00303 void setStringProperty( const std::string& property, const std::string& value, int index = 0 ) { setProperty<OfxhStringValue >( property, index, value ); } 00304 00305 /// set a particular int property 00306 void setIntProperty( const std::string& property, int v, int index = 0 ) { setProperty<OfxhIntValue >( property, index, v ); } 00307 00308 /// set a particular double property 00309 void setIntPropertyN( const std::string& property, const int* v, int N ) 00310 { 00311 setPropertyN<OfxhIntValue >( property, N, v ); 00312 } 00313 00314 /// get a particular double property 00315 void setDoubleProperty( const std::string& property, double v, int index = 0 ) { setProperty<OfxhDoubleValue >( property, index, v ); } 00316 00317 /// get a particular double property 00318 void setDoublePropertyN( const std::string& property, const double* v, int N ) { setPropertyN<OfxhDoubleValue >( property, N, v ); } 00319 00320 /// get a particular double property 00321 void setPointerProperty( const std::string& property, void* v, int index = 0 ) { setProperty<OfxhPointerValue >( property, index, v ); } 00322 00323 /// get the dimension of a particular property 00324 size_t getDimension( const std::string& property ) const { return fetchProperty( property ).getDimension(); } 00325 00326 /// is the given string one of the values of a multi-dimensional string prop 00327 /// this returns a non negative index if it is found, otherwise, -1 00328 int findStringPropValueIndex( const std::string& propName, 00329 const std::string& propValue ) const; 00330 00331 /// get a handle on this object for passing to the C API 00332 OfxPropertySetHandle getHandle() const { return ( OfxPropertySetHandle ) this; } 00333 00334 /// is this a nice property set, or a dodgy pointer passed back to us 00335 bool verifyMagic() { return this != NULL && _magic == kMagic; } 00336 00337 private: 00338 friend class boost::serialization::access; 00339 template<class Archive> 00340 void serialize( Archive& ar, const unsigned int version ) 00341 { 00342 ar& BOOST_SERIALIZATION_NVP( _props ); 00343 } 00344 00345 }; 00346 00347 /// set a particular property 00348 template<class T> 00349 void OfxhSet::setProperty( const std::string& property, int index, const typename T::Type& value ) 00350 { 00351 try 00352 { 00353 fetchLocalTypedProperty<OfxhPropertyTemplate<T> >( property ).setValue( value, index ); 00354 } 00355 catch( OfxhException& e ) 00356 { 00357 TUTTLE_LOG_ERROR( "Property::Set::setProperty - Error on " << property << " property (value=" << value << ")."); 00358 TUTTLE_LOG_ERROR( "on Property::Set (type:" << this->getStringProperty( kOfxPropType ) << ", name:" << this->getStringProperty( kOfxPropName ) << ")." ); 00359 TUTTLE_LOG_EXCEPTION( e ); 00360 //TUTTLE_LOG_DEBUG( *this ); 00361 } 00362 catch(... ) 00363 { 00364 TUTTLE_LOG_ERROR( "Property::Set::setProperty - Error on " << property << " property (value=" << value << ")." << 00365 "on Property::Set (type:" << this->getStringProperty( kOfxPropType ) << ", name:" << this->getStringProperty( kOfxPropName ) << ")." ); 00366 //TUTTLE_LOG_DEBUG( *this ); 00367 } 00368 } 00369 00370 /// set a particular property 00371 00372 template<class T> 00373 void OfxhSet::setPropertyN( const std::string& property, int count, const typename T::APIType* value ) 00374 { 00375 try 00376 { 00377 fetchLocalTypedProperty<OfxhPropertyTemplate<T> >( property ).setValueN( value, count ); 00378 } 00379 catch( OfxhException& e ) 00380 { 00381 TUTTLE_LOG_ERROR( "Set::setProperty - Error on " << property << " property (value=" << value << ")." ); 00382 TUTTLE_LOG_ERROR( "on Property::Set (type:" << this->getStringProperty( kOfxPropType ) << ", name:" << this->getStringProperty( kOfxPropName ) << ")." ); 00383 TUTTLE_LOG_EXCEPTION( e ); 00384 } 00385 catch(... ) 00386 { 00387 TUTTLE_LOG_ERROR( "Set::setProperty - Error on " << property << " property (value=" << value << ")." ); 00388 TUTTLE_LOG_ERROR( "on Property::Set (type:" << this->getStringProperty( kOfxPropType ) << ", name:" << this->getStringProperty( kOfxPropName ) << ")." ); 00389 } 00390 } 00391 00392 /// get a particular property 00393 00394 template<class T> 00395 typename T::ReturnType OfxhSet::getProperty( const std::string& property, int index ) const 00396 { 00397 /* 00398 if( !hasProperty( property, true ) ) 00399 { 00400 TUTTLE_TLOG( TUTTLE_INFO, "return kEmpty on property: " << property ); 00401 return T::kEmpty; /// @todo tuttle: is this really needed ? 00402 } 00403 */ 00404 return fetchTypedProperty<OfxhPropertyTemplate<T> >( property ).getValue( index ); 00405 } 00406 00407 /// get a particular property 00408 00409 template<class T> 00410 void OfxhSet::getPropertyN( const std::string& property, int count, typename T::APIType* value ) const 00411 { 00412 fetchTypedProperty<OfxhPropertyTemplate<T> >( property ).getValueN( value, count ); 00413 } 00414 00415 /// get a particular property 00416 00417 template<class T> 00418 typename T::ReturnType OfxhSet::getPropertyRaw( const std::string& property, int index ) const 00419 { 00420 return fetchTypedProperty<OfxhPropertyTemplate<T> >( property ).getValueRaw( index ); 00421 } 00422 00423 /// get a particular property 00424 00425 template<class T> 00426 void OfxhSet::getPropertyRawN( const std::string& property, int count, typename T::APIType* value ) const 00427 { 00428 return fetchTypedProperty<OfxhPropertyTemplate<T> >( property ).getValueNRaw( value, count ); 00429 } 00430 00431 } 00432 } 00433 } 00434 } 00435 00436 #endif