TuttleOFX
1
|
00001 #ifndef OFXH_PLUGINBINARY_HPP 00002 #define OFXH_PLUGINBINARY_HPP 00003 00004 #include "OfxhPlugin.hpp" 00005 #include "OfxhBinary.hpp" 00006 #include "OfxhCore.hpp" 00007 00008 #include <boost/ptr_container/serialize_ptr_vector.hpp> 00009 #include <boost/serialization/string.hpp> 00010 00011 namespace tuttle { 00012 namespace host { 00013 namespace ofx { 00014 00015 class OfxhPluginLoadGuard; 00016 class OfxhPluginCache; 00017 00018 /** 00019 * class that represents a binary file which holds plugins. 00020 * Has a set of plugins inside it and which it owns 00021 * These are owned by a PluginCache 00022 */ 00023 class OfxhPluginBinary 00024 { 00025 public: 00026 typedef OfxhPluginBinary This; 00027 typedef boost::ptr_vector<OfxhPlugin> PluginVector; 00028 00029 friend class OfxhPluginLoadGuard; 00030 00031 protected: 00032 OfxhBinary _binary; ///< our binary object, abstracted layer ontop of OS calls, defined in OfxhBinary.hpp 00033 std::string _filePath; ///< full path to the file 00034 std::string _bundlePath; ///< path to the .bundle directory 00035 PluginVector _plugins; ///< my plugins 00036 time_t _fileModificationTime; ///< used as a time stamp to check modification times, used for caching 00037 size_t _fileSize; ///< file size last time we check, used for caching 00038 bool _binaryChanged; ///< whether the timestamp/filesize in this cache is different from that in the actual binary 00039 00040 private: 00041 explicit OfxhPluginBinary() 00042 : _fileModificationTime( 0 ) 00043 , _fileSize( 0 ) 00044 , _binaryChanged( false ) 00045 {} 00046 00047 public: 00048 /// create one from the cache. this will invoke the Binary() constructor which 00049 /// will stat() the file. 00050 00051 explicit OfxhPluginBinary( const std::string& file, const std::string& bundlePath, time_t mtime, size_t size ) 00052 : _binary( file ) 00053 , _filePath( file ) 00054 , _bundlePath( bundlePath ) 00055 , _fileModificationTime( mtime ) 00056 , _fileSize( size ) 00057 , _binaryChanged( false ) 00058 { 00059 checkBinaryChanged(); 00060 } 00061 00062 /// constructor which will open a library file, call things inside it, and then 00063 /// create Plugin objects as appropriate for the plugins exported therefrom 00064 00065 explicit OfxhPluginBinary( const std::string& file, const std::string& bundlePath, OfxhPluginCache* cache ) 00066 : _binary( file ) 00067 , _filePath( file ) 00068 , _bundlePath( bundlePath ) 00069 , _binaryChanged( false ) 00070 { 00071 loadPluginInfo( cache ); 00072 } 00073 00074 /// dtor 00075 virtual ~OfxhPluginBinary(); 00076 00077 private: 00078 void checkBinaryChanged() 00079 { 00080 if( _fileModificationTime != _binary.getTime() || _fileSize != _binary.getSize() ) 00081 { 00082 _binaryChanged = true; 00083 } 00084 } 00085 00086 public: 00087 bool operator==( const This& other ) const 00088 { 00089 if( _binary != other._binary || 00090 _filePath != other._filePath || 00091 _bundlePath != other._bundlePath || 00092 _plugins != other._plugins || 00093 _fileModificationTime != other._fileModificationTime || 00094 _fileSize != other._fileSize || 00095 _binaryChanged != other._binaryChanged ) 00096 return false; 00097 return true; 00098 } 00099 00100 bool operator!=( const This& other ) const { return !This::operator==( other ); } 00101 00102 time_t getFileModificationTime() const 00103 { 00104 return _fileModificationTime; 00105 } 00106 00107 size_t getFileSize() const 00108 { 00109 return _fileSize; 00110 } 00111 00112 const std::string& getFilePath() const 00113 { 00114 return _filePath; 00115 } 00116 00117 const std::string& getBundlePath() const 00118 { 00119 return _bundlePath; 00120 } 00121 00122 const std::string getResourcesPath() const 00123 { 00124 return _bundlePath + "/Contents/Resources"; 00125 } 00126 00127 bool hasBinaryChanged() const 00128 { 00129 return _binaryChanged; 00130 } 00131 00132 bool isLoaded() const 00133 { 00134 return _binary.isLoaded(); 00135 } 00136 00137 #ifndef SWIG 00138 void addPlugin( OfxhPlugin* pe ) 00139 { 00140 _plugins.push_back( pe ); 00141 } 00142 void loadPluginInfo( OfxhPluginCache* ); 00143 #endif 00144 00145 /// how many plugins? 00146 int getNPlugins() const 00147 { 00148 return (int) _plugins.size(); 00149 } 00150 00151 /// get plugins 00152 PluginVector& getPlugins() 00153 { 00154 return _plugins; 00155 } 00156 00157 /// get plugins 00158 const PluginVector& getPlugins() const 00159 { 00160 return _plugins; 00161 } 00162 00163 /// get a plugin 00164 OfxhPlugin& getPlugin( int idx ) 00165 { 00166 return _plugins[idx]; 00167 } 00168 00169 /// get a plugin 00170 const OfxhPlugin& getPlugin( int idx ) const 00171 { 00172 return _plugins[idx]; 00173 } 00174 00175 private: 00176 friend class boost::serialization::access; 00177 template<class Archive> 00178 void serialize( Archive& ar, const unsigned int version ) 00179 { 00180 ar& BOOST_SERIALIZATION_NVP( _filePath ); 00181 ar& BOOST_SERIALIZATION_NVP( _bundlePath ); 00182 ar& BOOST_SERIALIZATION_NVP( _plugins ); 00183 ar& BOOST_SERIALIZATION_NVP( _fileModificationTime ); 00184 ar& BOOST_SERIALIZATION_NVP( _fileSize ); 00185 00186 if( typename Archive::is_loading() ) 00187 { 00188 _binary.init( _filePath ); 00189 checkBinaryChanged(); 00190 00191 for( PluginVector::iterator it = getPlugins().begin(), itEnd = getPlugins().end(); 00192 it != itEnd; 00193 ++it ) 00194 { 00195 it->setBinary( *this ); 00196 } 00197 } 00198 } 00199 }; 00200 00201 } 00202 } 00203 } 00204 00205 #endif 00206