WKernel.cpp 6.82 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 25
//
// 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/>.
//
//---------------------------------------------------------------------------

#include <iostream>
ebaum's avatar
ebaum committed
26
#include <list>
27 28
#include <string>
#include <vector>
ebaum's avatar
ebaum committed
29 30

#include <boost/thread/xtime.hpp>
ebaum's avatar
[ADD]  
ebaum committed
31 32

#include "WKernel.h"
ebaum's avatar
ebaum committed
33
#include "WModule.h"
34
#include "../modules/navigationSlices/WNavigationSliceModule.h"
ebaum's avatar
[ADD]  
ebaum committed
35 36
#include "../common/WException.h"

ebaum's avatar
ebaum committed
37 38
#include "../graphicsEngine/WGraphicsEngine.h"

39
/**
ebaum's avatar
ebaum committed
40 41 42 43
 * Used for program wide access to the kernel.
 */
WKernel* kernel = NULL;

44 45
WKernel::WKernel( int argc, char* argv[], boost::shared_ptr< WGUI > gui )
    : m_Gui( gui )
ebaum's avatar
[ADD]  
ebaum committed
46
{
ebaum's avatar
ebaum committed
47 48 49 50
    std::cout << "Initializing Kernel" << std::endl;

    kernel = this;

ebaum's avatar
[ADD]  
ebaum committed
51
    // initialize members
ebaum's avatar
ebaum committed
52 53 54
    m_ArgC = argc;
    m_ArgV = argv;
    m_FinishRequested = false;
ebaum's avatar
[ADD]  
ebaum committed
55

ebaum's avatar
ebaum committed
56 57 58
    // init GE, DataHandler, ...
    init();

ebaum's avatar
[ADD]  
ebaum committed
59 60 61 62 63 64 65
    // load modules
    loadModules();
}

WKernel::~WKernel()
{
    // cleanup
66
    WLogger::getLogger()->addLogMessage( "Shutting down Kernel", "Kernel", LL_DEBUG );
67 68

    // finish running thread
69
    WLogger::getLogger()->wait( true );
70
    // write remaining log messages
71
    WLogger::getLogger()->processQueue();
ebaum's avatar
[ADD]  
ebaum committed
72 73 74 75 76 77 78
}

WKernel::WKernel( const WKernel& other )
{
    *this = other;
}

ebaum's avatar
ebaum committed
79 80 81 82 83
WKernel* WKernel::getRunningKernel()
{
    return kernel;
}

84
boost::shared_ptr<WGraphicsEngine> WKernel::getGraphicsEngine() const
ebaum's avatar
ebaum committed
85 86 87 88
{
    return m_GraphicsEngine;
}

89 90 91 92 93
boost::shared_ptr<WDataHandler> WKernel::getDataHandler() const
{
    return m_DataHandler;
}

94
boost::shared_ptr< WGUI > WKernel::getGui()
95 96 97 98
{
    return m_Gui;
}

99 100 101 102
void WKernel::setGui( boost::shared_ptr< WGUI > gui )
{
    m_Gui = gui;
}
103

104
int WKernel::getArgumentCount() const
ebaum's avatar
ebaum committed
105 106 107 108
{
    return m_ArgC;
}

109
char** WKernel::getArguments() const
ebaum's avatar
ebaum committed
110 111 112 113 114 115
{
    return m_ArgV;
}

int WKernel::run()
{
116
    WLogger::getLogger()->addLogMessage( "Starting Kernel", "Kernel", LL_DEBUG );
ebaum's avatar
ebaum committed
117 118 119 120 121 122 123 124 125 126

    // TODO(ebaum): add separate graphics thread here
    m_GraphicsEngine->run();

    // run Gui
    // TODO(all): clean up this option handler mess
    m_Gui->run();

    // run? data handler stuff?

127 128 129 130
    // **************************************************************************************************************************
    // This part will be exchanged by some kind of ModuleContainer managing module execution.
    // TODO(ebaum): replace by ModuleContainer
    // **************************************************************************************************************************
131

ebaum's avatar
ebaum committed
132 133 134
    // run module execution threads
    // TODO(ebaum): after having modules loaded they should be started here.
    // currently this is just the test module
135
    WLogger::getLogger()->addLogMessage( "*** Starting modules:", "Kernel", LL_DEBUG );
136
    for( std::list<boost::shared_ptr<WModule> >::iterator list_iter = m_modules.begin(); list_iter != m_modules.end();
wiebel's avatar
[STYLE]  
wiebel committed
137
            ++list_iter )
ebaum's avatar
ebaum committed
138
    {
139
        WLogger::getLogger()->addLogMessage( "Starting module: " + ( *list_iter )->getName(), "Kernel", LL_DEBUG );
ebaum's avatar
ebaum committed
140 141 142
        ( *list_iter )->run();
    }

143 144 145 146 147
    // TODO(schurade): this must be moved somewhere else, and realize the wait loop in another fashion
    while ( !m_Gui->isInitalized() )
    {
    }
    m_Gui->getLoadButtonSignal()->connect( boost::bind( &WKernel::doLoadDataSets, this, _1 ) );
Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
148 149

    for( std::list<boost::shared_ptr<WModule> >::iterator list_iter = m_modules.begin(); list_iter != m_modules.end();
150 151 152 153 154
                ++list_iter )
    {
        ( *list_iter )->connectToGui();
    }

ebaum's avatar
ebaum committed
155
    // wait
156
    // TODO(ebaum): this is not the optimal. It would be better to quit OSG, GE and so on in the right order.
ebaum's avatar
ebaum committed
157 158 159 160
    m_Gui->wait( false );
    m_FinishRequested = true;

    // wait for modules to finish
161
    for( std::list<boost::shared_ptr<WModule> >::iterator list_iter = m_modules.begin(); list_iter != m_modules.end();
wiebel's avatar
[STYLE]  
wiebel committed
162
            ++list_iter )
ebaum's avatar
ebaum committed
163 164 165 166 167 168 169 170 171 172 173
    {
        ( *list_iter )->wait( true );
    }

    // finally GE
    m_GraphicsEngine->wait( true );

    // how to get QT return code from its thread?
    return 0;
}

ebaum's avatar
[ADD]  
ebaum committed
174 175
void WKernel::loadModules()
{
ebaum's avatar
ebaum committed
176
    // TODO(ebaum): add dynamic loading here
177
    WLogger::getLogger()->addLogMessage( "*** Loading Modules: ", "Kernel", LL_DEBUG );
ebaum's avatar
ebaum committed
178 179
    m_modules.clear();

180
    boost::shared_ptr<WModule> m = boost::shared_ptr<WModule>( new WNavigationSliceModule() );
181
    WLogger::getLogger()->addLogMessage( "Loading module: " + m->getName(), "Kernel", LL_DEBUG );
ebaum's avatar
ebaum committed
182 183

    m_modules.push_back( m );
ebaum's avatar
ebaum committed
184 185 186 187 188
}

void WKernel::init()
{
    // initialize
189
    findAppPath();
ebaum's avatar
ebaum committed
190 191 192

    // initialize graphics engine
    // this also includes initialization of WGEScene and OpenSceneGraph
193
    m_GraphicsEngine = boost::shared_ptr<WGraphicsEngine>( new WGraphicsEngine( m_shaderPath ) );
194 195 196

    // initialize Datahandler
    m_DataHandler = boost::shared_ptr<WDataHandler>( new WDataHandler() );
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
}

bool WKernel::findAppPath()
{
    // FIXME (schurade)
    // this should work on linux, have to implement it for windows and mac later

    int length;
    char appPath[255];

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

    // Catch some errors
    if ( length < 0 )
    {
        fprintf( stderr, "Error resolving symlink /proc/self/exe.\n" );
        return false;
    }
    if ( length >= 255 )
    {
        fprintf( stderr, "Path too long. Truncated.\n" );
        return false;
    }

    // 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;
    }

    m_AppPath = appPath;

    std::string shaderPath( appPath );
234
    m_shaderPath = shaderPath + "shaders/";
235 236

    return true;
ebaum's avatar
ebaum committed
237 238
}

239
bool WKernel::isFinishRequested() const
ebaum's avatar
ebaum committed
240 241
{
    return m_FinishRequested;
ebaum's avatar
[ADD]  
ebaum committed
242 243
}

244 245 246 247 248
void WKernel::doLoadDataSets( std::vector< std::string > fileNames )
{
    m_DataHandler->loadDataSets( fileNames );
}

249 250 251 252 253
boost::shared_ptr<WDataHandler> WKernel::getDataHandler()
{
    return m_DataHandler;
}

254 255 256 257 258 259 260
std::string WKernel::getAppPath()
{
    return m_AppPath;
}

std::string WKernel::getShaderPath()
{
261
    return m_shaderPath;
262
}