TuttleOFX  1
OfxhImageEffectPluginCache.cpp
Go to the documentation of this file.
00001 #include "OfxhImageEffectPluginCache.hpp"
00002 #include "OfxhImageEffectPlugin.hpp"
00003 
00004 ///@todo tuttle: remove this!
00005 #include <tuttle/host/Core.hpp>
00006 
00007 #include <boost/algorithm/string/case_conv.hpp>
00008 
00009 namespace tuttle {
00010 namespace host {
00011 namespace ofx {
00012 namespace imageEffect {
00013 
00014 OfxhImageEffectPluginCache::OfxhImageEffectPluginCache( tuttle::host::ofx::imageEffect::OfxhImageEffectHost& host )
00015         : OfxhPluginAPICacheI( kOfxImageEffectPluginApi, 1, 1 )
00016         , _host( &host ) {}
00017 
00018 OfxhImageEffectPluginCache::~OfxhImageEffectPluginCache() {}
00019 
00020 /**
00021  * get the plugin by id.  vermaj and vermin can be specified.  if they are not it will
00022  * pick the highest found version.
00023  */
00024 OfxhImageEffectPlugin* OfxhImageEffectPluginCache::getPluginById( const std::string& id, int vermaj, int vermin )
00025 {
00026         std::string idLower = id;
00027         boost::to_lower( idLower );
00028         
00029         if( vermaj == -1 &&  vermin == -1 )
00030                 return _pluginsByID[idLower];
00031 
00032         // return the highest version one, which fits the pattern provided
00033         OfxhImageEffectPlugin* sofar = 0;
00034 
00035         for( std::vector<OfxhImageEffectPlugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i )
00036         {
00037                 OfxhImageEffectPlugin& p = **i;
00038 
00039                 if( p.getIdentifier() != idLower )
00040                 {
00041                         continue;
00042                 }
00043 
00044                 if( vermaj != -1 && p.getVersionMajor() != vermaj )
00045                 {
00046                         continue;
00047                 }
00048 
00049                 if( vermin != -1 && p.getVersionMinor() != vermin )
00050                 {
00051                         continue;
00052                 }
00053 
00054                 if( !sofar || p.trumps( *sofar ) )
00055                 {
00056                         sofar = &p;
00057                 }
00058         }
00059         return sofar;
00060 }
00061 
00062 /**
00063  * get the plugin by label. vermaj and vermin can be specified.  if they are not it will
00064  * pick the highest found version.
00065  */
00066 OfxhImageEffectPlugin* OfxhImageEffectPluginCache::getPluginByLabel( const std::string& label, int vermaj, int vermin )
00067 {
00068         // return the highest version one, which fits the pattern provided
00069         OfxhImageEffectPlugin* sofar = 0;
00070 
00071         for( std::vector<OfxhImageEffectPlugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i )
00072         {
00073                 OfxhImageEffectPlugin& p = **i;
00074 
00075                 if( p.getDescriptor().getProperties().getStringProperty( kOfxPropLabel ) != label )
00076                 {
00077                         continue;
00078                 }
00079 
00080                 if( vermaj != -1 && p.getVersionMajor() != vermaj )
00081                 {
00082                         continue;
00083                 }
00084 
00085                 if( vermin != -1 && p.getVersionMinor() != vermin )
00086                 {
00087                         continue;
00088                 }
00089 
00090                 if( !sofar || p.trumps( *sofar ) )
00091                 {
00092                         sofar = &p;
00093                 }
00094         }
00095 
00096         return sofar;
00097 }
00098 
00099 const std::vector<OfxhImageEffectPlugin*>& OfxhImageEffectPluginCache::getPlugins() const
00100 {
00101         return _plugins;
00102 }
00103 
00104 const std::map<std::string, OfxhImageEffectPlugin*>& OfxhImageEffectPluginCache::getPluginsByID() const
00105 {
00106         return _pluginsByID;
00107 }
00108 
00109 /**
00110  * handle the case where the info needs filling in from the file.
00111  * Runs the "describe" action on the plugin.
00112  */
00113 void OfxhImageEffectPluginCache::loadFromPlugin( OfxhPlugin& op )
00114 {
00115         std::string msg = "loading ";
00116 
00117         msg += op.getRawIdentifier();
00118 
00119         _host->loadingStatus( msg );
00120 
00121         OfxhImageEffectPlugin& p = dynamic_cast<OfxhImageEffectPlugin&>( op );
00122 
00123         OfxhPluginHandle plug( p, getHost() );
00124 
00125         int rval = plug->mainEntry( kOfxActionLoad, 0, 0, 0 );
00126         
00127         if( rval != kOfxStatOK && rval != kOfxStatReplyDefault )
00128         {
00129                 BOOST_THROW_EXCEPTION( exception::OfxCustom( rval )
00130                     << exception::user( "Loading plugin failed." )
00131                     << exception::dev( "kOfxActionLoad failed." )
00132                     << exception::pluginIdentifier( op.getIdentifier() ) );
00133         }
00134 
00135         rval = plug->mainEntry( kOfxActionDescribe, p.getDescriptor().getHandle(), 0, 0 );
00136 
00137         if( rval != kOfxStatOK && rval != kOfxStatReplyDefault )
00138         {
00139                 BOOST_THROW_EXCEPTION( exception::OfxCustom( rval )
00140                     << exception::user( "Loading plugin failed." )
00141                     << exception::dev( "kOfxActionDescribe failed." )
00142                     << exception::pluginIdentifier( op.getIdentifier() ) );
00143         }
00144 
00145         const imageEffect::OfxhImageEffectNodeDescriptor& e = p.getDescriptor();
00146         const property::OfxhSet& eProps                     = e.getProperties();
00147 
00148         const int size = eProps.getDimension( kOfxImageEffectPropSupportedContexts );
00149 
00150         for( int j = 0; j < size; ++j )
00151         {
00152                 std::string context = eProps.getStringProperty( kOfxImageEffectPropSupportedContexts, j );
00153                 p.addContext( context );
00154         }
00155 
00156         rval = plug->mainEntry( kOfxActionUnload, 0, 0, 0 );
00157 
00158         if( rval != kOfxStatOK && rval != kOfxStatReplyDefault )
00159         {
00160                 BOOST_THROW_EXCEPTION( exception::OfxCustom( rval )
00161                     << exception::user( "Unloading plugin failed in initialization." )
00162                     << exception::dev( "kOfxActionUnload failed." )
00163                     << exception::pluginIdentifier( op.getIdentifier() ) );
00164         }
00165 }
00166 
00167 void OfxhImageEffectPluginCache::confirmPlugin( OfxhPlugin& p )
00168 {
00169         OfxhImageEffectPlugin& plugin = dynamic_cast<OfxhImageEffectPlugin&>( p );
00170 
00171         _plugins.push_back( &plugin );
00172 
00173         if( _pluginsByID.find( plugin.getIdentifier() ) != _pluginsByID.end() )
00174         {
00175                 OfxhImageEffectPlugin& otherPlugin = *_pluginsByID[plugin.getIdentifier()];
00176                 if( plugin.trumps( otherPlugin ) )
00177                 {
00178                         _pluginsByID[plugin.getIdentifier()] = &plugin;
00179                 }
00180         }
00181         else
00182         {
00183                 _pluginsByID[plugin.getIdentifier()] = &plugin;
00184         }
00185 
00186         OfxhMajorPlugin maj( plugin );
00187 
00188         if( _pluginsByIDMajor.find( maj ) != _pluginsByIDMajor.end() )
00189         {
00190                 OfxhImageEffectPlugin& otherPlugin = *_pluginsByIDMajor[maj];
00191                 if( plugin.getVersionMajor() != otherPlugin.getVersionMajor() || plugin.trumps( otherPlugin ) )
00192                 {
00193                         _pluginsByIDMajor[maj] = &plugin;
00194                 }
00195         }
00196         else
00197         {
00198                 _pluginsByIDMajor[maj] = &plugin;
00199         }
00200 }
00201 
00202 /// whether we support this plugin.
00203 bool OfxhImageEffectPluginCache::pluginSupported( const tuttle::host::ofx::OfxhPlugin& p, std::string& reason ) const
00204 {
00205         const OfxhImageEffectPlugin* imageEffectPlugin = dynamic_cast<const OfxhImageEffectPlugin*>( &p );
00206 
00207         if( !imageEffectPlugin )
00208                 return false;
00209         return core().getHost().pluginSupported( *imageEffectPlugin, reason );
00210 }
00211 
00212 OfxhPlugin* OfxhImageEffectPluginCache::newPlugin( OfxhPluginBinary& pb,
00213                                                    int               pi,
00214                                                    OfxPlugin&        pl )
00215 {
00216         OfxhImageEffectPlugin* plugin = new OfxhImageEffectPlugin( *this, pb, pi, pl );
00217 
00218         return plugin;
00219 }
00220 
00221 OfxhPlugin* OfxhImageEffectPluginCache::newPlugin( OfxhPluginBinary&  pb,
00222                                                    int                pi,
00223                                                    const std::string& api,
00224                                                    int                apiVersion,
00225                                                    const std::string& pluginId,
00226                                                    const std::string& rawId,
00227                                                    int                pluginMajorVersion,
00228                                                    int                pluginMinorVersion )
00229 {
00230         OfxhImageEffectPlugin* plugin = new OfxhImageEffectPlugin( *this, pb, pi, api, apiVersion, pluginId, rawId, pluginMajorVersion, pluginMinorVersion );
00231 
00232         return plugin;
00233 }
00234 
00235 std::ostream& operator<<( std::ostream& os, const OfxhImageEffectPluginCache& v )
00236 {
00237         os << "OfxhImageEffectPluginCache {" << std::endl;
00238 
00239         if( v._pluginsByID.empty() )
00240         {
00241                 os << "No Plug-ins Found." << std::endl;
00242                 os << "}" << std::endl;
00243                 return os;
00244         }
00245         os << "Nb Plugins:" << v._pluginsByID.size() << std::endl;
00246         
00247         os << "________________________________________________________________________________" << std::endl;
00248         for( std::map<std::string, OfxhImageEffectPlugin*>::const_iterator it = v._pluginsByID.begin(); it != v._pluginsByID.end(); ++it )
00249         {
00250                 os << "Plug-in:" << it->first << std::endl;
00251                 os << "  " << "Filepath: " << it->second->getBinary().getFilePath();
00252                 os << "(" << it->second->getIndex() << ")" << std::endl;
00253 
00254                 os << "Contexts:" << std::endl;
00255                 const std::set<std::string>& contexts = it->second->getContexts();
00256                 for( std::set<std::string>::const_iterator it2 = contexts.begin(); it2 != contexts.end(); ++it2 )
00257                         os << "  * " << *it2 << std::endl;
00258                 const OfxhImageEffectNodeDescriptor& d = it->second->getDescriptor();
00259                 os << "Inputs:" << std::endl;
00260                 const std::map<std::string, attribute::OfxhClipImageDescriptor*>& inputs = d.getClips();
00261                 for( std::map<std::string, attribute::OfxhClipImageDescriptor*>::const_iterator it2 = inputs.begin(); it2 != inputs.end(); ++it2 )
00262                         os << "    * " << it2->first << std::endl;
00263                 os << "________________________________________________________________________________" << std::endl;
00264         }
00265         os << "}" << std::endl;
00266         return os;
00267 }
00268 
00269 }
00270 }
00271 }
00272 }
00273