TuttleOFX
1
|
00001 #include "Core.hpp" 00002 00003 #include <tuttle/host/ofx/OfxhImageEffectPlugin.hpp> 00004 #include <tuttle/host/memory/MemoryPool.hpp> 00005 #include <tuttle/host/memory/MemoryCache.hpp> 00006 00007 #include <tuttle/common/system/system.hpp> 00008 00009 #include <boost/archive/xml_oarchive.hpp> 00010 #include <boost/archive/binary_oarchive.hpp> 00011 #include <boost/archive/text_oarchive.hpp> 00012 #include <boost/archive/xml_iarchive.hpp> 00013 #include <boost/archive/binary_iarchive.hpp> 00014 #include <boost/archive/text_iarchive.hpp> 00015 00016 #include <boost/serialization/serialization.hpp> 00017 #include <boost/serialization/nvp.hpp> 00018 00019 #include <boost/uuid/uuid.hpp> 00020 #include <boost/uuid/uuid_io.hpp> 00021 #include <boost/uuid/uuid_generators.hpp> 00022 00023 #include <boost/filesystem/operations.hpp> 00024 #include <boost/filesystem/convenience.hpp> 00025 00026 #ifdef TUTTLE_HOST_WITH_PYTHON_EXPRESSION 00027 #include <boost/python.hpp> 00028 #endif 00029 00030 #include <stdexcept> 00031 #include <iostream> 00032 #include <fstream> 00033 #include <vector> 00034 #include <cstring> // memset 00035 00036 namespace tuttle { 00037 namespace host { 00038 00039 namespace { 00040 memory::MemoryPool pool; 00041 memory::MemoryCache cache; 00042 } 00043 00044 Core::Core() 00045 : _imageEffectPluginCache( _host ) 00046 , _memoryPool( pool ) 00047 , _memoryCache( cache ) 00048 , _isPreloaded( false ) 00049 , _formatter( tuttle::common::Formatter::get() ) 00050 { 00051 #ifdef TUTTLE_HOST_WITH_PYTHON_EXPRESSION 00052 Py_Initialize( ); 00053 #endif 00054 _pluginCache.setCacheVersion( "tuttleV1" ); 00055 00056 // register the image effect cache with the global plugin cache 00057 _pluginCache.registerAPICache( _imageEffectPluginCache ); 00058 00059 _memoryPool.updateMemoryAuthorizedWithRAM(); 00060 // preload(); 00061 } 00062 00063 Core::~Core() 00064 {} 00065 00066 void Core::preload( const bool useCache ) 00067 { 00068 if( _isPreloaded ) 00069 return; 00070 00071 _isPreloaded = true; 00072 00073 // typedef boost::archive::binary_oarchive OArchive; 00074 // typedef boost::archive::binary_iarchive IArchive; 00075 // typedef boost::archive::text_oarchive OArchive; 00076 // typedef boost::archive::text_iarchive IArchive; 00077 typedef boost::archive::xml_oarchive OArchive; 00078 typedef boost::archive::xml_iarchive IArchive; 00079 00080 std::string cacheFile; 00081 if( useCache ) 00082 { 00083 cacheFile = (getPreferences().getTuttleHomePath() / "tuttlePluginCacheSerialize.xml").string(); 00084 00085 TUTTLE_LOG_DEBUG( TUTTLE_INFO, "plugin cache file = " << cacheFile ); 00086 00087 if( boost::filesystem::exists(cacheFile) ) 00088 { 00089 try 00090 { 00091 std::ifstream ifsb( cacheFile.c_str(), std::ios::in ); 00092 { 00093 TUTTLE_LOG_DEBUG( TUTTLE_INFO, "Read plugins cache." ); 00094 IArchive iArchive( ifsb ); 00095 iArchive >> BOOST_SERIALIZATION_NVP( _pluginCache ); 00096 // Destructor for an archive should be called before the stream is closed. It restores any altered stream facets to thier state before the the archive was opened. 00097 } 00098 } 00099 catch( std::exception& e ) 00100 { 00101 TUTTLE_LOG_WARNING( "Error when reading plugins cache file (" << e.what() << ")." ); 00102 // Clear the plugins cache to be sure that we don't stay in an unknown state. 00103 _pluginCache.clearPluginFiles(); 00104 00105 // As the plugins cache will be declared dirty, the cache file will be recreated. 00106 } 00107 } 00108 } 00109 _pluginCache.scanPluginFiles(); 00110 if( useCache && _pluginCache.isDirty() ) 00111 { 00112 // generate unique name for writing 00113 boost::uuids::random_generator gen; 00114 boost::uuids::uuid u = gen(); 00115 const std::string tmpCacheFile( cacheFile + ".writing." + boost::uuids::to_string(u) + ".xml" ); 00116 00117 TUTTLE_LOG_DEBUG( TUTTLE_INFO, "Write plugins cache " << tmpCacheFile ); 00118 try 00119 { 00120 // Serialize into a temporary file 00121 { 00122 std::ofstream ofsb( tmpCacheFile.c_str(), std::ios::out ); 00123 { 00124 OArchive oArchive( ofsb ); 00125 oArchive << BOOST_SERIALIZATION_NVP( _pluginCache ); 00126 // Destructor for an archive should be called before the stream is closed. It restores any altered stream facets to thier state before the the archive was opened. 00127 } 00128 } 00129 // Replace the cache file 00130 boost::filesystem::rename( tmpCacheFile, cacheFile ); 00131 } 00132 catch( std::exception& e ) 00133 { 00134 TUTTLE_LOG_WARNING( "Error when writing plugins cache file (" << e.what() << ")." ); 00135 try 00136 { 00137 // Try to remove the bad temporary cache file. 00138 if( boost::filesystem::exists(tmpCacheFile) ) 00139 { 00140 boost::filesystem::remove(tmpCacheFile); 00141 } 00142 } 00143 catch( std::exception& e ) 00144 {} 00145 } 00146 } 00147 } 00148 00149 std::ostream& operator<<( std::ostream& os, const Core& v ) 00150 { 00151 os << "Core {" << std::endl; 00152 os << v.getImageEffectPluginCache(); 00153 os << "}" << std::endl; 00154 return os; 00155 } 00156 00157 } 00158 } 00159