WKernel.cpp 7.69 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

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

ebaum's avatar
ebaum committed
107 108 109 110 111
WKernel* WKernel::getRunningKernel()
{
    return kernel;
}

112
boost::shared_ptr< WGraphicsEngine > WKernel::getGraphicsEngine() const
ebaum's avatar
ebaum committed
113
{
114
    return m_graphicsEngine;
ebaum's avatar
ebaum committed
115 116
}

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

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

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

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

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

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

142 143 144
    // start GE
    m_graphicsEngine->run();

145
    // default modules
146 147
    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
148
    m_moduleContainer->add( m_moduleFactory->create( m_moduleFactory->getPrototypeByName( "HUD" ) ) , true );
149

150 151
    // actually there is nothing more to do here
    waitForStop();
152

153
    WLogger::getLogger()->addLogMessage( "Shutting down Kernel", "Kernel", LL_INFO );
154 155
}

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

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

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

    m_AppPath = appPath;
199 200
    m_AppPath += "/";
    m_shaderPath = m_AppPath + "shaders/";
201

202 203
    // getcwd/get_current_dir_name() mallocs memory, free it here
    delete appPath;
204

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

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

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

241
const WBoolFlag& WKernel::isFinishRequested() const
ebaum's avatar
ebaum committed
242
{
243
    return m_shutdownFlag;
ebaum's avatar
[ADD]  
ebaum committed
244 245
}

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

260
boost::shared_ptr< WModule > WKernel::applyModule( boost::shared_ptr< WModule > applyOn, boost::shared_ptr< WModule > prototype )
261
{
262
    return getRootContainer()->applyModule( applyOn, prototype );
263 264
}

265
std::string WKernel::getAppPath()
266
{
267 268
    findAppPath();
    return WKernel::m_AppPath;
269 270
}

271
std::string WKernel::getShaderPath()
272
{
273 274
    findAppPath();
    return WKernel::m_shaderPath;
275
}