TuttleOFX
1
|
00001 /* 00002 * Software License : 00003 * 00004 * Copyright (c) 2007-2009, The Open Effects Association Ltd. All Rights Reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are met: 00008 * 00009 * Redistributions of source code must retain the above copyright notice, 00010 * this list of conditions and the following disclaimer. 00011 * Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions and the following disclaimer in the documentation 00013 * and/or other materials provided with the distribution. 00014 * Neither the name The Open Effects Association Ltd, nor the names of its 00015 * contributors may be used to endorse or promote products derived from this 00016 * software without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00019 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00020 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00021 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 00022 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00023 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00024 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00025 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00026 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00027 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00028 */ 00029 #ifndef _TUTTLE_HOST_OFX_PLUGINCACHE_HPP_ 00030 #define _TUTTLE_HOST_OFX_PLUGINCACHE_HPP_ 00031 00032 #include "property/OfxhSet.hpp" 00033 #include "OfxhPluginAPICache.hpp" 00034 #include "OfxhPluginBinary.hpp" 00035 00036 #include <ofxCore.h> 00037 00038 #include <boost/serialization/string.hpp> 00039 #include <boost/serialization/set.hpp> 00040 #include <boost/serialization/list.hpp> 00041 #include <boost/ptr_container/serialize_ptr_list.hpp> 00042 #include <boost/foreach.hpp> 00043 00044 #include <string> 00045 #include <set> 00046 #include <algorithm> 00047 #include <iostream> 00048 00049 namespace tuttle { 00050 namespace host { 00051 namespace ofx { 00052 00053 struct PluginCacheSupportedApi; 00054 00055 /** 00056 * Where we keep our plugins. 00057 */ 00058 class OfxhPluginCache 00059 { 00060 public: 00061 typedef OfxhPluginCache This; 00062 typedef boost::ptr_list<OfxhPluginBinary> OfxhPluginBinaryList; 00063 00064 protected: 00065 std::list<std::string> _pluginPath; ///< list of directories to look in 00066 std::set<std::string> _nonrecursePath; ///< list of directories to look in (non-recursively) 00067 std::list<std::string> _pluginDirs; ///< list of directories we found 00068 00069 OfxhPluginBinaryList _binaries; ///< all the binaries we know about, we own these 00070 std::list<OfxhPlugin*> _plugins; ///< all the plugins inside the binaries, we don't own these, populated from _binaries 00071 std::map<std::string, OfxhPlugin*> _pluginsByID; 00072 std::map<OfxhPluginIdent, bool> _loadedMap; ///< Used to check if a plugin is loaded twice 00073 std::set<std::string> _knownBinFiles; 00074 00075 std::list<PluginCacheSupportedApi> _apiHandlers; 00076 00077 // internal state 00078 bool _ignoreCache; 00079 std::string _cacheVersion; 00080 bool _dirty; 00081 bool _enablePluginSeek; ///< Turn off to make all seekPluginFile() calls return an empty string 00082 00083 public: 00084 /// ctor, which inits _pluginPath to default locations and not much else 00085 OfxhPluginCache(); 00086 00087 /// dtor 00088 ~OfxhPluginCache(); 00089 00090 protected: 00091 void scanDirectory( std::set<std::string>& foundBinFiles, const std::string& dir, bool recurse ); 00092 00093 void addPlugin( OfxhPlugin* plugin ); 00094 00095 public: 00096 friend std::ostream& operator<<( std::ostream& os, const This& g ); 00097 00098 public: 00099 /// get the plugin by id. vermaj and vermin can be specified. if they are not it will 00100 /// pick the highest found version. 00101 OfxhPlugin* getPluginById( const std::string& id, int vermaj = -1, int vermin = -1 ); 00102 const OfxhPlugin* getPluginById( const std::string& id, int vermaj = -1, int vermin = -1 ) const { return const_cast<This&>( *this ).getPluginById( id, vermaj, vermin ); } 00103 00104 /// get the list in which plugins are sought 00105 const std::list<std::string>& getPluginPath() const 00106 { 00107 return _pluginPath; 00108 } 00109 00110 /// was the cache outdated? 00111 bool isDirty() const 00112 { 00113 return _dirty; 00114 } 00115 00116 void setDirty() 00117 { 00118 //TUTTLE_TLOG( TUTTLE_INFO, "OfxhPluginCache::setDirty()" ); 00119 _dirty = true; 00120 } 00121 00122 /// add a directory to the plugin path 00123 void addDirectoryToPath( const std::string& f, bool recurse = true ) 00124 { 00125 _pluginPath.push_back( f ); 00126 if( !recurse ) 00127 { 00128 _nonrecursePath.insert( f ); 00129 } 00130 } 00131 00132 /// specify which subdirectory of /usr/OFX or equivilant 00133 /// (as well as 'Plugins') to look in for plugins. 00134 void setPluginHostPath( const std::string& hostId ); 00135 00136 /// set the version string to write to the cache, 00137 /// and also that we expect on cachess read in 00138 void setCacheVersion( const std::string& cacheVersion ) 00139 { 00140 _cacheVersion = cacheVersion; 00141 } 00142 00143 // populate the cache. must call scanPluginFiles() after to check for changes. 00144 //void readCache( std::istream& is ); 00145 00146 // seek a particular file on the OFX plugin path 00147 std::string seekPluginFile( const std::string& baseName ) const; 00148 00149 /// Sets behaviour of seekPluginFile(). 00150 /// Enable (the default): normal operation; disable: returns an empty string instead 00151 void setPluginSeekEnabled( bool enabled ) 00152 { 00153 _enablePluginSeek = enabled; 00154 } 00155 00156 /// scan for plugins 00157 void scanPluginFiles(); 00158 00159 /// Remove all plugins 00160 void clearPluginFiles(); 00161 00162 /// register an API cache handler 00163 void registerAPICache( APICache::OfxhPluginAPICacheI& apiCache ); 00164 00165 /// find the API cache handler for the given api/apiverson 00166 APICache::OfxhPluginAPICacheI* findApiHandler( const std::string& api, int apiver ); 00167 00168 /// obtain a list of plugins to walk through 00169 const std::list<OfxhPlugin*>& getPlugins() const 00170 { 00171 return _plugins; 00172 } 00173 00174 OfxhPluginBinaryList& getBinaries() 00175 { 00176 return _binaries; 00177 } 00178 00179 private: 00180 friend class boost::serialization::access; 00181 template<class Archive> 00182 void serialize( Archive& ar, const unsigned int version ) 00183 { 00184 // ar & BOOST_SERIALIZATION_NVP(_pluginPath); 00185 // ar & BOOST_SERIALIZATION_NVP(_nonrecursePath); 00186 // ar & BOOST_SERIALIZATION_NVP(_pluginDirs); 00187 ar& BOOST_SERIALIZATION_NVP( _binaries ); 00188 // ar & BOOST_SERIALIZATION_NVP(_plugins); // just a link, don't save this 00189 // ar& BOOST_SERIALIZATION_NVP( _knownBinFiles ); 00190 00191 if( typename Archive::is_loading() ) 00192 { 00193 BOOST_FOREACH( OfxhPluginBinary& pluginBinary, _binaries ) 00194 { 00195 _knownBinFiles.insert( pluginBinary.getFilePath() ); 00196 BOOST_FOREACH( OfxhPlugin& plugin, pluginBinary.getPlugins() ) 00197 { 00198 APICache::OfxhPluginAPICacheI* apiCache = findApiHandler( plugin.getPluginApi(), plugin.getApiVersion() ); 00199 plugin.setApiHandler( *apiCache ); 00200 _plugins.push_back( &plugin ); 00201 } 00202 } 00203 } 00204 } 00205 00206 }; 00207 00208 } 00209 } 00210 } 00211 00212 #endif