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 #include "OfxhSet.hpp" 00030 #include "OfxhPropertyTemplate.hpp" 00031 #include "OfxhGetHook.hpp" 00032 #include "OfxhNotifyHook.hpp" 00033 00034 #include <tuttle/host/ofx/OfxhCore.hpp> 00035 00036 #include <ofxCore.h> 00037 #include <ofxImageEffect.h> 00038 00039 #include <iostream> 00040 #include <cstring> 00041 00042 //#define DEBUG_PROPERTIES true 00043 00044 namespace tuttle { 00045 namespace host { 00046 namespace ofx { 00047 namespace property { 00048 00049 00050 OfxhProperty& OfxhSet::localAt( const int index ) 00051 { 00052 if( index >= getLocalSize() ) 00053 { 00054 if( index >= getSize() ) 00055 { 00056 BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrValue) 00057 << exception::dev() + "OfxhSet::at: " + index + ", property not found." ); 00058 } 00059 else 00060 { 00061 BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrValue) 00062 << exception::dev() + "OfxhSet::at: " + index + " is a non-local property." ); 00063 } 00064 } 00065 00066 PropertyMap::iterator it = _props.begin(); 00067 std::advance(it, index); 00068 return * it->second; 00069 } 00070 00071 const OfxhProperty& OfxhSet::at( const int index ) const 00072 { 00073 if( index < getLocalSize() ) 00074 { 00075 PropertyMap::const_iterator it = _props.begin(); 00076 std::advance(it, index); 00077 return * it->second; 00078 } 00079 if( _chainedSet == NULL ) 00080 { 00081 BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrValue) 00082 << exception::dev() + "OfxhSet::at: " + index + ", property not found." ); 00083 } 00084 return _chainedSet->at(index - getLocalSize()); 00085 } 00086 00087 void OfxhSet::setGetHook( const std::string& s, OfxhGetHook* ghook ) 00088 { 00089 fetchLocalProperty( s ).setGetHook( ghook ); 00090 } 00091 00092 /** 00093 * add a notify hook for a particular property. users may need to call particular 00094 * specialised versions of this. 00095 */ 00096 void OfxhSet::addNotifyHook( const std::string& s, OfxhNotifyHook* hook ) 00097 { 00098 fetchLocalProperty( s ).addNotifyHook( hook ); 00099 } 00100 00101 OfxhProperty& OfxhSet::fetchLocalProperty( const std::string& name ) 00102 { 00103 PropertyMap::iterator i = _props.find( name ); 00104 00105 if( i == _props.end() ) 00106 { 00107 BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrValue, "fetchLocalProperty: " + name + ". Property not found." ) ); //+ " on type:" + getStringProperty(kOfxPropType) + " name:" + getStringProperty(kOfxPropName) );// " NULL, (followChain: " << followChain << ")."; 00108 } 00109 return *( i->second ); 00110 } 00111 00112 const OfxhProperty& OfxhSet::fetchProperty( const std::string& name ) const 00113 { 00114 PropertyMap::const_iterator i = _props.find( name ); 00115 00116 if( i == _props.end() ) 00117 { 00118 if( _chainedSet ) 00119 { 00120 return _chainedSet->fetchProperty( name ); 00121 } 00122 BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrValue ) 00123 << exception::dev() + "fetchProperty: " + name + " property not found." ); 00124 } 00125 return *( i->second ); 00126 } 00127 00128 /** 00129 * add one new property 00130 */ 00131 void OfxhSet::createProperty( const OfxhPropSpec& spec ) 00132 { 00133 if( _props.find( spec.name ) != _props.end() ) 00134 { 00135 BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrExists ) 00136 << exception::dev() + "Tried to add a duplicate property to a Property::Set (" + spec.name + ")" ); 00137 } 00138 std::string key( spec.name ); // for constness 00139 switch( spec.type ) 00140 { 00141 case ePropTypeInt: 00142 _props.insert( key, new Int( spec.name, spec.dimension, spec.readonly, spec.defaultValue ? std::atoi( spec.defaultValue ) : 0 ) ); 00143 break; 00144 case ePropTypeDouble: 00145 _props.insert( key, new Double( spec.name, spec.dimension, spec.readonly, spec.defaultValue ? std::atof( spec.defaultValue ) : 0 ) ); 00146 break; 00147 case ePropTypeString: 00148 _props.insert( key, new String( spec.name, spec.dimension, spec.readonly, spec.defaultValue ? spec.defaultValue : "" ) ); 00149 break; 00150 case ePropTypePointer: 00151 _props.insert( key, new Pointer( spec.name, spec.dimension, spec.readonly, (void*) spec.defaultValue ) ); 00152 break; 00153 case ePropTypeNone: 00154 BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrUnsupported ) 00155 << exception::dev() + "Tried to create a property of an unrecognized type (" + spec.name + ", " + mapTypeEnumToString( spec.type ) + ")" ); 00156 } 00157 } 00158 00159 void OfxhSet::addProperties( const OfxhPropSpec spec[] ) 00160 { 00161 while( spec->name ) 00162 { 00163 createProperty( *spec ); 00164 ++spec; 00165 } 00166 } 00167 00168 void OfxhSet::eraseProperty( const std::string& propName ) 00169 { 00170 _props.erase( propName ); 00171 } 00172 00173 bool OfxhSet::hasProperty( const std::string& propName, bool followChain ) const 00174 { 00175 PropertyMap::const_iterator it = _props.find( propName ); 00176 00177 if( it == _props.end() ) 00178 { 00179 if( followChain && _chainedSet ) 00180 { 00181 return _chainedSet->hasProperty( propName, true ); 00182 } 00183 } 00184 return it != _props.end(); 00185 } 00186 00187 bool OfxhSet::hasLocalProperty( const std::string& propName ) const 00188 { 00189 return hasProperty( propName, false ); 00190 } 00191 00192 /** 00193 * add one new property 00194 */ 00195 void OfxhSet::addProperty( OfxhProperty* prop ) 00196 { 00197 std::string key( prop->getName() ); // for constness 00198 00199 _props.insert( key, prop ); 00200 } 00201 00202 /** 00203 * empty ctor 00204 */ 00205 OfxhSet::OfxhSet() 00206 : _magic( kMagic ) 00207 , _chainedSet( NULL ) 00208 {} 00209 00210 OfxhSet::OfxhSet( const OfxhPropSpec spec[] ) 00211 : _magic( kMagic ) 00212 , _chainedSet( NULL ) 00213 { 00214 addProperties( spec ); 00215 } 00216 00217 OfxhSet::OfxhSet( const OfxhSet& other ) 00218 : _magic( kMagic ) 00219 { 00220 operator=( other ); 00221 } 00222 00223 OfxhSet::~OfxhSet() 00224 { 00225 clear(); 00226 } 00227 00228 void OfxhSet::clear() 00229 { 00230 _props.clear(); 00231 } 00232 00233 OfxhSet& OfxhSet::operator=( const This& other ) 00234 { 00235 _props = other._props.clone(); 00236 _chainedSet = other._chainedSet; 00237 return *this; 00238 } 00239 00240 bool OfxhSet::operator==( const This& other ) const 00241 { 00242 if( _props != other._props ) 00243 return false; 00244 if( _chainedSet == NULL ) 00245 { 00246 if( other._chainedSet != NULL ) 00247 if( other._chainedSet->getSize() != 0 ) 00248 return false; 00249 } 00250 else 00251 { 00252 if( other._chainedSet == NULL ) 00253 if( _chainedSet->getSize() != 0 ) 00254 return false; 00255 if( *_chainedSet != *( other._chainedSet ) ) 00256 return false; 00257 } 00258 return true; 00259 } 00260 00261 void OfxhSet::copyValues( const This& other ) 00262 { 00263 if( _props.size() != other._props.size() ) 00264 { 00265 BOOST_THROW_EXCEPTION( exception::Bug() 00266 << exception::dev( "You try to copy properties values, but the two lists are not identical." ) ); 00267 } 00268 00269 PropertyMap::const_iterator oit = other._props.begin(), oitEnd = other._props.end(); 00270 for( PropertyMap::iterator it = _props.begin(), itEnd = _props.end(); 00271 it != itEnd && oit != oitEnd; 00272 ++it, ++oit ) 00273 { 00274 OfxhProperty& p = *( it->second ); 00275 const OfxhProperty& op = *( oit->second ); 00276 if( p.getName() != op.getName() ) 00277 { 00278 BOOST_THROW_EXCEPTION( exception::Bug() 00279 << exception::dev( "You try to copy properties values, but it is not the same property in the two lists." ) ); 00280 } 00281 p.copyValues( op ); 00282 } 00283 } 00284 00285 /// get a particular int property 00286 int OfxhSet::getIntPropertyRaw( const std::string& property, int index ) const 00287 { 00288 return getPropertyRaw<OfxhIntValue>( property, index ); 00289 } 00290 00291 /// get a particular double property 00292 00293 double OfxhSet::getDoublePropertyRaw( const std::string& property, int index ) const 00294 { 00295 return getPropertyRaw<OfxhDoubleValue>( property, index ); 00296 } 00297 00298 /// get a particular double property 00299 00300 void* OfxhSet::getPointerPropertyRaw( const std::string& property, int index ) const 00301 { 00302 return getPropertyRaw<OfxhPointerValue>( property, index ); 00303 } 00304 00305 /// get a particular double property 00306 00307 const std::string& OfxhSet::getStringPropertyRaw( const std::string& property, int index ) const 00308 { 00309 return fetchTypedProperty<String>( property ).getValueRaw( index ); 00310 //return OfxhStringValue::kEmpty; 00311 } 00312 00313 /// get a particular int property 00314 00315 int OfxhSet::getIntProperty( const std::string& property, int index ) const 00316 { 00317 return getProperty<OfxhIntValue >( property, index ); 00318 } 00319 00320 /// get the value of a particular double property 00321 00322 void OfxhSet::getIntPropertyN( const std::string& property, int* v, int N ) const 00323 { 00324 return getPropertyN<OfxhIntValue >( property, N, v ); 00325 } 00326 00327 /// get a particular double property 00328 00329 double OfxhSet::getDoubleProperty( const std::string& property, int index ) const 00330 { 00331 return getProperty<OfxhDoubleValue >( property, index ); 00332 } 00333 00334 /// get the value of a particular double property 00335 00336 void OfxhSet::getDoublePropertyN( const std::string& property, double* v, int N ) const 00337 { 00338 return getPropertyN<OfxhDoubleValue >( property, N, v ); 00339 } 00340 00341 /// get a particular double property 00342 00343 void* OfxhSet::getPointerProperty( const std::string& property, int index ) const 00344 { 00345 return getProperty<OfxhPointerValue >( property, index ); 00346 } 00347 00348 /// get a particular double property 00349 00350 const std::string& OfxhSet::getStringProperty( const std::string& property, int index ) const 00351 { 00352 return getProperty<OfxhStringValue >( property, index ); 00353 } 00354 00355 /// is the given string one of the values of a multi-dimensional string prop 00356 /// this returns a non negative index if it is found, otherwise, -1 00357 00358 int OfxhSet::findStringPropValueIndex( const std::string& propName, 00359 const std::string& propValue ) const 00360 { 00361 const String& prop = fetchStringProperty( propName ); 00362 00363 const std::vector<std::string>& values = prop.getValues(); 00364 std::vector<std::string>::const_iterator i = find( values.begin(), values.end(), propValue ); 00365 if( i != values.end() ) 00366 { 00367 return int(i - values.begin() ); 00368 } 00369 return -1; 00370 } 00371 00372 std::ostream& operator<<( std::ostream& os, const OfxhSet& v ) 00373 { 00374 os << "property::Set {" << std::endl; 00375 for( PropertyMap::const_iterator it = v._props.begin(), itEnd = v._props.end(); 00376 it != itEnd; 00377 ++it ) 00378 { 00379 const OfxhProperty& prop = *( it->second ); 00380 os << " " << it->first << " "; 00381 os << "(type:" << mapTypeEnumToString( prop.getType() ) 00382 << " dim:" << prop.getDimension() << " ro:" << prop.getPluginReadOnly() 00383 << " modifiedBy:" << ( prop.getModifiedBy() == eModifiedByHost ? "host" : "plugin" ) 00384 << ") : ["; 00385 int i = 0; 00386 for( ; i < (int)( prop.getDimension() ) - 1; ++i ) 00387 { 00388 os << prop.getStringValueAt( i ) << ", "; 00389 } 00390 if( prop.getDimension() > 0 ) 00391 os << prop.getStringValueAt( i ); 00392 os << "] " << std::endl; 00393 } 00394 os << "}" << std::endl; 00395 return os; 00396 } 00397 00398 } 00399 } 00400 } 00401 }