WKernel.cpp 7.08 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
#if defined(__APPLE__)
#include <mach-o/dyld.h>
#endif

ebaum's avatar
[ADD]  
ebaum committed
29
#include <iostream>
ebaum's avatar
ebaum committed
30
#include <list>
31 32
#include <string>
#include <vector>
ebaum's avatar
ebaum committed
33 34

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

ebaum's avatar
ebaum committed
36
#include "WModule.h"
37
#include "WModuleFactory.h"
ebaum's avatar
[ADD]  
ebaum committed
38 39
#include "../common/WException.h"

ebaum's avatar
ebaum committed
40 41
#include "../graphicsEngine/WGraphicsEngine.h"

42
#include "WKernel.h"
43

44
/**
ebaum's avatar
ebaum committed
45 46 47 48
 * Used for program wide access to the kernel.
 */
WKernel* kernel = NULL;

49
WKernel::WKernel( int argc, char* argv[], boost::shared_ptr< WGUI > gui )
50
    : m_gui( gui )
ebaum's avatar
[ADD]  
ebaum committed
51
{
52
    WLogger::getLogger()->addLogMessage( "Initializing Kernel", "Kernel", LL_DEBUG );
ebaum's avatar
ebaum committed
53 54 55

    kernel = this;

ebaum's avatar
[ADD]  
ebaum committed
56
    // initialize members
ebaum's avatar
ebaum committed
57 58 59
    m_ArgC = argc;
    m_ArgV = argv;
    m_FinishRequested = false;
ebaum's avatar
[ADD]  
ebaum committed
60

61 62
    // get module factory
    m_moduleFactory = WModuleFactory::getModuleFactory();
63
    m_moduleContainer = boost::shared_ptr< WModuleContainer >();
64

ebaum's avatar
ebaum committed
65 66 67
    // init GE, DataHandler, ...
    init();

ebaum's avatar
[ADD]  
ebaum committed
68 69 70 71 72 73 74
    // load modules
    loadModules();
}

WKernel::~WKernel()
{
    // cleanup
75
    WLogger::getLogger()->addLogMessage( "Shutting down Kernel", "Kernel", LL_DEBUG );
76 77

    // finish running thread
78
    WLogger::getLogger()->wait( true );
79
    // write remaining log messages
80
    WLogger::getLogger()->processQueue();
ebaum's avatar
[ADD]  
ebaum committed
81 82 83 84 85 86 87
}

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

ebaum's avatar
ebaum committed
88 89 90 91 92
WKernel* WKernel::getRunningKernel()
{
    return kernel;
}

93
boost::shared_ptr< WGraphicsEngine > WKernel::getGraphicsEngine() const
ebaum's avatar
ebaum committed
94
{
95
    return m_graphicsEngine;
ebaum's avatar
ebaum committed
96 97
}

Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
98
boost::shared_ptr< WModuleContainer > WKernel::getRootContainer() const
99
{
Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
100
    return m_moduleContainer;
101 102
}

Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
103
boost::shared_ptr< WGUI > WKernel::getGui() const
104
{
105
    return m_gui;
106 107
}

108 109
void WKernel::setGui( boost::shared_ptr< WGUI > gui )
{
110
    m_gui = gui;
111
}
112

113
int WKernel::getArgumentCount() const
ebaum's avatar
ebaum committed
114 115 116 117
{
    return m_ArgC;
}

118
char** WKernel::getArguments() const
ebaum's avatar
ebaum committed
119 120 121 122
{
    return m_ArgV;
}

Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
123 124
void WKernel::stop()
{
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
125
    getRootContainer()->stop();
Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
126 127
}

ebaum's avatar
ebaum committed
128 129
int WKernel::run()
{
130
    WLogger::getLogger()->addLogMessage( "Starting Kernel", "Kernel", LL_DEBUG );
ebaum's avatar
ebaum committed
131 132

    // run Gui
133
    m_gui->run();
ebaum's avatar
ebaum committed
134 135 136

    // run? data handler stuff?

137
    // TODO(schurade): this must be moved somewhere else, and realize the wait loop in another fashion
138
    while ( !m_gui->isInitalized() )
139 140
    {
    }
141
    m_gui->getLoadButtonSignal()->connect( boost::bind( &WKernel::doLoadDataSets, this, _1 ) );
Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
142

143
    // default modules
144 145
    m_moduleContainer->add( m_moduleFactory->create( m_moduleFactory->getPrototypeByName( "Navigation Slice Module" ) ) );
    m_moduleContainer->add( m_moduleFactory->create( m_moduleFactory->getPrototypeByName( "Coordinate System Module" ) ) );
Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
146 147 148

    m_gui->wait( false );
    m_FinishRequested = true;
149
    m_moduleContainer->stop();
ebaum's avatar
ebaum committed
150 151 152 153 154

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

ebaum's avatar
[ADD]  
ebaum committed
155 156
void WKernel::loadModules()
{
157 158
    // load all modules
    m_moduleFactory->load();
ebaum's avatar
ebaum committed
159 160 161 162
}

void WKernel::init()
{
163
     // initialize
164
    findAppPath();
ebaum's avatar
ebaum committed
165

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

ebaum's avatar
ebaum committed
170 171
    // initialize graphics engine
    // this also includes initialization of WGEScene and OpenSceneGraph
172
    m_graphicsEngine = boost::shared_ptr< WGraphicsEngine >( new WGraphicsEngine( m_shaderPath ) );
173 174

    // initialize Datahandler
175
    m_dataHandler = boost::shared_ptr< WDataHandler >( new WDataHandler() );
176 177 178 179 180 181
}

bool WKernel::findAppPath()
{
    // FIXME (schurade)
    // this should work on linux, have to implement it for windows and mac later
Alexander Wiebel's avatar
Alexander Wiebel committed
182
#ifdef __linux__
183 184 185 186 187 188 189 190
    int length;
    char appPath[255];

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

    // Catch some errors
    if ( length < 0 )
    {
191
        WLogger::getLogger()->addLogMessage( "Error resolving symlink /proc/self/exe.", "Kernel", LL_ERROR );
192 193 194 195
        return false;
    }
    if ( length >= 255 )
    {
196
        WLogger::getLogger()->addLogMessage( "Path too long. Truncated.", "Kernel", LL_ERROR );
197 198 199 200 201 202 203 204 205 206 207
        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;
schurade's avatar
schurade committed
208
        assert( length >= 0 );
209 210 211 212 213
    }

    m_AppPath = appPath;

    std::string shaderPath( appPath );
214
    m_shaderPath = shaderPath + "shaders/";
215 216

    return true;
schurade's avatar
schurade committed
217
#elif defined( __APPLE__ )
218
    char path[1024];
schurade's avatar
schurade committed
219
    uint32_t size = sizeof( path );
220
    if( _NSGetExecutablePath( path, &size ) == 0 )
221
    {
222 223 224
        WLogger::getLogger()->addLogMessage( "Executable path is " + std::string( path ), "Kernel", LL_ERROR );

        int i = strlen( path );
schurade's avatar
schurade committed
225 226 227 228 229 230
        while( path[i] != '/' )
        {
            path[i] = '\0';
            i--;
            assert( i >= 0 );
        }
231
        WLogger::getLogger()->addLogMessage( "Application path is " + std::string( path ), "Kernel", LL_ERROR );
schurade's avatar
schurade committed
232 233 234 235 236 237
        m_AppPath = path;

        std::string shaderPath( path );
        m_shaderPath = shaderPath + "shaders/";

        return true;
238 239 240
    }
    else
    {
241
        WLogger::getLogger()->addLogMessage( "Buffer too small; need size " + boost::lexical_cast< std::string >( size ),
242
                                             "Kernel", LL_ERROR );
schurade's avatar
schurade committed
243
        assert( size <= sizeof( path ) );
244 245 246 247 248 249
    }
#else
#error findAppPath not implemented for this platform
#endif

    return false;
ebaum's avatar
ebaum committed
250 251
}

252
bool WKernel::isFinishRequested() const
ebaum's avatar
ebaum committed
253 254
{
    return m_FinishRequested;
ebaum's avatar
[ADD]  
ebaum committed
255 256
}

257 258
void WKernel::doLoadDataSets( std::vector< std::string > fileNames )
{
259 260 261 262 263 264 265
    // add a new data module for each file to load
    for ( std::vector< std::string >::iterator iter = fileNames.begin(); iter != fileNames.end(); ++iter )
    {
        boost::shared_ptr< WModule > mod = m_moduleFactory->create( m_moduleFactory->getPrototypeByName( "Data Module" ) );
        mod->getProperties()->setValue( "filename" , ( *iter ) );
        m_moduleContainer->add( mod );
    }
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
}

Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
273
std::string WKernel::getAppPath() const
274 275 276 277
{
    return m_AppPath;
}

Sebastian Eichelbaum's avatar
[MERGE]  
Sebastian Eichelbaum committed
278
std::string WKernel::getShaderPath() const
279
{
280
    return m_shaderPath;
281
}