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