TuttleOFX
1
|
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