TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/host/ofx/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 OfxhImageEffectPluginCache::MapPluginsByID& 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         OfxhPluginLoadGuard plug( p, getHost() );
00124 
00125         int rval = plug->mainEntry( kOfxActionLoad, 0, 0, 0 );
00126         
00127         if( rval != kOfxStatOK && rval != kOfxStatReplyDefault )
00128         {
00129                 op.setIsSupported(false);
00130                 BOOST_THROW_EXCEPTION( exception::OfxCustom( rval )
00131                     << exception::user( "Loading plugin failed." )
00132                     << exception::dev( "kOfxActionLoad failed." )
00133                     << exception::pluginIdentifier( op.getIdentifier() ) );
00134         }
00135 
00136         rval = plug->mainEntry( kOfxActionDescribe, p.getDescriptor().getHandle(), 0, 0 );
00137 
00138         if( rval != kOfxStatOK && rval != kOfxStatReplyDefault )
00139         {
00140                 op.setIsSupported(false);
00141                 BOOST_THROW_EXCEPTION( exception::OfxCustom( rval )
00142                     << exception::user( "Loading plugin failed." )
00143                     << exception::dev( "kOfxActionDescribe failed." )
00144                     << exception::pluginIdentifier( op.getIdentifier() ) );
00145         }
00146 
00147         const imageEffect::OfxhImageEffectNodeDescriptor& e = p.getDescriptor();
00148         const property::OfxhSet& eProps                     = e.getProperties();
00149 
00150         const int size = eProps.getDimension( kOfxImageEffectPropSupportedContexts );
00151 
00152         for( int j = 0; j < size; ++j )
00153         {
00154                 std::string context = eProps.getStringProperty( kOfxImageEffectPropSupportedContexts, j );
00155                 p.addContext( context );
00156         }
00157 
00158         op.setIsSupported(true);
00159         
00160         rval = plug->mainEntry( kOfxActionUnload, 0, 0, 0 );
00161 
00162         if( rval != kOfxStatOK && rval != kOfxStatReplyDefault )
00163         {
00164                 BOOST_THROW_EXCEPTION( exception::OfxCustom( rval )
00165                     << exception::user( "Unloading plugin failed in initialization." )
00166                     << exception::dev( "kOfxActionUnload failed." )
00167                     << exception::pluginIdentifier( op.getIdentifier() ) );
00168         }
00169 }
00170 
00171 void OfxhImageEffectPluginCache::confirmPlugin( OfxhPlugin& p )
00172 {
00173         OfxhImageEffectPlugin& plugin = dynamic_cast<OfxhImageEffectPlugin&>( p );
00174 
00175         _plugins.push_back( &plugin );
00176 
00177         if( _pluginsByID.find( plugin.getIdentifier() ) != _pluginsByID.end() )
00178         {
00179                 OfxhImageEffectPlugin& otherPlugin = *_pluginsByID[plugin.getIdentifier()];
00180                 if( plugin.trumps( otherPlugin ) )
00181                 {
00182                         _pluginsByID[plugin.getIdentifier()] = &plugin;
00183                 }
00184         }
00185         else
00186         {
00187                 _pluginsByID[plugin.getIdentifier()] = &plugin;
00188         }
00189 
00190         OfxhMajorPlugin maj( plugin );
00191 
00192         if( _pluginsByIDMajor.find( maj ) != _pluginsByIDMajor.end() )
00193         {
00194                 OfxhImageEffectPlugin& otherPlugin = *_pluginsByIDMajor[maj];
00195                 if( plugin.getVersionMajor() != otherPlugin.getVersionMajor() || plugin.trumps( otherPlugin ) )
00196                 {
00197                         _pluginsByIDMajor[maj] = &plugin;
00198                 }
00199         }
00200         else
00201         {
00202                 _pluginsByIDMajor[maj] = &plugin;
00203         }
00204 }
00205 
00206 /// whether we support this plugin.
00207 bool OfxhImageEffectPluginCache::pluginSupported( const tuttle::host::ofx::OfxhPlugin& p, std::string& reason ) const
00208 {
00209         const OfxhImageEffectPlugin* imageEffectPlugin = dynamic_cast<const OfxhImageEffectPlugin*>( &p );
00210 
00211         if( !imageEffectPlugin )
00212                 return false;
00213         return core().getHost().pluginSupported( *imageEffectPlugin, reason );
00214 }
00215 
00216 OfxhPlugin* OfxhImageEffectPluginCache::newPlugin( OfxhPluginBinary& pb,
00217                                                    int               pi,
00218                                                    OfxPlugin&        pl )
00219 {
00220         OfxhImageEffectPlugin* plugin = new OfxhImageEffectPlugin( *this, pb, pi, pl );
00221 
00222         return plugin;
00223 }
00224 
00225 OfxhPlugin* OfxhImageEffectPluginCache::newPlugin( OfxhPluginBinary&  pb,
00226                                                    int                pi,
00227                                                    const std::string& api,
00228                                                    int                apiVersion,
00229                                                    const std::string& pluginId,
00230                                                    const std::string& rawId,
00231                                                    int                pluginMajorVersion,
00232                                                    int                pluginMinorVersion )
00233 {
00234         OfxhImageEffectPlugin* plugin = new OfxhImageEffectPlugin( *this, pb, pi, api, apiVersion, pluginId, rawId, pluginMajorVersion, pluginMinorVersion );
00235 
00236         return plugin;
00237 }
00238 
00239 std::ostream& operator<<( std::ostream& os, const OfxhImageEffectPluginCache& v )
00240 {
00241         os << "OfxhImageEffectPluginCache {" << std::endl;
00242 
00243         if( v._pluginsByID.empty() )
00244         {
00245                 os << "No Plug-ins Found." << std::endl;
00246                 os << "}" << std::endl;
00247                 return os;
00248         }
00249         os << "Nb Plugins:" << v._pluginsByID.size() << std::endl;
00250         
00251         os << "________________________________________________________________________________" << std::endl;
00252         for( OfxhImageEffectPluginCache::MapPluginsByID::const_iterator it = v._pluginsByID.begin(); it != v._pluginsByID.end(); ++it )
00253         {
00254                 os << "Plug-in:" << it->first << std::endl;
00255                 os << "  " << "Filepath: " << it->second->getBinary().getFilePath();
00256                 os << "(" << it->second->getIndex() << ")" << std::endl;
00257 
00258                 os << "Contexts:" << std::endl;
00259                 const std::set<std::string>& contexts = it->second->getContexts();
00260                 for( std::set<std::string>::const_iterator it2 = contexts.begin(); it2 != contexts.end(); ++it2 )
00261                         os << "  * " << *it2 << std::endl;
00262                 const OfxhImageEffectNodeDescriptor& d = it->second->getDescriptor();
00263                 os << "Inputs:" << std::endl;
00264                 const std::map<std::string, attribute::OfxhClipImageDescriptor*>& inputs = d.getClips();
00265                 for( std::map<std::string, attribute::OfxhClipImageDescriptor*>::const_iterator it2 = inputs.begin(); it2 != inputs.end(); ++it2 )
00266                         os << "    * " << it2->first << std::endl;
00267                 os << "________________________________________________________________________________" << std::endl;
00268         }
00269         os << "}" << std::endl;
00270         return os;
00271 }
00272 
00273 }
00274 }
00275 }
00276 }
00277