TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/host/Core.cpp
Go to the documentation of this file.
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