OpenWalnut  1.4.0
WKernel.cpp
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifdef __linux__
00026     #include <unistd.h> // used for getcwd (to get current directory)
00027 #endif
00028 
00029 #if defined(__APPLE__)
00030     #include <mach-o/dyld.h>
00031 #endif
00032 
00033 #include <string>
00034 #include <vector>
00035 
00036 #include "../common/WLogger.h"
00037 #include "../common/WThreadedRunner.h"
00038 #include "../common/WTimer.h"
00039 #include "../common/WRealtimeTimer.h"
00040 #include "../dataHandler/WDataHandler.h"
00041 #include "../ui/WUI.h"
00042 #include "exceptions/WKernelException.h"
00043 #include "WKernel.h"
00044 #include "WModuleContainer.h"
00045 #include "WModuleFactory.h"
00046 #include "WROIManager.h"
00047 #include "WSelectionManager.h"
00048 
00049 #include "core/WVersion.h"   // NOTE: this file is auto-generated by CMAKE
00050 
00051 /**
00052  * Used for program wide access to the kernel.
00053  */
00054 WKernel* WKernel::m_kernel = NULL;
00055 
00056 WKernel::WKernel( boost::shared_ptr< WGraphicsEngine > ge, boost::shared_ptr< WUI > ui ):
00057     WThreadedRunner(),
00058     m_timer( WTimer::SPtr( new WRealtimeTimer() ) )
00059 {
00060     WLogger::getLogger()->addLogMessage( "Initializing Kernel", "Kernel", LL_INFO );
00061     wlog::debug( "Kernel" ) << "Version: " << W_VERSION;
00062 
00063     setThreadName( "Kernel" );
00064 
00065     // init the singleton
00066     m_kernel = this;
00067 
00068     // initialize members
00069     m_ui = ui;
00070     m_graphicsEngine = ge;
00071 
00072     // init
00073     init();
00074 }
00075 
00076 WKernel::~WKernel()
00077 {
00078     // cleanup
00079     WLogger::getLogger()->addLogMessage( "Shutting down Kernel", "Kernel", LL_INFO );
00080 }
00081 
00082 WKernel* WKernel::instance( boost::shared_ptr< WGraphicsEngine > ge, boost::shared_ptr< WUI > ui )
00083 {
00084     if( m_kernel == NULL )
00085     {
00086         new WKernel( ge, ui ); // m_kernel will be set in the constructor.
00087     }
00088 
00089     return m_kernel;
00090 }
00091 
00092 void WKernel::init()
00093 {
00094     // initialize
00095     m_roiManager = boost::shared_ptr< WROIManager >( new WROIManager() );
00096 
00097     m_selectionManager = boost::shared_ptr< WSelectionManager >( new WSelectionManager() );
00098 
00099     // get module factory
00100     m_moduleFactory = WModuleFactory::getModuleFactory();
00101 
00102     // init data handler
00103     WDataHandler::getDataHandler();
00104 
00105     // initialize module container
00106     m_moduleContainer = boost::shared_ptr< WModuleContainer >( new WModuleContainer( "KernelRootContainer",
00107                 "Root module container in Kernel." ) );
00108     // this avoids the root container to be marked as "crashed" if a contained module crashes.
00109     m_moduleContainer->setCrashIfModuleCrashes( false );
00110 
00111     // load all modules
00112     m_moduleFactory->load();
00113 
00114     m_scriptEngine = boost::shared_ptr< WScriptEngine >( new WScriptEngine( m_moduleContainer ) );
00115 }
00116 
00117 WKernel* WKernel::getRunningKernel()
00118 {
00119     return m_kernel;
00120 }
00121 
00122 boost::shared_ptr< WGraphicsEngine > WKernel::getGraphicsEngine() const
00123 {
00124     return m_graphicsEngine;
00125 }
00126 
00127 boost::shared_ptr< WModuleContainer > WKernel::getRootContainer() const
00128 {
00129     return m_moduleContainer;
00130 }
00131 
00132 boost::shared_ptr< WUI > WKernel::getUI() const
00133 {
00134     return m_ui;
00135 }
00136 
00137 void WKernel::finalize()
00138 {
00139     WLogger::getLogger()->addLogMessage( "Stopping Kernel", "Kernel", LL_INFO );
00140 
00141     // NOTE: stopping a container erases all modules inside.
00142     getRootContainer()->stop();
00143 
00144     WLogger::getLogger()->addLogMessage( "Stopping Data Handler", "Kernel", LL_INFO );
00145     WDataHandler::getDataHandler()->clear();
00146 }
00147 
00148 void WKernel::threadMain()
00149 {
00150     WLogger::getLogger()->addLogMessage( "Starting Kernel", "Kernel", LL_INFO );
00151 
00152     // wait for UI to be initialized properly
00153     if( m_ui )
00154     {
00155         m_ui->isInitialized().wait();
00156     }
00157     else
00158     {
00159         wlog::warn( "Kernel" ) << "Expected UI instance but none was initialized.";
00160     }
00161 
00162     // start GE
00163     if( m_graphicsEngine )
00164     {
00165         m_graphicsEngine->run();
00166 
00167         // wait for it to be ready
00168         m_graphicsEngine->waitForFinalize();
00169     }
00170     else
00171     {
00172         wlog::warn( "Kernel" ) << "Expected GE instance but none was initialized.";
00173     }
00174 
00175     // do extension loading
00176     wlog::info( "Kernel" ) << "Initializing extensions.";
00177     WModuleFactory::getModuleLoader()->initializeExtensions();
00178 
00179     // done. Notify anyone waiting
00180     wlog::info( "Kernel" ) << "Initialization completed.";
00181     m_startupCompleted.notify();
00182 
00183     // actually there is nothing more to do here
00184     waitForStop();
00185 
00186     WLogger::getLogger()->addLogMessage( "Shutting down Kernel", "Kernel", LL_INFO );
00187 }
00188 
00189 const WBoolFlag& WKernel::isFinishRequested() const
00190 {
00191     return m_shutdownFlag;
00192 }
00193 
00194 WBatchLoader::SPtr WKernel::loadDataSets( std::vector< std::string > filenames, bool suppressColormaps )
00195 {
00196     return getRootContainer()->loadDataSets( filenames, suppressColormaps );
00197 }
00198 
00199 WBatchLoader::SPtr WKernel::loadDataSetsSynchronously( std::vector< std::string > filenames, bool suppressColormaps )
00200 {
00201     return getRootContainer()->loadDataSetsSynchronously( filenames, suppressColormaps );
00202 }
00203 
00204 boost::shared_ptr< WModule > WKernel::applyModule( boost::shared_ptr< WModule > applyOn, boost::shared_ptr< WModule > prototype )
00205 {
00206     return getRootContainer()->applyModule( applyOn, prototype );
00207 }
00208 
00209 boost::shared_ptr< WROIManager > WKernel::getRoiManager()
00210 {
00211     return m_roiManager;
00212 }
00213 
00214 boost::shared_ptr< WSelectionManager>WKernel::getSelectionManager()
00215 {
00216     return m_selectionManager;
00217 }
00218 
00219 boost::shared_ptr<WScriptEngine> WKernel::getScriptEngine()
00220 {
00221     return m_scriptEngine;
00222 }
00223 
00224 WTimer::ConstSPtr WKernel::getTimer() const
00225 {
00226     return m_timer;
00227 }
00228 
00229 boost::signals2::connection WKernel::subscribeSignal( WKernel::KERNEL_SIGNAL signal, WKernel::t_KernelGenericSignalHandlerType notifier )
00230 {
00231     switch( signal )
00232     {
00233         case KERNEL_STARTUPCOMPLETE:
00234             return m_startupCompleted.subscribeSignal( notifier );
00235         default:
00236             std::ostringstream s;
00237             s << "Could not subscribe to unknown signal.";
00238             throw WKernelException( s.str() );
00239             break;
00240     }
00241 }