TuttleOFX  1
OfxhSet.cpp
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 #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 }