WKernel.cpp 7.62 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"
42
#include "WBatchLoader.h"
ebaum's avatar
[ADD]  
ebaum committed
43
#include "../common/WException.h"
44
#include "../common/WCondition.h"
45
#include "../common/WConditionOneShot.h"
46
#include "../common/WFlag.h"
47
#include "../common/WPreferences.h"
ebaum's avatar
[ADD]  
ebaum committed
48

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

51
#include "WKernel.h"
52

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

172 173
    // FIXME (schurade)
    // this should work on linux, have to implement it for windows and mac later
Alexander Wiebel's avatar
Alexander Wiebel committed
174
#ifdef __linux__
175 176 177

    // 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
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
    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 );
    //}
205 206

    m_AppPath = appPath;
207 208
    m_AppPath += "/";
    m_shaderPath = m_AppPath + "shaders/";
209

210 211
    // getcwd/get_current_dir_name() mallocs memory, free it here
    delete appPath;
212

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

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

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

249
const WBoolFlag& WKernel::isFinishRequested() const
ebaum's avatar
ebaum committed
250
{
251
    return m_shutdownFlag;
ebaum's avatar
[ADD]  
ebaum committed
252 253
}

254
void WKernel::loadDataSets( std::vector< std::string > fileNames )
255
{
256 257 258 259 260 261
    getRootContainer()->loadDataSets( fileNames );
}

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

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

269
std::string WKernel::getAppPath()
270
{
271 272
    findAppPath();
    return WKernel::m_AppPath;
273 274
}

275
std::string WKernel::getShaderPath()
276
{
277 278
    findAppPath();
    return WKernel::m_shaderPath;
279
}