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