WKernel.cpp 7.89 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/thread/xtime.hpp>
ebaum's avatar
[ADD]  
ebaum committed
39

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

ebaum's avatar
ebaum committed
47 48
#include "../graphicsEngine/WGraphicsEngine.h"

49
#include "WKernel.h"
50

51
/**
ebaum's avatar
ebaum committed
52 53 54 55
 * Used for program wide access to the kernel.
 */
WKernel* kernel = NULL;

56 57 58 59 60 61 62 63 64 65
/**
 * Define shader path.
 */
std::string WKernel::m_shaderPath = std::string();

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

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

71
    // init the singleton
ebaum's avatar
ebaum committed
72 73
    kernel = this;

ebaum's avatar
[ADD]  
ebaum committed
74
    // initialize members
75 76
    m_gui = gui;
    m_graphicsEngine = ge;
77

78
    // init
ebaum's avatar
ebaum committed
79
    init();
ebaum's avatar
[ADD]  
ebaum committed
80 81 82 83 84
}

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

88
void WKernel::init()
ebaum's avatar
[ADD]  
ebaum committed
89
{
90
    // initialize
91 92 93 94 95 96 97 98 99 100
    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
101
    m_graphicsEngine->setShaderPath( WKernel::m_shaderPath );
102 103 104 105 106 107

    // initialize Datahandler
    m_dataHandler = boost::shared_ptr< WDataHandler >( new WDataHandler() );

    // 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
    m_moduleContainer->add( m_moduleFactory->create( m_moduleFactory->getPrototypeByName( "Navigation Slice Module" ) ) , true );
    m_moduleContainer->add( m_moduleFactory->create( m_moduleFactory->getPrototypeByName( "Coordinate System Module" ) ) , true );
schurade's avatar
schurade committed
151
    m_moduleContainer->add( m_moduleFactory->create( m_moduleFactory->getPrototypeByName( "HUD" ) ) , true );
152

153 154
    // actually there is nothing more to do here
    waitForStop();
155

156
    WLogger::getLogger()->addLogMessage( "Shutting down Kernel", "Kernel", LL_INFO );
157 158
}

159
void WKernel::findAppPath()
160
{
161 162 163 164 165 166
    // only get the path if not already done
    if ( m_AppPath != "" )
    {
        return;
    }

167 168
    // FIXME (schurade)
    // this should work on linux, have to implement it for windows and mac later
Alexander Wiebel's avatar
Alexander Wiebel committed
169
#ifdef __linux__
170 171 172

    // 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
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
    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 );
    //}
200 201

    m_AppPath = appPath;
202 203
    m_AppPath += "/";
    m_shaderPath = m_AppPath + "shaders/";
204

205 206
    // getcwd/get_current_dir_name() mallocs memory, free it here
    delete appPath;
207

schurade's avatar
schurade committed
208
#elif defined( __APPLE__ )
209
    char path[1024];
schurade's avatar
schurade committed
210
    uint32_t size = sizeof( path );
211
    if( _NSGetExecutablePath( path, &size ) == 0 )
212
    {
213
        WLogger::getLogger()->addLogMessage( "Executable path is " + std::string( path ), "Kernel", LL_DEBUG );
214 215

        int i = strlen( path );
schurade's avatar
schurade committed
216 217 218 219 220 221
        while( path[i] != '/' )
        {
            path[i] = '\0';
            i--;
            assert( i >= 0 );
        }
222
        WLogger::getLogger()->addLogMessage( "Application path is " + std::string( path ), "Kernel", LL_DEBUG );
schurade's avatar
schurade committed
223 224 225 226
        m_AppPath = path;

        std::string shaderPath( path );
        m_shaderPath = shaderPath + "shaders/";
227 228 229
    }
    else
    {
230
        WLogger::getLogger()->addLogMessage( "Buffer too small; need size " + boost::lexical_cast< std::string >( size ),
231
                                             "Kernel", LL_ERROR );
schurade's avatar
schurade committed
232
        assert( size <= sizeof( path ) );
233 234
    }
#else
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
235
#pragma message( "Error: findAppPath not implemented for this platform" )
236 237 238 239 240
    // for windows, use something like this:
    // DWORD GetModuleFileName( NULL, HMODULE hModule, // handle to module
    //                                LPTSTR lpFilename, // path buffer
    //                                DWORD nSize // size of buffer
    // );
241
#endif
ebaum's avatar
ebaum committed
242 243
}

244
const WBoolFlag& WKernel::isFinishRequested() const
ebaum's avatar
ebaum committed
245
{
246
    return m_shutdownFlag;
ebaum's avatar
[ADD]  
ebaum committed
247 248
}

249
void WKernel::loadDataSets( std::vector< std::string > fileNames )
250
{
251
    // add a new data module for each file to load
252 253
    using boost::shared_ptr;
    for( std::vector< std::string >::iterator iter = fileNames.begin(); iter != fileNames.end(); ++iter )
254
    {
255
        shared_ptr< WModule > mod = m_moduleFactory->create( m_moduleFactory->getPrototypeByName( "Data Module" ) );
256 257
        mod->getProperties()->setValue( "filename" , ( *iter ) );
        m_moduleContainer->add( mod );
258 259
        // searialize loading of a couple of data sets
        mod->isReady().wait();
260
    }
261 262
}

263
boost::shared_ptr< WModule > WKernel::applyModule( boost::shared_ptr< WModule > applyOn, boost::shared_ptr< WModule > prototype )
264
{
265
    return getRootContainer()->applyModule( applyOn, prototype );
266 267
}

Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
268
boost::shared_ptr< WDataHandler > WKernel::getDataHandler() const
269
{
270
    return m_dataHandler;
271 272
}

273
std::string WKernel::getAppPath()
274
{
275 276
    findAppPath();
    return WKernel::m_AppPath;
277 278
}

279
std::string WKernel::getShaderPath()
280
{
281 282
    findAppPath();
    return WKernel::m_shaderPath;
283
}