WKernel.cpp 8.09 KB
Newer Older
ebaum's avatar
[ADD]  
ebaum committed
1 2
//---------------------------------------------------------------------------
//
3
// Project: OpenWalnut ( http://www.openwalnut.org )
ebaum's avatar
[ADD]  
ebaum committed
4
//
5 6
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
ebaum's avatar
[ADD]  
ebaum committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------

25 26 27 28
#ifdef __linux__
#include <unistd.h> // used for getcwd (to get current directory)
#endif

29 30 31 32
#if defined(__APPLE__)
#include <mach-o/dyld.h>
#endif

ebaum's avatar
[ADD]  
ebaum committed
33
#include <iostream>
ebaum's avatar
ebaum committed
34
#include <list>
35 36
#include <string>
#include <vector>
ebaum's avatar
ebaum committed
37

38
#include <boost/filesystem.hpp>
ebaum's avatar
ebaum committed
39
#include <boost/thread/xtime.hpp>
ebaum's avatar
[ADD]  
ebaum committed
40

ebaum's avatar
ebaum committed
41
#include "WModule.h"
42
#include "WModuleFactory.h"
43
#include "WBatchLoader.h"
ebaum's avatar
[ADD]  
ebaum committed
44
#include "../common/WException.h"
45
#include "../common/WCondition.h"
46
#include "../common/WConditionOneShot.h"
47
#include "../common/WFlag.h"
48
#include "../common/WPreferences.h"
ebaum's avatar
[ADD]  
ebaum committed
49

ebaum's avatar
ebaum committed
50 51
#include "../graphicsEngine/WGraphicsEngine.h"

52
#include "WKernel.h"
53

54
/**
ebaum's avatar
ebaum committed
55 56 57 58
 * Used for program wide access to the kernel.
 */
WKernel* kernel = NULL;

59 60 61 62 63 64 65 66 67 68
/**
 * Define shader path.
 */
std::string WKernel::m_shaderPath = std::string();

/**
 * Define app path.
 */
std::string WKernel::m_AppPath = std::string();

69
WKernel::WKernel( boost::shared_ptr< WGraphicsEngine > ge, boost::shared_ptr< WGUI > gui ):
70
    WThreadedRunner()
ebaum's avatar
[ADD]  
ebaum committed
71
{
72
    WLogger::getLogger()->addLogMessage( "Initializing Kernel", "Kernel", LL_INFO );
ebaum's avatar
ebaum committed
73

74
    // init the singleton
ebaum's avatar
ebaum committed
75 76
    kernel = this;

ebaum's avatar
[ADD]  
ebaum committed
77
    // initialize members
78 79
    m_gui = gui;
    m_graphicsEngine = ge;
80

81
    // init
ebaum's avatar
ebaum committed
82
    init();
ebaum's avatar
[ADD]  
ebaum committed
83 84 85 86 87
}

WKernel::~WKernel()
{
    // cleanup
88
    WLogger::getLogger()->addLogMessage( "Shutting down Kernel", "Kernel", LL_INFO );
ebaum's avatar
[ADD]  
ebaum committed
89 90
}

91
void WKernel::init()
ebaum's avatar
[ADD]  
ebaum committed
92
{
93
    // initialize
94 95 96 97 98 99 100 101 102 103
    findAppPath();

    // get module factory
    m_moduleFactory = WModuleFactory::getModuleFactory();

    // initialize module container
    m_moduleContainer = boost::shared_ptr< WModuleContainer >( new WModuleContainer( "KernelRootContainer",
                "Root module container in Kernel." ) );

    // initialize graphics engine, or, at least set some stuff
104
    m_graphicsEngine->setShaderPath( WKernel::m_shaderPath );
105 106 107

    // load all modules
    m_moduleFactory->load();
ebaum's avatar
[ADD]  
ebaum committed
108 109
}

ebaum's avatar
ebaum committed
110 111 112 113 114
WKernel* WKernel::getRunningKernel()
{
    return kernel;
}

115
boost::shared_ptr< WGraphicsEngine > WKernel::getGraphicsEngine() const
ebaum's avatar
ebaum committed
116
{
117
    return m_graphicsEngine;
ebaum's avatar
ebaum committed
118 119
}

Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
120
boost::shared_ptr< WModuleContainer > WKernel::getRootContainer() const
121
{
Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
122
    return m_moduleContainer;
123 124
}

Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
125
boost::shared_ptr< WGUI > WKernel::getGui() const
126
{
127
    return m_gui;
128 129
}

130
void WKernel::finalize()
Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
131
{
132
    WLogger::getLogger()->addLogMessage( "Stopping Kernel", "Kernel", LL_INFO );
133 134

    // NOTE: stopping a container erases all modules inside.
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
135
    getRootContainer()->stop();
Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
136 137
}

138
void WKernel::threadMain()
ebaum's avatar
ebaum committed
139
{
140
    WLogger::getLogger()->addLogMessage( "Starting Kernel", "Kernel", LL_INFO );
ebaum's avatar
ebaum committed
141

142
    // wait for GUI to be initialized properly
143
    m_gui->isInitialized().wait();
Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
144

145 146 147
    // start GE
    m_graphicsEngine->run();

148
    // default modules
149 150 151
    {
        bool ignore;
        m_moduleContainer->add( m_moduleFactory->create( m_moduleFactory->getPrototypeByName( "Navigation Slice Module" ) ) , true );
152
        m_moduleContainer->add( m_moduleFactory->create( m_moduleFactory->getPrototypeByName( "Coordinate System Module" ) ) , true );
153 154
        if( !( WPreferences::getPreference( "modules.standard.ignoreHUD", &ignore ) && ignore ) )
        {
155
            m_moduleContainer->add( m_moduleFactory->create( m_moduleFactory->getPrototypeByName( "HUD" ) ) , true );
156 157
        }
    }
158

159 160
    // actually there is nothing more to do here
    waitForStop();
161

162
    WLogger::getLogger()->addLogMessage( "Shutting down Kernel", "Kernel", LL_INFO );
163 164
}

165
void WKernel::findAppPath()
166
{
167 168 169 170 171 172
    // only get the path if not already done
    if ( m_AppPath != "" )
    {
        return;
    }

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
    if ( m_AppPath != "" )
    {
        return;
    }

    // unified version with boost::filesystem
    namespace fs = boost::filesystem;
    fs::path currentDir( fs::initial_path<fs::path>() );

    m_AppPath = currentDir.file_string();
//    std::cout << "Set app path to " << m_AppPath << std::endl;

    m_shaderPath = fs::path( currentDir / "shaders" ).file_string();
//    std::cout << "Set shader path to " << m_shaderPath << std::endl;
/*
188 189
    // FIXME (schurade)
    // this should work on linux, have to implement it for windows and mac later
Alexander Wiebel's avatar
Alexander Wiebel committed
190
#ifdef __linux__
191 192 193

    // This might be the better alternative to the below code but it does not print the path to the executable, but to the current
    // working directory, which in the unix world is the better choice as path
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
    char* appPath = get_current_dir_name();

    // int length;
    //char appPath[255];

    //length = readlink( "/proc/self/exe", appPath, sizeof( appPath ) );

    //// Catch some errors
    //if ( length < 0 )
    //{
    //    WLogger::getLogger()->addLogMessage( "Error resolving symlink /proc/self/exe.", "Kernel", LL_ERROR );
    //}
    //if ( length >= 255 )
    //{
    //    WLogger::getLogger()->addLogMessage( "Path too long. Truncated.", "Kernel", LL_ERROR );
    //}

    //// the string this readlink() function returns is appended with a '@'.
    //appPath[length] = '\0';

    //// strip off the executable name
    //while ( appPath[length] != '/' )
    //{
    //    appPath[length] = '\0';
    //    --length;
    //    assert( length >= 0 );
    //}
221 222

    m_AppPath = appPath;
223 224
    m_AppPath += "/";
    m_shaderPath = m_AppPath + "shaders/";
225

226 227
    // getcwd/get_current_dir_name() mallocs memory, free it here
    delete appPath;
228

schurade's avatar
schurade committed
229
#elif defined( __APPLE__ )
230
    char path[1024];
schurade's avatar
schurade committed
231
    uint32_t size = sizeof( path );
232
    if( _NSGetExecutablePath( path, &size ) == 0 )
233
    {
234
        WLogger::getLogger()->addLogMessage( "Executable path is " + std::string( path ), "Kernel", LL_DEBUG );
235 236

        int i = strlen( path );
schurade's avatar
schurade committed
237 238 239 240 241 242
        while( path[i] != '/' )
        {
            path[i] = '\0';
            i--;
            assert( i >= 0 );
        }
243
        WLogger::getLogger()->addLogMessage( "Application path is " + std::string( path ), "Kernel", LL_DEBUG );
schurade's avatar
schurade committed
244 245 246 247
        m_AppPath = path;

        std::string shaderPath( path );
        m_shaderPath = shaderPath + "shaders/";
248 249 250
    }
    else
    {
251
        WLogger::getLogger()->addLogMessage( "Buffer too small; need size " + boost::lexical_cast< std::string >( size ),
252
                                             "Kernel", LL_ERROR );
schurade's avatar
schurade committed
253
        assert( size <= sizeof( path ) );
254 255
    }
#else
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
256
#pragma message( "Error: findAppPath not implemented for this platform" )
257 258 259 260 261
    // for windows, use something like this:
    // DWORD GetModuleFileName( NULL, HMODULE hModule, // handle to module
    //                                LPTSTR lpFilename, // path buffer
    //                                DWORD nSize // size of buffer
    // );
262
#endif
263
*/
ebaum's avatar
ebaum committed
264 265
}

266
const WBoolFlag& WKernel::isFinishRequested() const
ebaum's avatar
ebaum committed
267
{
268
    return m_shutdownFlag;
ebaum's avatar
[ADD]  
ebaum committed
269 270
}

271
void WKernel::loadDataSets( std::vector< std::string > fileNames )
272
{
273 274 275 276 277 278
    getRootContainer()->loadDataSets( fileNames );
}

void WKernel::loadDataSetsSynchronously( std::vector< std::string > fileNames )
{
    getRootContainer()->loadDataSetsSynchronously( fileNames );
279 280
}

281
boost::shared_ptr< WModule > WKernel::applyModule( boost::shared_ptr< WModule > applyOn, boost::shared_ptr< WModule > prototype )
282
{
283
    return getRootContainer()->applyModule( applyOn, prototype );
284 285
}

286
std::string WKernel::getAppPath()
287
{
288 289
    findAppPath();
    return WKernel::m_AppPath;
290 291
}

292
std::string WKernel::getShaderPath()
293
{
294 295
    findAppPath();
    return WKernel::m_shaderPath;
296
}