TuttleOFX  1
OfxhParamSet.cpp
Go to the documentation of this file.
00001 #include "OfxhParamSet.hpp"
00002 
00003 #include <boost/functional/hash.hpp>
00004 
00005 #include <boost/algorithm/string/join.hpp>
00006 #include <boost/algorithm/string/predicate.hpp>
00007 #include <boost/foreach.hpp>
00008 
00009 
00010 namespace tuttle {
00011 namespace host {
00012 namespace ofx {
00013 namespace attribute {
00014 
00015 OfxhParamSet::OfxhParamSet()
00016 {}
00017 
00018 OfxhParamSet::OfxhParamSet( const OfxhParamSet& other )
00019 {
00020         operator=( other );
00021 }
00022 
00023 void OfxhParamSet::initMapFromList()
00024 {
00025         BOOST_FOREACH( OfxhParam& p, _paramVector )
00026         {
00027                 _params[p.getName()] = &p;
00028                 _paramsByScriptName[p.getScriptName()] = &p;
00029         }
00030 }
00031 
00032 OfxhParamSet::~OfxhParamSet()
00033 {}
00034 
00035 void OfxhParamSet::operator=( const OfxhParamSet& other )
00036 {
00037         _paramVector = other._paramVector.clone();
00038         initMapFromList();
00039 }
00040 
00041 void OfxhParamSet::copyParamsValues( const OfxhParamSet& other )
00042 {
00043         if( _paramVector.size() != other._paramVector.size() )
00044         {
00045                 BOOST_THROW_EXCEPTION( exception::Bug()
00046                     << exception::dev( "You try to copy parameters values, but the two lists are not identical." ) );
00047         }
00048 
00049         ParamVector::const_iterator oit = other._paramVector.begin(), oitEnd = other._paramVector.end();
00050         for( ParamVector::iterator it = _paramVector.begin(), itEnd = _paramVector.end();
00051              it != itEnd && oit != oitEnd;
00052              ++it, ++oit )
00053         {
00054                 OfxhParam& p        = *it;
00055                 const OfxhParam& op = *oit;
00056                 if( p.getName() != op.getName() )
00057                 {
00058                         BOOST_THROW_EXCEPTION( exception::Bug()
00059                             << exception::dev( "You try to copy parameters values, but it is not the same parameters in the two lists." ) );
00060                 }
00061                 p.copy( op );
00062         }
00063         initMapFromList();
00064 }
00065 
00066 std::size_t OfxhParamSet::getHashAtTime( const OfxTime time ) const
00067 {
00068         std::size_t seed = 0;
00069         BOOST_FOREACH( const OfxhParam& param, getParamVector() )
00070         {
00071                 //TUTTLE_TLOG_VAR( TUTTLE_INFO, param.getName() );
00072                 if( param.paramTypeHasData() && param.getEvaluateOnChange() )
00073                 {
00074                         boost::hash_combine( seed, param.getHashAtTime( time ) );
00075                 }
00076         }
00077         return seed;
00078 }
00079 
00080 //void OfxhParamSet::referenceParam( const std::string& name, OfxhParam* instance ) OFX_EXCEPTION_SPEC
00081 //{
00082         //      if( _allParams.find( name ) != _allParams.end() )
00083         //      {
00084         //              BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrExists, "Trying to reference a new parameter which already exists." ) );
00085         //      }
00086         //      _allParams[name] = instance;
00087 //}
00088 
00089 OfxhParam& OfxhParamSet::getParam( const std::string& name )
00090 {
00091         ParamMap::iterator it = _params.find( name );
00092         if( it == _params.end() )
00093         {
00094                 BOOST_THROW_EXCEPTION( exception::BadIndex()
00095                                 << exception::user() + "Param name \"" + name + "\" not found."
00096                         );
00097         }
00098         return *it->second;
00099 }
00100 
00101 OfxhParam& OfxhParamSet::getParamByScriptName( const std::string& scriptName, const bool acceptPartialName )
00102 {
00103         ParamMap::iterator it = _paramsByScriptName.find( scriptName );
00104         if( it != _paramsByScriptName.end() )
00105                 return *it->second;
00106 
00107         std::vector<std::string> matches;
00108         OfxhParam* res = NULL;
00109         if( acceptPartialName )
00110         {
00111                 BOOST_FOREACH( ParamMap::value_type& p, _paramsByScriptName )
00112                 {
00113                         if( boost::algorithm::starts_with( p.first, scriptName ) )
00114                         {
00115                                 matches.push_back( p.first );
00116                                 res = p.second;
00117                         }
00118                 }
00119                 if( matches.size() > 1 )
00120                 {
00121                         BOOST_THROW_EXCEPTION( exception::Value()
00122                                         << exception::user() + "Ambiguous partial param script name \"" + scriptName + "\". Possible values are: " + boost::algorithm::join( matches, ", " ) + "."
00123                                 );
00124                 }
00125         }
00126 
00127         if( matches.size() == 0 )
00128         {
00129                 BOOST_THROW_EXCEPTION( exception::Value()
00130                                 << exception::user() + "Param script name \"" + scriptName + "\" not found."
00131                         );
00132         }
00133         return *res;
00134 }
00135 OfxhParam* OfxhParamSet::getParamPtrByScriptName( const std::string& name, const bool acceptPartialName )
00136 {
00137         try
00138         {
00139                 return &this->getParamByScriptName( name, acceptPartialName );
00140         }
00141         catch(...)
00142         {
00143                 return NULL;
00144         }
00145 }
00146 const OfxhParam* OfxhParamSet::getParamPtrByScriptName( const std::string& name, const bool acceptPartialName ) const
00147 {
00148         try
00149         {
00150                 return &this->getParamByScriptName( name, acceptPartialName );
00151         }
00152         catch(...)
00153         {
00154                 return NULL;
00155         }
00156 }
00157 
00158 // get the param
00159 OfxhParam& OfxhParamSet::getParam( const std::size_t index )
00160 {
00161         if( index > _paramVector.size() )
00162                 BOOST_THROW_EXCEPTION( exception::BadIndex()
00163                                 << exception::user() + "Param not found, index out of range. (index=" + index + ", nb params=" + _paramVector.size() + ")"
00164                         );
00165 
00166         return _paramVector[index];
00167 }
00168 
00169 
00170 void OfxhParamSet::addParam( OfxhParam* instance ) OFX_EXCEPTION_SPEC
00171 {
00172         if( _params.find( instance->getName() ) != _params.end() )
00173         {
00174                 BOOST_THROW_EXCEPTION( OfxhException( kOfxStatErrExists, "Trying to add a new parameter which already exists." ) );
00175         }
00176         _paramVector.push_back( instance );
00177         _params[instance->getName()] = instance;
00178         _paramsByScriptName[instance->getScriptName()] = instance;
00179         //      referenceParam( name, instance );
00180 }
00181 
00182 }
00183 }
00184 }
00185 }
00186