Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 3370


Ignore:
Timestamp:
Jul 30, 2009, 2:10:44 PM (15 years ago)
Author:
rgrieder
Message:

Merged resource branch back to the trunk. Changes:

  • Automated graphics loading by evaluating whether a GameState requires it
  • Using native Tcl library (x3n)

Windows users: Update your dependency package!

Location:
code/trunk
Files:
3 deleted
89 edited
5 copied

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/cmake/Media.cmake

    r2721 r3370  
    4545################ Installation #################
    4646
    47 # Try no to copy both tcl script file libraries
    48 IF(TCL_LIBRARY MATCHES "85|8\\.5")
    49   SET(TCL_EXCLUDE_PATTERN "tcl8\\.4")
    50 ELSEIF(TCL_LIBRARY MATCHES "84|8\\.4")
    51   SET(TCL_EXCLUDE_PATTERN "tcl8\\.5")
    52 ENDIF()
    53 
    5447INSTALL(
    5548  DIRECTORY ${CMAKE_MEDIA_OUTPUT_DIRECTORY}/
    5649  DESTINATION ${ORXONOX_MEDIA_INSTALL_PATH}
    57   REGEX "\\.svn$|_svn$|backToPNG|${TCL_EXCLUDE_PATTERN}" EXCLUDE
     50  REGEX "\\.svn$|_svn$|backToPNG" EXCLUDE
    5851)
  • code/trunk/cmake/PackageConfig.cmake

    r3309 r3370  
    55# MAJOR: Interface breaking change somewhere (library version changed, etc.)
    66# MINOR: Bug fix or small conformant changes
    7 SET(DEPENDENCY_VERSION_REQUIRED 2)
     7SET(DEPENDENCY_VERSION_REQUIRED 3)
    88IF(NOT EXISTS ${DEPENDENCY_PACKAGE_DIR}/version.txt)
    99  SET(DEPENDENCY_VERSION 1.0)
     
    3131
    3232# Include paths and other special treatments
    33 SET(ENV{ALUTDIR}               ${DEP_INCLUDE_DIR}/freealut-1.1.0)
    34 SET(ENV{BOOST_ROOT}            ${DEP_INCLUDE_DIR}/boost-1.39.0)
    35 SET(ENV{CEGUIDIR}              ${DEP_INCLUDE_DIR}/cegui-0.6.2)
    36 SET(ENV{DXSDK_DIR}             ${DEP_INCLUDE_DIR}/directx-2007.aug)
    37 SET(ENV{ENETDIR}               ${DEP_INCLUDE_DIR}/enet-1.2)
    38 SET(ENV{LUA_DIR}               ${DEP_INCLUDE_DIR}/lua-5.1.4)
    39 SET(ENV{OGGDIR}                ${DEP_INCLUDE_DIR}/libogg-1.1.3)
    40 SET(ENV{VORBISDIR}             ${DEP_INCLUDE_DIR}/libvorbis-1.2.0)
    41 SET(ENV{OGRE_HOME}             ${DEP_INCLUDE_DIR}/ogre-1.4.9)
     33SET(ENV{ALUTDIR}               ${DEP_INCLUDE_DIR}/freealut)
     34SET(ENV{BOOST_ROOT}            ${DEP_INCLUDE_DIR}/boost)
     35SET(ENV{CEGUIDIR}              ${DEP_INCLUDE_DIR}/cegui)
     36SET(ENV{DXSDK_DIR}             ${DEP_INCLUDE_DIR}/directx)
     37SET(ENV{ENETDIR}               ${DEP_INCLUDE_DIR}/enet)
     38SET(ENV{LUA_DIR}               ${DEP_INCLUDE_DIR}/lua)
     39SET(ENV{OGGDIR}                ${DEP_INCLUDE_DIR}/libogg)
     40SET(ENV{VORBISDIR}             ${DEP_INCLUDE_DIR}/libvorbis)
     41SET(ENV{OGRE_HOME}             ${DEP_INCLUDE_DIR}/ogre)
    4242SET(ENV{OGRE_PLUGIN_DIR}       ${DEP_BINARY_DIR})
    43 SET(ENV{OPENALDIR}             ${DEP_INCLUDE_DIR}/openal-1.1)
    44 LIST(APPEND CMAKE_INCLUDE_PATH ${DEP_INCLUDE_DIR}/tcl-8.5.2/include)
    45 LIST(APPEND CMAKE_INCLUDE_PATH ${DEP_INCLUDE_DIR}/zlib-1.2.3/include)
     43SET(ENV{OPENALDIR}             ${DEP_INCLUDE_DIR}/openal)
     44LIST(APPEND CMAKE_INCLUDE_PATH ${DEP_INCLUDE_DIR}/tcl/include)
     45LIST(APPEND CMAKE_INCLUDE_PATH ${DEP_INCLUDE_DIR}/zlib/include)
    4646
    4747### INSTALL ###
     48
     49# Tcl script library
     50INSTALL(
     51  DIRECTORY ${DEP_LIBRARY_DIR}/tcl/
     52  DESTINATION lib/tcl
     53)
     54
    4855# On Windows, DLLs have to be in the executable folder, install them
    4956IF(WIN32 AND DEP_BINARY_DIR)
  • code/trunk/cmake/PackageConfigMSVC.cmake

    r3196 r3370  
    5858
    5959  # Visual Leak Detector
    60   SET(VLD_INCLUDE_DIR  ${DEP_INCLUDE_DIR}/vld-1.9h CACHE PATH "")
    61   SET(VLD_LIBRARY_DIR  ${DEP_LIBRARY_DIR}          CACHE PATH "")
     60  SET(VLD_INCLUDE_DIR  ${DEP_INCLUDE_DIR}/vld  CACHE PATH "")
     61  SET(VLD_LIBRARY_DIR  ${DEP_LIBRARY_DIR}       CACHE PATH "")
    6262  LINK_DIRECTORIES(${VLD_LIBRARY_DIR}) # Used for auto-linking
    6363  MARK_AS_ADVANCED(VLD_INCLUDE_DIR VLD_LIBRARY_DIR)
  • code/trunk/src/SpecialConfig.h.in

    r3196 r3370  
    8888    const char ORXONOX_LOG_DEV_PATH[]         = "@CMAKE_LOG_OUTPUT_DIRECTORY@";
    8989#endif
    90    
    91     /* OGRE Plugins */
     90#ifdef DEPENDENCY_PACKAGE_ENABLE
     91    const char ORXONOX_DEP_LIB_PATH[]         = "@DEP_LIBRARY_DIR@";
     92#endif
     93
     94    // OGRE PLUGINS
    9295#ifdef NDEBUG
    9396    const char ORXONOX_OGRE_PLUGINS[] = "@OGRE_PLUGINS_RELEASE@";
  • code/trunk/src/core/CMakeLists.txt

    r3327 r3370  
    2727  GameMode.cc
    2828  GameState.cc
     29  GraphicsManager.cc
     30  GUIManager.cc
    2931  Language.cc
    3032  LuaBind.cc
     
    8082  LINK_LIBRARIES
    8183    ${OGRE_LIBRARY}
     84    ${Boost_FILESYSTEM_LIBRARY}
     85    ${Boost_SYSTEM_LIBRARY} # Filesystem dependency
    8286    ${Boost_THREAD_LIBRARY}
    83     ${Boost_FILESYSTEM_LIBRARY}
    84     ${Boost_SYSTEM_LIBRARY}
    85     ${Boost_DATE_TIME_LIBRARY} # MSVC only
     87    ${Boost_DATE_TIME_LIBRARY} # Thread dependency
     88    ${CEGUI_LIBRARY}
     89    ${CEGUILUA_LIBRARY}
    8690    ${LUA_LIBRARIES}
    8791    cpptcl_orxonox
     92    ogreceguirenderer_orxonox
    8893    ois_orxonox
    8994    tinyxml++_orxonox
  • code/trunk/src/core/Clock.h

    r3196 r3370  
    2626 *
    2727 */
    28 
    29 /**
    30     @file
    31     @brief Declaration of the Core class.
    32 
    33     The Core class is a singleton, only used to configure some variables
    34     in the core through the config-file.
    35 */
    3628
    3729#ifndef _Clock_H__
  • code/trunk/src/core/ConfigFileManager.cc

    r3301 r3370  
    4242    const char* const DEFAULT_CONFIG_FILE = "default.ini";
    4343
    44     ConfigFileManager* ConfigFileManager::singletonRef_s = 0;
     44    ConfigFileManager* ConfigFileManager::singletonPtr_s = 0;
    4545
    4646    SetConsoleCommandShortcutExtern(config).argumentCompleter(0, autocompletion::configvalueclasses()).argumentCompleter(1, autocompletion::configvalues()).argumentCompleter(2, autocompletion::configvalue());
     
    482482         : mininmalFreeType_(ConfigFileType::numberOfReservedTypes)
    483483    {
    484         assert(singletonRef_s == 0);
    485         singletonRef_s = this;
    486484    }
    487485
     
    490488        for(std::map<ConfigFileType, ConfigFile*>::const_iterator it = this->configFiles_.begin(); it != this->configFiles_.end(); )
    491489            delete (it++)->second;
    492 
    493         assert(singletonRef_s != 0);
    494         singletonRef_s = 0;
    495490    }
    496491
  • code/trunk/src/core/ConfigFileManager.h

    r3196 r3370  
    3838
    3939#include "util/OrxEnum.h"
     40#include "util/Singleton.h"
    4041
    4142namespace orxonox
     
    267268    // ConfigFileManager //
    268269    ///////////////////////
    269     class _CoreExport ConfigFileManager
    270     {
     270    class _CoreExport ConfigFileManager : public Singleton<ConfigFileManager>
     271    {
     272        friend class Singleton<ConfigFileManager>;
    271273        public:
    272274            ConfigFileManager();
     
    305307            void updateConfigValues(ConfigFileType type);
    306308
    307             static ConfigFileManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
    308 
    309309        private:
    310310            ConfigFileManager(const ConfigFileManager&);
     
    315315            unsigned int mininmalFreeType_;
    316316
    317             static ConfigFileManager* singletonRef_s;
     317            static ConfigFileManager* singletonPtr_s;
    318318    };
    319319}
  • code/trunk/src/core/ConsoleCommandCompilation.cc

    r3198 r3370  
    9494        if (newline)
    9595        {
    96             COUT(0) << text << std::endl;
     96            COUT(0) << stripEnclosingBraces(text) << std::endl;
    9797        }
    9898        else
    9999        {
    100             COUT(0) << text;
     100            COUT(0) << stripEnclosingBraces(text);
    101101        }
    102102    }
  • code/trunk/src/core/Core.cc

    r3323 r3370  
    4141#include <cstdio>
    4242#include <boost/filesystem.hpp>
     43#include <OgreRenderWindow.h>
    4344
    4445#ifdef ORXONOX_PLATFORM_WINDOWS
     
    6869#include "CoreIncludes.h"
    6970#include "Factory.h"
     71#include "GameMode.h"
     72#include "GraphicsManager.h"
     73#include "GUIManager.h"
    7074#include "Identifier.h"
    7175#include "Language.h"
     
    7478#include "TclBind.h"
    7579#include "TclThreadManager.h"
     80#include "input/InputManager.h"
    7681
    7782namespace orxonox
    7883{
    7984    //! Static pointer to the singleton
    80     Core* Core::singletonRef_s  = 0;
     85    Core* Core::singletonPtr_s  = 0;
    8186
    8287    SetCommandLineArgument(mediaPath, "").information("Path to the media/data files");
     
    134139                .callback(this, &CoreConfiguration::debugLevelChanged);
    135140
    136             SetConfigValue(language_, Language::getLanguage().defaultLanguage_)
     141            SetConfigValue(language_, Language::getInstance().defaultLanguage_)
    137142                .description("The language of the ingame text")
    138143                .callback(this, &CoreConfiguration::languageChanged);
     
    141146                .callback(this, &CoreConfiguration::initializeRandomNumberGenerator);
    142147
    143             SetConfigValue(mediaPathString_, mediaPath_.string())
    144                 .description("Relative path to the game data.")
    145                 .callback(this, &CoreConfiguration::mediaPathChanged);
     148            // Only show this config value for development builds
     149            if (Core::isDevelopmentRun())
     150            {
     151                SetConfigValue(mediaPathString_, mediaPath_.string())
     152                    .description("Relative path to the game data.")
     153                    .callback(this, &CoreConfiguration::mediaPathChanged);
     154            }
    146155        }
    147156
     
    170179        {
    171180            // Read the translation file after the language was configured
    172             Language::getLanguage().readTranslatedLanguageFile();
     181            Language::getInstance().readTranslatedLanguageFile();
    173182        }
    174183
     
    198207        void tsetMediaPath(const std::string& path)
    199208        {
    200             ModifyConfigValue(mediaPathString_, tset, path);
     209            if (Core::isDevelopmentRun())
     210            {
     211                ModifyConfigValue(mediaPathString_, tset, path);
     212            }
     213            else
     214            {
     215                // Manual 'config' value without the file entry
     216                mediaPathString_ = path;
     217                this->mediaPathChanged();
     218            }
    201219        }
    202220
     
    230248
    231249    Core::Core(const std::string& cmdLine)
    232     {
    233         if (singletonRef_s != 0)
    234         {
    235             COUT(0) << "Error: The Core singleton cannot be recreated! Shutting down." << std::endl;
    236             abort();
    237         }
    238         Core::singletonRef_s = this;
    239 
    240         // We need the variables very soon. But don't configure them yet!
    241         this->configuration_ = new CoreConfiguration();
    242 
     250        // Cleanup guard for identifier destruction (incl. XMLPort, configValues, consoleCommands)
     251        : identifierDestroyer_(Identifier::destroyAllIdentifiers)
     252        // Cleanup guard for external console commands that don't belong to an Identifier
     253        , consoleCommandDestroyer_(CommandExecutor::destroyExternalCommands)
     254        , configuration_(new CoreConfiguration()) // Don't yet create config values!
     255        , bDevRun_(false)
     256        , bGraphicsLoaded_(false)
     257    {
    243258        // Parse command line arguments first
    244259        CommandLine::parseCommandLine(cmdLine);
     
    256271        // create a signal handler (only active for linux)
    257272        // This call is placed as soon as possible, but after the directories are set
    258         this->signalHandler_ = new SignalHandler();
     273        this->signalHandler_.reset(new SignalHandler());
    259274        this->signalHandler_->doCatch(configuration_->executablePath_.string(), Core::getLogPathString() + "orxonox_crash.log");
    260275
     
    275290
    276291        // Manage ini files and set the default settings file (usually orxonox.ini)
    277         this->configFileManager_ = new ConfigFileManager();
     292        this->configFileManager_.reset(new ConfigFileManager());
    278293        this->configFileManager_->setFilename(ConfigFileType::Settings,
    279294            CommandLine::getValue("settingsFile").getString());
    280295
    281296        // Required as well for the config values
    282         this->languageInstance_ = new Language();
     297        this->languageInstance_.reset(new Language());
    283298
    284299        // Do this soon after the ConfigFileManager has been created to open up the
     
    287302
    288303        // Create the lua interface
    289         this->luaBind_ = new LuaBind();
     304        this->luaBind_.reset(new LuaBind());
    290305
    291306        // initialise Tcl
    292         this->tclBind_ = new TclBind(Core::getMediaPathString());
    293         this->tclThreadManager_ = new TclThreadManager(tclBind_->getTclInterpreter());
     307        this->tclBind_.reset(new TclBind(Core::getMediaPathString()));
     308        this->tclThreadManager_.reset(new TclThreadManager(tclBind_->getTclInterpreter()));
    294309
    295310        // create a shell
    296         this->shell_ = new Shell();
     311        this->shell_.reset(new Shell());
    297312
    298313        // creates the class hierarchy for all classes with factories
     
    301316
    302317    /**
    303         @brief Sets the bool to true to avoid static functions accessing a deleted object.
     318    @brief
     319        All destruction code is handled by scoped_ptrs and SimpleScopeGuards.
    304320    */
    305321    Core::~Core()
    306322    {
    307         delete this->shell_;
    308         delete this->tclThreadManager_;
    309         delete this->tclBind_;
    310         delete this->luaBind_;
    311         delete this->configuration_;
    312         delete this->languageInstance_;
    313         delete this->configFileManager_;
    314 
    315         // Destroy command line arguments
    316         CommandLine::destroyAllArguments();
    317         // Also delete external console command that don't belong to an Identifier
    318         CommandExecutor::destroyExternalCommands();
    319         // Clean up class hierarchy stuff (identifiers, XMLPort, configValues, consoleCommand)
    320         Identifier::destroyAllIdentifiers();
    321 
    322         delete this->signalHandler_;
    323 
    324         // Don't assign singletonRef_s with NULL! Recreation is not supported
     323    }
     324
     325    void Core::loadGraphics()
     326    {
     327        if (bGraphicsLoaded_)
     328            return;
     329
     330        // Load OGRE including the render window
     331        scoped_ptr<GraphicsManager> graphicsManager(new GraphicsManager());
     332
     333        // The render window width and height are used to set up the mouse movement.
     334        size_t windowHnd = 0;
     335        graphicsManager->getRenderWindow()->getCustomAttribute("WINDOW", &windowHnd);
     336
     337        // Calls the InputManager which sets up the input devices.
     338        scoped_ptr<InputManager> inputManager(new InputManager(windowHnd));
     339
     340        // load the CEGUI interface
     341        guiManager_.reset(new GUIManager(graphicsManager->getRenderWindow()));
     342
     343        // Dismiss scoped pointers
     344        graphicsManager_.swap(graphicsManager);
     345        inputManager_.swap(inputManager);
     346
     347        bGraphicsLoaded_ = true;
     348    }
     349
     350    void Core::unloadGraphics()
     351    {
     352        if (!bGraphicsLoaded_)
     353            return;
     354
     355        this->guiManager_.reset();;
     356        this->inputManager_.reset();;
     357        this->graphicsManager_.reset();
     358
     359        bGraphicsLoaded_ = false;
    325360    }
    326361
     
    415450    }
    416451
     452    /*static*/ const boost::filesystem::path& Core::getRootPath()
     453    {
     454        return getInstance().configuration_->rootPath_;
     455    }
     456    /*static*/ std::string Core::getRootPathString()
     457    {
     458        return getInstance().configuration_->rootPath_.string() + '/';
     459    }
     460
    417461    /**
    418462    @note
     
    524568        {
    525569            COUT(1) << "Running from the build tree." << std::endl;
    526             Core::isDevBuild_ = true;
     570            Core::bDevRun_ = true;
    527571            configuration_->mediaPath_  = ORXONOX_MEDIA_DEV_PATH;
    528572            configuration_->configPath_ = ORXONOX_CONFIG_DEV_PATH;
     
    603647    }
    604648
    605     void Core::update(const Clock& time)
    606     {
    607         this->tclThreadManager_->update(time);
     649    bool Core::preUpdate(const Clock& time) throw()
     650    {
     651        std::string exceptionMessage;
     652        try
     653        {
     654            if (this->bGraphicsLoaded_)
     655            {
     656                // process input events
     657                this->inputManager_->update(time);
     658                // process gui events
     659                this->guiManager_->update(time);
     660            }
     661            // process thread commands
     662            this->tclThreadManager_->update(time);
     663        }
     664        catch (const std::exception& ex)
     665        { exceptionMessage = ex.what(); }
     666        catch (...)
     667        { exceptionMessage = "Unknown exception"; }
     668        if (!exceptionMessage.empty())
     669        {
     670            COUT(0) << "An exception occurred in the Core preUpdate: " << exceptionMessage << std::endl;
     671            COUT(0) << "This should really never happen! Closing the program." << std::endl;
     672            return false;
     673        }
     674        return true;
     675    }
     676
     677    bool Core::postUpdate(const Clock& time) throw()
     678    {
     679        std::string exceptionMessage;
     680        try
     681        {
     682            if (this->bGraphicsLoaded_)
     683            {
     684                // Render (doesn't throw)
     685                this->graphicsManager_->update(time);
     686            }
     687        }
     688        catch (const std::exception& ex)
     689        { exceptionMessage = ex.what(); }
     690        catch (...)
     691        { exceptionMessage = "Unknown exception"; }
     692        if (!exceptionMessage.empty())
     693        {
     694            COUT(0) << "An exception occurred in the Core postUpdate: " << exceptionMessage << std::endl;
     695            COUT(0) << "This should really never happen! Closing the program." << std::endl;
     696            return false;
     697        }
     698        return true;
    608699    }
    609700}
  • code/trunk/src/core/Core.h

    r3323 r3370  
    4343
    4444#include <cassert>
     45#include <boost/scoped_ptr.hpp>
    4546#include "util/OutputHandler.h"
     47#include "util/ScopeGuard.h"
     48#include "util/Singleton.h"
    4649
    4750namespace orxonox
    4851{
    4952    class CoreConfiguration;
     53    using boost::scoped_ptr;
    5054
    5155    /**
     
    5559        The class provides information about the media, config and log path.
    5660        It determines those by the use of platform specific functions.
     61    @remark
     62        You should only create this singleton once because it destroys the identifiers!
    5763    */
    58     class _CoreExport Core
     64    class _CoreExport Core : public Singleton<Core>
    5965    {
     66        typedef Loki::ScopeGuardImpl0<void (*)()> SimpleScopeGuard;
     67        friend class Singleton<Core>;
     68
    6069        public:
    6170            /**
     
    7180            void setConfigValues();
    7281
    73             void update(const Clock& time);
     82            bool preUpdate(const Clock& time) throw();
     83            bool postUpdate(const Clock& time) throw();
    7484
    75             static Core& getInstance() { assert(Core::singletonRef_s); return *Core::singletonRef_s; }
     85            void loadGraphics();
     86            void unloadGraphics();
    7687
    7788            static int   getSoftDebugLevel(OutputHandler::OutputDevice device = OutputHandler::LD_All);
     
    8798            //! Returns the path to the log files as boost::filesystem::path
    8899            static const boost::filesystem::path& getLogPath();
     100            //! Returns the path to the root folder as boost::filesystem::path
     101            static const boost::filesystem::path& getRootPath();
    89102            //! Returns the path to the data files as std::string
    90103            static std::string getMediaPathString();
     
    93106            //! Returns the path to the log files as std::string
    94107            static std::string getLogPathString();
     108            //! Returns the path to the root folder as std::string
     109            static std::string getRootPathString();
     110
     111            static bool isDevelopmentRun() { return getInstance().bDevRun_; }
    95112
    96113        private:
     
    102119            void setThreadAffinity(int limitToCPU);
    103120
    104             // Singletons
    105             ConfigFileManager*    configFileManager_;
    106             Language*             languageInstance_;
    107             LuaBind*              luaBind_;
    108             Shell*                shell_;
    109             SignalHandler*        signalHandler_;
    110             TclBind*              tclBind_;
    111             TclThreadManager*     tclThreadManager_;
     121            // Mind the order for the destruction!
     122            scoped_ptr<SignalHandler>     signalHandler_;
     123            SimpleScopeGuard              identifierDestroyer_;
     124            SimpleScopeGuard              consoleCommandDestroyer_;
     125            scoped_ptr<ConfigFileManager> configFileManager_;
     126            scoped_ptr<Language>          languageInstance_;
     127            scoped_ptr<CoreConfiguration> configuration_;
     128            scoped_ptr<LuaBind>           luaBind_;
     129            scoped_ptr<TclBind>           tclBind_;
     130            scoped_ptr<TclThreadManager>  tclThreadManager_;
     131            scoped_ptr<Shell>             shell_;
     132            // graphical
     133            scoped_ptr<GraphicsManager>   graphicsManager_;     //!< Interface to OGRE
     134            scoped_ptr<InputManager>      inputManager_;        //!< Interface to OIS
     135            scoped_ptr<GUIManager>        guiManager_;          //!< Interface to GUI
    112136
    113             bool isDevBuild_;                               //!< True for builds in the build directory (not installed)
    114             CoreConfiguration*    configuration_;
     137            bool                          bDevRun_;             //!< True for runs in the build directory (not installed)
     138            bool                          bGraphicsLoaded_;
    115139
    116             static Core* singletonRef_s;
     140            static Core* singletonPtr_s;
    117141    };
    118142}
  • code/trunk/src/core/CorePrereqs.h

    r3327 r3370  
    123123    class FunctorMember;
    124124    class FunctorStatic;
     125    class GraphicsManager;
     126    class GUIManager;
    125127    class Identifier;
    126128    class IRC;
     
    144146    template <class T>
    145147    class ObjectListIterator;
     148    class OgreWindowEventListener;
    146149    class OrxonoxClass;
    147150    class Shell;
     
    167170    // game states
    168171    class Game;
    169     struct GameStateConstrParams;
    170172    class GameState;
     173    struct GameStateInfo;
    171174    struct GameStateTreeNode;
    172175
     
    220223}
    221224
     225// CEGUI
     226namespace CEGUI
     227{
     228    class DefaultLogger;
     229    class Logger;
     230    class LuaScriptModule;
     231
     232    class OgreCEGUIRenderer;
     233    class OgreCEGUIResourceProvider;
     234    class OgreCEGUITexture;
     235}
     236
     237// Lua
     238struct lua_State;
     239
    222240// TinyXML and TinyXML++
    223241class TiXmlString;
  • code/trunk/src/core/Game.cc

    r3323 r3370  
    4040#include "util/Debug.h"
    4141#include "util/Exception.h"
     42#include "util/ScopeGuard.h"
    4243#include "util/Sleep.h"
    4344#include "util/SubString.h"
     
    4849#include "CoreIncludes.h"
    4950#include "ConfigValueIncludes.h"
     51#include "GameMode.h"
    5052#include "GameState.h"
    5153
     
    5961    SetConsoleCommandShortcutExternAlias(stop_game, "exit");
    6062
    61     std::map<std::string, Game::GameStateInfo> Game::gameStateDeclarations_s;
    62     Game* Game::singletonRef_s = 0;
     63    std::map<std::string, GameStateInfo> Game::gameStateDeclarations_s;
     64    Game* Game::singletonPtr_s = 0;
    6365
    6466
     
    6971    struct GameStateTreeNode
    7072    {
    71         GameState* state_;
     73        std::string name_;
    7274        weak_ptr<GameStateTreeNode> parent_;
    7375        std::vector<shared_ptr<GameStateTreeNode> > children_;
     
    112114    Game::Game(const std::string& cmdLine)
    113115    {
    114         if (singletonRef_s != 0)
    115         {
    116             COUT(0) << "Error: The Game singleton cannot be recreated! Shutting down." << std::endl;
    117             abort();
    118         }
    119         singletonRef_s = this;
    120 
    121116        this->bAbort_ = false;
    122117        bChangingState_ = false;
    123118
     119#ifdef ORXONOX_PLATFORM_WINDOWS
     120        minimumSleepTime_ = 1000/*us*/;
     121#else
     122        minimumSleepTime_ = 0/*us*/;
     123#endif
     124
    124125        // Create an empty root state
    125         declareGameState<GameState>("GameState", "emptyRootGameState", true, false);
    126 
    127         // reset statistics
    128         this->statisticsStartTime_ = 0;
    129         this->statisticsTickTimes_.clear();
    130         this->periodTickTime_ = 0;
    131         this->periodTime_ = 0;
    132         this->avgFPS_ = 0.0f;
    133         this->avgTickTime_ = 0.0f;
     126        this->declareGameState<GameState>("GameState", "emptyRootGameState", true, false);
    134127
    135128        // Set up a basic clock to keep time
    136         this->gameClock_ = new Clock();
     129        this->gameClock_.reset(new Clock());
    137130
    138131        // Create the Core
    139         this->core_ = new Core(cmdLine);
    140 
    141         // After the core has been created, we can safely instantiate the GameStates
     132        this->core_.reset(new Core(cmdLine));
     133
     134        // After the core has been created, we can safely instantiate the GameStates that don't require graphics
    142135        for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin();
    143136            it != gameStateDeclarations_s.end(); ++it)
    144137        {
    145             // Only create the states appropriate for the game mode
    146             //if (GameMode::showsGraphics || !it->second.bGraphicsMode)
    147             GameStateConstrParams params = { it->second.stateName, it->second.bIgnoreTickTime };
    148             gameStates_[getLowercase(it->second.stateName)] = GameStateFactory::fabricate(it->second.className, params);
     138            if (!it->second.bGraphicsMode)
     139                constructedStates_[it->second.stateName] = GameStateFactory::fabricate(it->second);
    149140        }
    150141
    151142        // The empty root state is ALWAYS loaded!
    152143        this->rootStateNode_ = shared_ptr<GameStateTreeNode>(new GameStateTreeNode());
    153         this->rootStateNode_->state_ = getState("emptyRootGameState");
    154         this->activeStateNode_ = this->rootStateNode_;
    155         this->activeStates_.push_back(this->rootStateNode_->state_);
     144        this->rootStateNode_->name_ = "emptyRootGameState";
     145        this->loadedTopStateNode_ = this->rootStateNode_;
     146        this->loadedStates_.push_back(this->getState(rootStateNode_->name_));
    156147
    157148        // Do this after the Core creation!
    158         this->configuration_ = new GameConfiguration();
     149        this->configuration_.reset(new GameConfiguration());
    159150    }
    160151
    161152    /**
    162153    @brief
     154        All destruction code is handled by scoped_ptrs and SimpleScopeGuards.
    163155    */
    164156    Game::~Game()
    165157    {
    166         // Destroy the configuration helper class instance
    167         delete this->configuration_;
    168 
    169         // Destroy the GameStates (note that the nodes still point to them, but doesn't matter)
    170         for (std::map<std::string, GameState*>::const_iterator it = gameStates_.begin();
    171             it != gameStates_.end(); ++it)
    172             delete it->second;
    173 
    174         // Destroy the Core and with it almost everything
    175         delete this->core_;
    176         delete this->gameClock_;
    177 
    178         // Take care of the GameStateFactories
    179         GameStateFactory::destroyFactories();
    180 
    181         // Don't assign singletonRef_s with NULL! Recreation is not supported
    182158    }
    183159
     
    195171            COUT(0) << "Warning: Starting game without requesting GameState. This automatically terminates the program." << std::endl;
    196172
     173        // reset statistics
     174        this->statisticsStartTime_ = 0;
     175        this->statisticsTickTimes_.clear();
     176        this->periodTickTime_ = 0;
     177        this->periodTime_ = 0;
     178        this->avgFPS_ = 0.0f;
     179        this->avgTickTime_ = 0.0f;
     180        this->excessSleepTime_ = 0;
     181
    197182        // START GAME
    198183        // first delta time should be about 0 seconds
     
    201186        StatisticsTickInfo tickInfo = {0, 0};
    202187        statisticsTickTimes_.push_back(tickInfo);
    203         while (!this->bAbort_ && (!this->activeStates_.empty() || this->requestedStateNodes_.size() > 0))
    204         {
    205             uint64_t currentTime = this->gameClock_->getRealMicroseconds();
    206 
    207             uint64_t nextTickTime = statisticsTickTimes_.back().tickTime + static_cast<uint64_t>(1000000.0f / configuration_->fpsLimit_);
    208             if (currentTime < nextTickTime)
    209             {
    210                 usleep(nextTickTime - currentTime);
    211                 continue;
    212             }
     188        while (!this->bAbort_ && (!this->loadedStates_.empty() || this->requestedStateNodes_.size() > 0))
     189        {
     190            // Generate the dt
    213191            this->gameClock_->capture();
    214192
    215             // STATISTICS
    216             StatisticsTickInfo tickInfo = {currentTime, 0};
     193            // Statistics init
     194            StatisticsTickInfo tickInfo = {gameClock_->getMicroseconds(), 0};
    217195            statisticsTickTimes_.push_back(tickInfo);
    218196            this->periodTime_ += this->gameClock_->getDeltaTimeMicroseconds();
    219197
    220             // UPDATE STATE STACK
    221             while (this->requestedStateNodes_.size() > 0)
    222             {
    223                 shared_ptr<GameStateTreeNode> requestedStateNode = this->requestedStateNodes_.front();
    224                 assert(this->activeStateNode_);
    225                 if (!this->activeStateNode_->parent_.expired() && requestedStateNode == this->activeStateNode_->parent_.lock())
    226                     this->unloadState(this->activeStateNode_->state_);
    227                 else // has to be child
    228                 {
    229                     try
    230                     {
    231                         this->loadState(requestedStateNode->state_);
    232                     }
    233                     catch (const std::exception& ex)
    234                     {
    235                         COUT(1) << "Error: Loading GameState '" << requestedStateNode->state_->getName() << "' failed: " << ex.what() << std::endl;
    236                         // All scheduled operations have now been rendered inert --> flush them and issue a warning
    237                         if (this->requestedStateNodes_.size() > 1)
    238                             COUT(1) << "All " << this->requestedStateNodes_.size() - 1 << " scheduled transitions have been ignored." << std::endl;
    239                         this->requestedStateNodes_.clear();
    240                         break;
    241                     }
    242                 }
    243                 this->activeStateNode_ = requestedStateNode;
    244                 this->requestedStateNodes_.erase(this->requestedStateNodes_.begin());
    245             }
    246 
    247             // UPDATE, Core first
    248             bool threwException = false;
    249             try
    250             {
    251                 this->core_->update(*this->gameClock_);
    252             }
    253             catch (const std::exception& ex)
    254             {
    255                 threwException = true;
    256                 COUT(0) << "Exception while ticking the Core: " << ex.what() << std::endl;
    257             }
    258             catch (...)
    259             {
    260                 threwException = true;
    261             }
    262             if (threwException)
    263             {
    264                 COUT(0) << "An exception occured while ticking the Core. This should really never happen!" << std::endl;
    265                 COUT(0) << "Closing the program." << std::endl;
     198            // Update the GameState stack if required
     199            this->updateGameStateStack();
     200
     201            // Core preUpdate (doesn't throw)
     202            if (!this->core_->preUpdate(*this->gameClock_))
     203            {
    266204                this->stop();
    267205                break;
    268206            }
    269207
    270             // UPDATE, GameStates bottom to top in the stack
    271             // Note: The first element is the empty root state, which doesn't need ticking
    272             for (std::vector<GameState*>::const_iterator it = this->activeStates_.begin() + 1;
    273                 it != this->activeStates_.end(); ++it)
    274             {
    275                 bool threwException = false;
     208            // Update the GameStates bottom up in the stack
     209            this->updateGameStates();
     210
     211            // Core postUpdate (doesn't throw)
     212            if (!this->core_->postUpdate(*this->gameClock_))
     213            {
     214                this->stop();
     215                break;
     216            }
     217
     218            // Evaluate statistics
     219            this->updateStatistics();
     220
     221            // Limit framerate
     222            this->updateFPSLimiter();
     223        }
     224
     225        // UNLOAD all remaining states
     226        while (this->loadedStates_.size() > 1)
     227            this->unloadState(this->loadedStates_.back()->getName());
     228        this->loadedTopStateNode_ = this->rootStateNode_;
     229        this->requestedStateNodes_.clear();
     230    }
     231
     232    void Game::updateGameStateStack()
     233    {
     234        while (this->requestedStateNodes_.size() > 0)
     235        {
     236            shared_ptr<GameStateTreeNode> requestedStateNode = this->requestedStateNodes_.front();
     237            assert(this->loadedTopStateNode_);
     238            if (!this->loadedTopStateNode_->parent_.expired() && requestedStateNode == this->loadedTopStateNode_->parent_.lock())
     239                this->unloadState(loadedTopStateNode_->name_);
     240            else // has to be child
     241            {
    276242                try
    277243                {
    278                     // Add tick time for most of the states
    279                     uint64_t timeBeforeTick;
    280                     if (!(*it)->ignoreTickTime())
    281                         timeBeforeTick = this->gameClock_->getRealMicroseconds();
    282                     (*it)->update(*this->gameClock_);
    283                     if (!(*it)->ignoreTickTime())
    284                         this->addTickTime(static_cast<uint32_t>(this->gameClock_->getRealMicroseconds() - timeBeforeTick));
     244                    this->loadState(requestedStateNode->name_);
    285245                }
    286246                catch (const std::exception& ex)
    287247                {
    288                     threwException = true;
    289                     COUT(0) << "Exception while ticking: " << ex.what() << std::endl;
    290                 }
    291                 catch (...)
    292                 {
    293                     threwException = true;
    294                 }
    295                 if (threwException)
    296                 {
    297                     COUT(1) << "An exception occured while ticking GameState '" << (*it)->getName() << "'. This should really never happen!" << std::endl;
    298                     COUT(1) << "Unloading all GameStates depending on the one that crashed." << std::endl;
    299                     if ((*it)->getParent() != NULL)
    300                         this->requestState((*it)->getParent()->getName());
    301                     else
    302                         this->stop();
     248                    COUT(1) << "Error: Loading GameState '" << requestedStateNode->name_ << "' failed: " << ex.what() << std::endl;
     249                    // All scheduled operations have now been rendered inert --> flush them and issue a warning
     250                    if (this->requestedStateNodes_.size() > 1)
     251                        COUT(1) << "All " << this->requestedStateNodes_.size() - 1 << " scheduled transitions have been ignored." << std::endl;
     252                    this->requestedStateNodes_.clear();
    303253                    break;
    304254                }
    305 
    306             }
    307 
    308             // STATISTICS
    309             if (this->periodTime_ > this->configuration_->statisticsRefreshCycle_)
    310             {
    311                 std::list<StatisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();
    312                 assert(it != this->statisticsTickTimes_.end());
    313                 int64_t lastTime = currentTime - this->configuration_->statisticsAvgLength_;
    314                 if (static_cast<int64_t>(it->tickTime) < lastTime)
     255            }
     256            this->loadedTopStateNode_ = requestedStateNode;
     257            this->requestedStateNodes_.erase(this->requestedStateNodes_.begin());
     258        }
     259    }
     260
     261    void Game::updateGameStates()
     262    {
     263        // Note: The first element is the empty root state, which doesn't need ticking
     264        for (GameStateVector::const_iterator it = this->loadedStates_.begin() + 1;
     265            it != this->loadedStates_.end(); ++it)
     266        {
     267            std::string exceptionMessage;
     268            try
     269            {
     270                // Add tick time for most of the states
     271                uint64_t timeBeforeTick;
     272                if ((*it)->getInfo().bIgnoreTickTime)
     273                    timeBeforeTick = this->gameClock_->getRealMicroseconds();
     274                (*it)->update(*this->gameClock_);
     275                if ((*it)->getInfo().bIgnoreTickTime)
     276                    this->subtractTickTime(static_cast<int32_t>(this->gameClock_->getRealMicroseconds() - timeBeforeTick));
     277            }
     278            catch (const std::exception& ex)
     279            { exceptionMessage = ex.what(); }
     280            catch (...)
     281            { exceptionMessage = "Unknown exception"; }
     282            if (!exceptionMessage.empty())
     283            {
     284                COUT(1) << "An exception occurred while updating '" << (*it)->getName() << "': " << exceptionMessage << std::endl;
     285                COUT(1) << "This should really never happen!" << std::endl;
     286                COUT(1) << "Unloading all GameStates depending on the one that crashed." << std::endl;
     287                shared_ptr<GameStateTreeNode> current = this->loadedTopStateNode_;
     288                while (current->name_ != (*it)->getName() && current)
     289                    current = current->parent_.lock();
     290                if (current && current->parent_.lock())
     291                    this->requestState(current->parent_.lock()->name_);
     292                else
     293                    this->stop();
     294                break;
     295            }
     296        }
     297    }
     298
     299    void Game::updateStatistics()
     300    {
     301        // Add the tick time of this frame (rendering time has already been subtracted)
     302        uint64_t currentTime = gameClock_->getMicroseconds();
     303        uint64_t currentRealTime = gameClock_->getRealMicroseconds();
     304        this->statisticsTickTimes_.back().tickLength += currentRealTime - currentTime;
     305        this->periodTickTime_ += currentRealTime - currentTime;
     306        if (this->periodTime_ > this->configuration_->statisticsRefreshCycle_)
     307        {
     308            std::list<StatisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();
     309            assert(it != this->statisticsTickTimes_.end());
     310            int64_t lastTime = currentTime - this->configuration_->statisticsAvgLength_;
     311            if (static_cast<int64_t>(it->tickTime) < lastTime)
     312            {
     313                do
    315314                {
    316                     do
    317                     {
    318                         assert(this->periodTickTime_ >= it->tickLength);
    319                         this->periodTickTime_ -= it->tickLength;
    320                         ++it;
    321                         assert(it != this->statisticsTickTimes_.end());
    322                     } while (static_cast<int64_t>(it->tickTime) < lastTime);
    323                     this->statisticsTickTimes_.erase(this->statisticsTickTimes_.begin(), it);
    324                 }
    325 
    326                 uint32_t framesPerPeriod = this->statisticsTickTimes_.size();
    327                 this->avgFPS_ = static_cast<float>(framesPerPeriod) / (currentTime - this->statisticsTickTimes_.front().tickTime) * 1000000.0f;
    328                 this->avgTickTime_ = static_cast<float>(this->periodTickTime_) / framesPerPeriod / 1000.0f;
    329 
    330                 this->periodTime_ -= this->configuration_->statisticsRefreshCycle_;
    331             }
    332         }
    333 
    334         // UNLOAD all remaining states
    335         while (this->activeStates_.size() > 1)
    336             this->unloadState(this->activeStates_.back());
    337         this->activeStateNode_ = this->rootStateNode_;
    338         this->requestedStateNodes_.clear();
     315                    assert(this->periodTickTime_ >= it->tickLength);
     316                    this->periodTickTime_ -= it->tickLength;
     317                    ++it;
     318                    assert(it != this->statisticsTickTimes_.end());
     319                } while (static_cast<int64_t>(it->tickTime) < lastTime);
     320                this->statisticsTickTimes_.erase(this->statisticsTickTimes_.begin(), it);
     321            }
     322
     323            uint32_t framesPerPeriod = this->statisticsTickTimes_.size();
     324            this->avgFPS_ = static_cast<float>(framesPerPeriod) / (currentTime - this->statisticsTickTimes_.front().tickTime) * 1000000.0f;
     325            this->avgTickTime_ = static_cast<float>(this->periodTickTime_) / framesPerPeriod / 1000.0f;
     326
     327            this->periodTime_ -= this->configuration_->statisticsRefreshCycle_;
     328        }
     329    }
     330
     331    void Game::updateFPSLimiter()
     332    {
     333        // Why configuration_->fpsLimit_ - 1? No idea, but otherwise the fps rate is always (from 10 to 200!) one frame too high
     334        uint32_t nextTime = gameClock_->getMicroseconds() - excessSleepTime_ + static_cast<uint32_t>(1000000.0f / (configuration_->fpsLimit_ - 1));
     335        uint64_t currentRealTime = gameClock_->getRealMicroseconds();
     336        while (currentRealTime < nextTime - minimumSleepTime_)
     337        {
     338            usleep(nextTime - currentRealTime);
     339            currentRealTime = gameClock_->getRealMicroseconds();
     340        }
     341        // Integrate excess to avoid steady state error
     342        excessSleepTime_ = currentRealTime - nextTime;
     343        // Anti windup
     344        if (excessSleepTime_ > 50000) // 20ms is about the maximum time Windows would sleep for too long
     345            excessSleepTime_ = 50000;
    339346    }
    340347
     
    344351    }
    345352
    346     void Game::addTickTime(uint32_t length)
     353    void Game::subtractTickTime(int32_t length)
    347354    {
    348355        assert(!this->statisticsTickTimes_.empty());
    349         this->statisticsTickTimes_.back().tickLength += length;
    350         this->periodTickTime_+=length;
     356        this->statisticsTickTimes_.back().tickLength -= length;
     357        this->periodTickTime_ -= length;
    351358    }
    352359
     
    356363    void Game::requestState(const std::string& name)
    357364    {
    358         GameState* state = this->getState(name);
    359         if (state == NULL)
     365        if (!this->checkState(name))
     366        {
     367            COUT(2) << "Warning: GameState named '" << name << "' doesn't exist!" << std::endl;
    360368            return;
    361 
    362         //if (this->bChangingState_)
    363         //{
    364         //    COUT(2) << "Warning: Requesting GameStates while loading/unloading a GameState is illegal! Ignoring." << std::endl;
    365         //    return;
    366         //}
     369        }
     370
     371        if (this->bChangingState_)
     372        {
     373            COUT(2) << "Warning: Requesting GameStates while loading/unloading a GameState is illegal! Ignoring." << std::endl;
     374            return;
     375        }
    367376
    368377        shared_ptr<GameStateTreeNode> lastRequestedNode;
    369378        if (this->requestedStateNodes_.empty())
    370             lastRequestedNode = this->activeStateNode_;
     379            lastRequestedNode = this->loadedTopStateNode_;
    371380        else
    372381            lastRequestedNode = this->requestedStateNodes_.back();
    373         if (state == lastRequestedNode->state_)
     382        if (name == lastRequestedNode->name_)
    374383        {
    375384            COUT(2) << "Warning: Requesting the currently active state! Ignoring." << std::endl;
     
    381390        for (unsigned int i = 0; i < lastRequestedNode->children_.size(); ++i)
    382391        {
    383             if (lastRequestedNode->children_[i]->state_ == state)
     392            if (lastRequestedNode->children_[i]->name_ == name)
    384393            {
    385394                requestedNodes.push_back(lastRequestedNode->children_[i]);
     
    394403            while (currentNode != NULL)
    395404            {
    396                 if (currentNode->state_ == state)
     405                if (currentNode->name_ == name)
    397406                    break;
    398407                currentNode = currentNode->parent_.lock();
     
    418427        shared_ptr<GameStateTreeNode> lastRequestedNode;
    419428        if (this->requestedStateNodes_.empty())
    420             lastRequestedNode = this->activeStateNode_;
     429            lastRequestedNode = this->loadedTopStateNode_;
    421430        else
    422431            lastRequestedNode = this->requestedStateNodes_.back();
    423432        if (lastRequestedNode != this->rootStateNode_)
    424             this->requestState(lastRequestedNode->parent_.lock()->state_->getName());
     433            this->requestState(lastRequestedNode->parent_.lock()->name_);
    425434        else
    426435            COUT(2) << "Warning: Can't pop the internal dummy root GameState" << std::endl;
    427436    }
    428437
    429     GameState* Game::getState(const std::string& name)
    430     {
    431         std::map<std::string, GameState*>::const_iterator it = gameStates_.find(getLowercase(name));
    432         if (it != gameStates_.end())
     438    shared_ptr<GameState> Game::getState(const std::string& name)
     439    {
     440        GameStateMap::const_iterator it = constructedStates_.find(name);
     441        if (it != constructedStates_.end())
    433442            return it->second;
    434443        else
    435444        {
    436             COUT(1) << "Error: Could not find GameState '" << name << "'. Ignoring." << std::endl;
    437             return 0;
     445            std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(name);
     446            if (it != gameStateDeclarations_s.end())
     447                COUT(1) << "Error: GameState '" << name << "' has not yet been loaded." << std::endl;
     448            else
     449                COUT(1) << "Error: Could not find GameState '" << name << "'." << std::endl;
     450            return shared_ptr<GameState>();
    438451        }
    439452    }
     
    461474            std::string newStateName = it->first;
    462475            unsigned newLevel = it->second + 1; // empty root is 0
    463             GameState* newState = this->getState(newStateName);
    464             if (!newState)
     476            if (!this->checkState(newStateName))
    465477                ThrowException(GameState, "GameState with name '" << newStateName << "' not found!");
    466             if (newState == this->rootStateNode_->state_)
     478            if (newStateName == this->rootStateNode_->name_)
    467479                ThrowException(GameState, "You shouldn't use 'emptyRootGameState' in the hierarchy...");
    468480            shared_ptr<GameStateTreeNode> newNode(new GameStateTreeNode);
    469             newNode->state_ = newState;
     481            newNode->name_ = newStateName;
    470482
    471483            if (newLevel <= currentLevel)
     
    480492                newNode->parent_ = currentNode;
    481493                currentNode->children_.push_back(newNode);
    482                 currentNode->state_->addChild(newNode->state_);
    483494            }
    484495            else
     
    491502    /*** Internal ***/
    492503
    493     void Game::loadState(GameState* state)
     504    void Game::loadGraphics()
     505    {
     506        if (!GameMode::bShowsGraphics_s)
     507        {
     508            core_->loadGraphics();
     509            Loki::ScopeGuard graphicsUnloader = Loki::MakeObjGuard(*this, &Game::unloadGraphics);
     510            GameMode::bShowsGraphics_s = true;
     511
     512            // Construct all the GameStates that require graphics
     513            for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin();
     514                it != gameStateDeclarations_s.end(); ++it)
     515            {
     516                if (it->second.bGraphicsMode)
     517                {
     518                    // Game state loading failure is serious --> don't catch
     519                    shared_ptr<GameState> gameState = GameStateFactory::fabricate(it->second);
     520                    if (!constructedStates_.insert(std::make_pair(
     521                        it->second.stateName, gameState)).second)
     522                        assert(false); // GameState was already created!
     523                }
     524            }
     525            graphicsUnloader.Dismiss();
     526        }
     527    }
     528
     529    void Game::unloadGraphics()
     530    {
     531        if (GameMode::bShowsGraphics_s)
     532        {
     533            // Destroy all the GameStates that require graphics
     534            for (GameStateMap::iterator it = constructedStates_.begin(); it != constructedStates_.end();)
     535            {
     536                if (it->second->getInfo().bGraphicsMode)
     537                    constructedStates_.erase(it++);
     538                else
     539                    ++it;
     540            }
     541
     542            core_->unloadGraphics();
     543            GameMode::bShowsGraphics_s = false;
     544        }
     545    }
     546
     547    bool Game::checkState(const std::string& name) const
     548    {
     549        std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(name);
     550        if (it == gameStateDeclarations_s.end())
     551            return false;
     552        else
     553            return true;
     554    }
     555
     556    void Game::loadState(const std::string& name)
    494557    {
    495558        this->bChangingState_ = true;
     559        LOKI_ON_BLOCK_EXIT_OBJ(*this, &Game::resetChangingState);
     560
     561        // If state requires graphics, load it
     562        Loki::ScopeGuard graphicsUnloader = Loki::MakeObjGuard(*this, &Game::unloadGraphics);
     563        if (gameStateDeclarations_s[name].bGraphicsMode && !GameMode::showsGraphics())
     564            this->loadGraphics();
     565        else
     566            graphicsUnloader.Dismiss();
     567
     568        shared_ptr<GameState> state = this->getState(name);
    496569        state->activate();
    497         if (!this->activeStates_.empty())
    498             this->activeStates_.back()->activity_.topState = false;
    499         this->activeStates_.push_back(state);
     570        if (!this->loadedStates_.empty())
     571            this->loadedStates_.back()->activity_.topState = false;
     572        this->loadedStates_.push_back(state);
    500573        state->activity_.topState = true;
     574
     575        graphicsUnloader.Dismiss();
     576    }
     577
     578    void Game::unloadState(const std::string& name)
     579    {
     580        this->bChangingState_ = true;
     581        try
     582        {
     583            shared_ptr<GameState> state = this->getState(name);
     584            state->activity_.topState = false;
     585            this->loadedStates_.pop_back();
     586            if (!this->loadedStates_.empty())
     587                this->loadedStates_.back()->activity_.topState = true;
     588            state->deactivate();
     589        }
     590        catch (const std::exception& ex)
     591        {
     592            COUT(2) << "Warning: Unloading GameState '" << name << "' threw an exception: " << ex.what() << std::endl;
     593            COUT(2) << "         There might be potential resource leaks involved! To avoid this, improve exception-safety." << std::endl;
     594        }
     595        // Check if graphics is still required
     596        bool graphicsRequired = false;
     597        for (unsigned i = 0; i < loadedStates_.size(); ++i)
     598            graphicsRequired |= loadedStates_[i]->getInfo().bGraphicsMode;
     599        if (!graphicsRequired)
     600            this->unloadGraphics();
    501601        this->bChangingState_ = false;
    502602    }
    503603
    504     void Game::unloadState(orxonox::GameState* state)
    505     {
    506         this->bChangingState_ = true;
    507         state->activity_.topState = false;
    508         this->activeStates_.pop_back();
    509         if (!this->activeStates_.empty())
    510             this->activeStates_.back()->activity_.topState = true;
    511         try
    512         {
    513             state->deactivate();
    514         }
    515         catch (const std::exception& ex)
    516         {
    517             COUT(2) << "Warning: Unloading GameState '" << state->getName() << "' threw an exception: " << ex.what() << std::endl;
    518             COUT(2) << "         There might be potential resource leaks involved! To avoid this, improve exception-safety." << std::endl;
    519         }
    520         this->bChangingState_ = false;
    521     }
    522 
    523     std::map<std::string, Game::GameStateFactory*> Game::GameStateFactory::factories_s;
    524 
    525     /*static*/ GameState* Game::GameStateFactory::fabricate(const std::string& className, const GameStateConstrParams& params)
    526     {
    527         std::map<std::string, GameStateFactory*>::const_iterator it = factories_s.find(className);
     604    std::map<std::string, shared_ptr<Game::GameStateFactory> > Game::GameStateFactory::factories_s;
     605
     606    /*static*/ shared_ptr<GameState> Game::GameStateFactory::fabricate(const GameStateInfo& info)
     607    {
     608        std::map<std::string, shared_ptr<Game::GameStateFactory> >::const_iterator it = factories_s.find(info.className);
    528609        assert(it != factories_s.end());
    529         return it->second->fabricate(params);
    530     }
    531 
    532     /*static*/ void Game::GameStateFactory::destroyFactories()
    533     {
    534         for (std::map<std::string, GameStateFactory*>::const_iterator it = factories_s.begin(); it != factories_s.end(); ++it)
    535             delete it->second;
    536         factories_s.clear();
     610        return it->second->fabricateInternal(info);
    537611    }
    538612}
  • code/trunk/src/core/Game.h

    r3323 r3370  
    4444#include <vector>
    4545#include <boost/shared_ptr.hpp>
     46#include <boost/scoped_ptr.hpp>
    4647#include <boost/preprocessor/cat.hpp>
    4748
    4849#include "util/Debug.h"
    49 #include "util/StringUtils.h"
     50#include "util/Singleton.h"
    5051
    5152/**
     
    6061{
    6162    class GameConfiguration;
     63    using boost::scoped_ptr;
     64    using boost::shared_ptr;
     65
     66    //! Helper object required before GameStates are being constructed
     67    struct GameStateInfo
     68    {
     69        std::string stateName;
     70        std::string className;
     71        bool bIgnoreTickTime;
     72        bool bGraphicsMode;
     73    };
    6274
    6375    /**
    6476    @brief
    6577        Main class responsible for running the game.
     78    @remark
     79        You should only create this singleton once because it owns the Core class! (see remark there)
    6680    */
    67     class _CoreExport Game
     81    class _CoreExport Game : public Singleton<Game>
    6882    {
     83        friend class Singleton<Game>;
     84        typedef std::vector<shared_ptr<GameState> > GameStateVector;
     85        typedef std::map<std::string, shared_ptr<GameState> > GameStateMap;
     86        typedef boost::shared_ptr<GameStateTreeNode> GameStateTreeNodePtr;
    6987    public:
    7088        Game(const std::string& cmdLine);
     
    7290
    7391        void setStateHierarchy(const std::string& str);
    74         GameState* getState(const std::string& name);
     92        shared_ptr<GameState> getState(const std::string& name);
    7593
    7694        void run();
     
    86104        float getAvgFPS()      { return this->avgFPS_; }
    87105
    88         void addTickTime(uint32_t length);
     106        void subtractTickTime(int32_t length);
    89107
    90108        template <class T>
    91109        static bool declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bConsoleMode);
    92         static Game& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
    93110
    94111    private:
     
    97114        public:
    98115            virtual ~GameStateFactory() { }
    99             static GameState* fabricate(const std::string& className, const GameStateConstrParams& params);
     116            static shared_ptr<GameState> fabricate(const GameStateInfo& info);
    100117            template <class T>
    101118            static void createFactory(const std::string& className)
    102                 { factories_s[className] = new TemplateGameStateFactory<T>(); }
    103             static void destroyFactories();
     119                { factories_s[className].reset(new TemplateGameStateFactory<T>()); }
    104120        private:
    105             virtual GameState* fabricate(const GameStateConstrParams& params) = 0;
    106             static std::map<std::string, GameStateFactory*> factories_s;
     121            virtual shared_ptr<GameState> fabricateInternal(const GameStateInfo& info) = 0;
     122            static std::map<std::string, shared_ptr<GameStateFactory> > factories_s;
    107123        };
    108124        template <class T>
     
    110126        {
    111127        public:
    112             GameState* fabricate(const GameStateConstrParams& params)
    113                 { return new T(params); }
    114         };
    115 
    116         struct GameStateInfo
    117         {
    118             std::string stateName;
    119             std::string className;
    120             bool bIgnoreTickTime;
    121             bool bGraphicsMode;
     128            shared_ptr<GameState> fabricateInternal(const GameStateInfo& info)
     129                { return shared_ptr<GameState>(new T(info)); }
    122130        };
    123131
     
    130138        Game(Game&); // don't mess with singletons
    131139
    132         void loadState(GameState* state);
    133         void unloadState(GameState* state);
    134 
    135         std::map<std::string, GameState*>    gameStates_;
    136         std::vector<GameState*>              activeStates_;
    137         boost::shared_ptr<GameStateTreeNode> rootStateNode_;
    138         boost::shared_ptr<GameStateTreeNode> activeStateNode_;
    139         std::vector<boost::shared_ptr<GameStateTreeNode> > requestedStateNodes_;
    140 
    141         Core*                           core_;
    142         Clock*                          gameClock_;
    143         GameConfiguration*              configuration_;
    144 
    145         bool                            bChangingState_;
    146         bool                            bAbort_;
     140        void loadGraphics();
     141        void unloadGraphics();
     142
     143        bool checkState(const std::string& name) const;
     144        void loadState(const std::string& name);
     145        void unloadState(const std::string& name);
     146
     147        // Main loop structuring
     148        void updateGameStateStack();
     149        void updateGameStates();
     150        void updateStatistics();
     151        void updateFPSLimiter();
     152
     153        // ScopeGuard helper function
     154        void resetChangingState() { this->bChangingState_ = false; }
     155
     156        scoped_ptr<Clock>                  gameClock_;
     157        scoped_ptr<Core>                   core_;
     158        scoped_ptr<GameConfiguration>      configuration_;
     159
     160        GameStateMap                       constructedStates_;
     161        GameStateVector                    loadedStates_;
     162        GameStateTreeNodePtr               rootStateNode_;
     163        GameStateTreeNodePtr               loadedTopStateNode_;
     164        std::vector<GameStateTreeNodePtr>  requestedStateNodes_;
     165
     166        bool                               bChangingState_;
     167        bool                               bAbort_;
    147168
    148169        // variables for time statistics
    149         uint64_t                        statisticsStartTime_;
    150         std::list<StatisticsTickInfo>   statisticsTickTimes_;
    151         uint32_t                        periodTime_;
    152         uint32_t                        periodTickTime_;
    153         float                           avgFPS_;
    154         float                           avgTickTime_;
     170        uint64_t                           statisticsStartTime_;
     171        std::list<StatisticsTickInfo>      statisticsTickTimes_;
     172        uint32_t                           periodTime_;
     173        uint32_t                           periodTickTime_;
     174        float                              avgFPS_;
     175        float                              avgTickTime_;
     176        int                                excessSleepTime_;
     177        unsigned int                       minimumSleepTime_;
    155178
    156179        static std::map<std::string, GameStateInfo> gameStateDeclarations_s;
    157         static Game* singletonRef_s;        //!< Pointer to the Singleton
     180        static Game* singletonPtr_s;        //!< Pointer to the Singleton
    158181    };
    159182
     
    161184    /*static*/ bool Game::declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bGraphicsMode)
    162185    {
    163         std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(getLowercase(stateName));
     186        std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(stateName);
    164187        if (it == gameStateDeclarations_s.end())
    165188        {
    166             GameStateInfo& info = gameStateDeclarations_s[getLowercase(stateName)];
     189            GameStateInfo& info = gameStateDeclarations_s[stateName];
    167190            info.stateName = stateName;
    168191            info.className = className;
  • code/trunk/src/core/GameMode.h

    r2896 r3370  
    4141    class _CoreExport GameMode
    4242    {
     43        friend class Game;
     44
    4345        public:
    4446            static bool showsGraphics() { return bShowsGraphics_s; }
     
    4749            static bool isStandalone()  { return bIsStandalone_s; }
    4850            static bool isMaster()      { return bIsMaster_s; }
    49             static void setShowsGraphics(bool val) { bShowsGraphics_s = val; updateIsMaster(); }
     51
    5052            static void setHasServer    (bool val) { bHasServer_s     = val; updateIsMaster(); }
    5153            static void setIsClient     (bool val) { bIsClient_s      = val; updateIsMaster(); }
    5254            static void setIsStandalone (bool val) { bIsStandalone_s  = val; updateIsMaster(); }
    53             static void updateIsMaster  ()         { bIsMaster_s      = (bHasServer_s || bIsStandalone_s); }
    5455
    5556        private:
     
    5758            GameMode(const GameMode& inst);
    5859            ~GameMode();
     60
     61            static void updateIsMaster()
     62            {
     63                bIsMaster_s = (bHasServer_s || bIsStandalone_s);
     64            }
    5965
    6066            static bool bShowsGraphics_s;                   //!< global variable that tells whether to show graphics
  • code/trunk/src/core/GameState.cc

    r3280 r3370  
    3838#include "util/Exception.h"
    3939#include "util/OrxAssert.h"
     40#include "Game.h"
    4041
    4142namespace orxonox
     
    4546        Constructor only initialises variables and sets the name permanently.
    4647    */
    47     GameState::GameState(const GameStateConstrParams& params)
    48         : name_(params.name)
    49         , bIgnoreTickTime_(params.bIgnoreTickTime)
    50         , parent_(0)
     48    GameState::GameState(const GameStateInfo& info)
     49        : info_(info)
    5150    {
    5251        this->activity_.activating   = false;
     
    6766    }
    6867
    69     /**
    70     @brief
    71         Adds a child to the current tree. The Child can contain children of its own.
    72         But you cannot a state tree that already has an active state.
    73     @param state
    74         The state to be added.
    75     */
    76     void GameState::addChild(GameState* state)
     68    const std::string& GameState::getName() const
    7769    {
    78         assert(state != NULL);
    79 
    80         std::map<std::string, GameState*>::const_iterator it = this->children_.find(state->getName());
    81         if (it == this->children_.end())
    82         {
    83             this->children_[state->getName()] = state;
    84             // mark us as parent
    85             state->setParent(this);
    86         }
    87         else
    88         {
    89             ThrowException(GameState, "Cannot add two children with the same name");
    90         }
    91     }
    92 
    93     /**
    94     @brief
    95         Removes a child by instance. This splits the tree in two parts,
    96         each of them functional on its own.
    97     @param state
    98         GameState by instance pointer
    99     */
    100     void GameState::removeChild(GameState* state)
    101     {
    102         assert(state != NULL);
    103 
    104         std::map<std::string, GameState*>::iterator it = this->children_.find(state->getName());
    105         if (it != this->children_.end())
    106             this->children_.erase(it);
    107         else
    108         {
    109             ThrowException(GameState, "Game state '" + name_ + "' doesn't have a child named '"
    110                 + state->getName() + "'.");
    111         }
     70        return info_.stateName;
    11271    }
    11372
  • code/trunk/src/core/GameState.h

    r3280 r3370  
    4545    /**
    4646    @brief
    47         Helper class to group construction parameters for better genericity.
    48     */
    49     struct GameStateConstrParams
    50     {
    51         std::string name;
    52         bool bIgnoreTickTime;
    53     };
    54 
    55     /**
    56     @brief
    5747        An implementation of a tree to manage game states.
    5848        This leads to a certain hierarchy that is created at runtime.
     
    8777
    8878    public:
    89         GameState(const GameStateConstrParams& params);
     79        GameState(const GameStateInfo& info);
    9080        virtual ~GameState();
    9181
    92         const std::string& getName() const { return name_; }
    93         State getActivity()          const { return this->activity_; }
    94         GameState* getParent()       const { return this->parent_; }
    95 
    96         bool ignoreTickTime()        const { return this->bIgnoreTickTime_; }
    97 
    98         void addChild(GameState* state);
    99         void removeChild(GameState* state);
     82        const std::string& getName()   const;
     83        State getActivity()            const { return activity_; }
     84        const GameStateInfo& getInfo() const { return info_; }
    10085
    10186    protected:
     
    10590
    10691    private:
    107         void setParent(GameState* state) { this->parent_ = state; }
    10892        void setActivity(State activity);
    10993        void activateInternal();
     
    11195        void updateInternal(const Clock& time);
    11296
    113         const std::string                        name_;
    114         State                                    activity_;
    115         const bool                               bIgnoreTickTime_;
    116         GameState*                               parent_;
    117         std::map<std::string, GameState*>        children_;
     97        const GameStateInfo& info_;
     98        State                activity_;
    11899    };
    119100}
  • code/trunk/src/core/IRC.cc

    r3318 r3370  
    5757        try
    5858        {
    59             this->interpreter_->def("orxonox::irc::say", IRC::tcl_say, Tcl::variadic());
    60             this->interpreter_->def("orxonox::irc::privmsg", IRC::tcl_privmsg, Tcl::variadic());
    61             this->interpreter_->def("orxonox::irc::action", IRC::tcl_action, Tcl::variadic());
    62             this->interpreter_->def("orxonox::irc::info", IRC::tcl_info, Tcl::variadic());
     59            this->interpreter_->def("::orxonox::irc::say", IRC::tcl_say, Tcl::variadic());
     60            this->interpreter_->def("::orxonox::irc::privmsg", IRC::tcl_privmsg, Tcl::variadic());
     61            this->interpreter_->def("::orxonox::irc::action", IRC::tcl_action, Tcl::variadic());
     62            this->interpreter_->def("::orxonox::irc::info", IRC::tcl_info, Tcl::variadic());
    6363        }
    6464        catch (Tcl::tcl_error const &e)
  • code/trunk/src/core/Identifier.h

    r3333 r3370  
    500500#ifdef ORXONOX_COMPILER_MSVC
    501501        typedef Loki::TypeTraits<typename Loki::TypeTraits<T>::PointeeType>::NonConstType ClassType;
    502         return source->template getDerivedPointer<ClassType>(ClassIdentifier<ClassType>::getIdentifier()->getClassID());
     502        if (source != NULL)
     503            return source->template getDerivedPointer<ClassType>(ClassIdentifier<ClassType>::getIdentifier()->getClassID());
     504        else
     505            return NULL;
    503506#else
    504507        return dynamic_cast<T>(source);
  • code/trunk/src/core/Language.cc

    r3280 r3370  
    8989    // ###############################
    9090
    91     Language* Language::singletonRef_s = 0;
     91    Language* Language::singletonPtr_s = 0;
    9292
    9393    /**
     
    9696    Language::Language()
    9797    {
    98         assert(singletonRef_s == 0);
    99         singletonRef_s = this;
    100 
    10198        this->defaultLanguage_ = "default";
    10299        this->defaultLocalisation_ = "ERROR: LANGUAGE ENTRY DOESN'T EXIST!";
     
    113110        for (std::map<std::string, LanguageEntry*>::iterator it = this->languageEntries_.begin(); it != this->languageEntries_.end(); ++it)
    114111            delete (it->second);
    115 
    116         assert(singletonRef_s);
    117         singletonRef_s = 0;
    118112    }
    119113
  • code/trunk/src/core/Language.h

    r3280 r3370  
    3737    Usage:
    3838     - Set the entry with the default string:
    39        Language::getLanguage()->addEntry("label of the entry", "the string to translate");
     39       Language::getInstance()->addEntry("label of the entry", "the string to translate");
    4040
    4141     - Get the localisation of the entry in the configured language:
    42        std::cout << Language::getLanguage()->getLocalisation("name of the entry") << std::endl;
     42       std::cout << Language::getInstance()->getLocalisation("name of the entry") << std::endl;
    4343*/
    4444
     
    5151#include <string>
    5252#include <cassert>
     53#include "util/Singleton.h"
    5354
    5455#define AddLanguageEntry(label, fallbackstring) \
    55     orxonox::Language::getLanguage().addEntry(label, fallbackstring)
     56    orxonox::Language::getInstance().addEntry(label, fallbackstring)
    5657
    5758#define GetLocalisation(label) \
    58     orxonox::Language::getLanguage().getLocalisation(label)
     59    orxonox::Language::getInstance().getLocalisation(label)
    5960
    6061
     
    112113    // ###############################
    113114    //! The Language class manges the language files and entries and stores the LanguageEntry objects in a map.
    114     class _CoreExport Language
     115    class _CoreExport Language : public Singleton<Language>
    115116    {
     117        friend class Singleton<Language>;
    116118        friend class CoreConfiguration;
    117119
     
    120122            ~Language();
    121123
    122             static Language& getLanguage() { assert(singletonRef_s); return *singletonRef_s; }
    123124            void addEntry(const LanguageEntryLabel& label, const std::string& entry);
    124125            const std::string& getLocalisation(const LanguageEntryLabel& label) const;
     
    137138            std::map<std::string, LanguageEntry*> languageEntries_; //!< A map to store all LanguageEntry objects and their labels
    138139
    139             static Language* singletonRef_s;
     140            static Language* singletonPtr_s;
    140141    };
    141142}
  • code/trunk/src/core/Loader.cc

    r3196 r3370  
    3030
    3131#include <tinyxml/ticpp.h>
    32 #include <boost/filesystem.hpp>
    3332
    3433#include "util/Debug.h"
    3534#include "util/Exception.h"
    3635#include "BaseObject.h"
    37 #include "Core.h"
    3836#include "Iterator.h"
    3937#include "ObjectList.h"
     
    210208        return Loader::load(file, mask);
    211209    }
    212 
    213     std::vector<std::string> Loader::getLevelList()
    214     {
    215         std::vector<std::string> levelList;
    216 
    217         boost::filesystem::directory_iterator file(Core::getMediaPathString() + "levels");
    218         boost::filesystem::directory_iterator end;
    219 
    220         while (file != end)
    221         {
    222             if (!boost::filesystem::is_directory(*file) && file->string()[file->string().length()-1] != '~')
    223             {
    224                 std::string filename = file->path().leaf();
    225                 if (filename.length() > 4)
    226                     levelList.push_back(filename.substr(0,filename.length()-4));
    227             }
    228             ++file;
    229         }
    230         return levelList;
    231     }
    232210}
  • code/trunk/src/core/Loader.h

    r3196 r3370  
    5656
    5757            static ClassTreeMask currentMask_s;
    58             static std::vector<std::string> getLevelList();
    5958
    6059        private:
  • code/trunk/src/core/LuaBind.cc

    r3301 r3370  
    3939#include "util/Debug.h"
    4040#include "util/StringUtils.h"
    41 #include "ToluaBindCore.h"
    4241#include "Core.h"
    4342
    4443namespace orxonox
    4544{
    46   LuaBind* LuaBind::singletonRef_s = NULL;
     45  LuaBind* LuaBind::singletonPtr_s = NULL;
    4746
    4847  LuaBind::LuaBind()
    4948  {
    50     assert(LuaBind::singletonRef_s == 0);
    51     LuaBind::singletonRef_s = this;
    52 
    5349    this->includePath_ = Core::getMediaPathString();
    5450
     
    6561    luaopen_debug(luaState_);
    6662#endif
    67     tolua_Core_open(luaState_);
     63
     64    // Open all available tolua interfaces
     65    this->openToluaInterfaces(luaState_);
     66
    6867    output_ = "";
    6968    isRunning_ = false;
    7069  }
     70
     71  LuaBind::~LuaBind()
     72  {
     73    this->closeToluaInterfaces(luaState_);
     74  };
    7175
    7276  void LuaBind::luaPrint(const std::string& str)
     
    315319  }
    316320
     321  void LuaBind::addToluaInterface(int (*function)(lua_State*), const std::string& name)
     322  {
     323    toluaInterfaces_.push_back(std::make_pair(name, function));
     324    // Apply changes to our own lua state as well
     325    (*function)(luaState_);
     326  }
     327
     328  void LuaBind::openToluaInterfaces(lua_State* state)
     329  {
     330    for (unsigned int i = 0; i < toluaInterfaces_.size(); ++i)
     331      (*toluaInterfaces_[i].second)(state);
     332  }
     333
     334  void LuaBind::closeToluaInterfaces(lua_State* state)
     335  {
     336    for (unsigned int i = 0; i < toluaInterfaces_.size(); ++i)
     337    {
     338      lua_pushnil(state);
     339      lua_setglobal(state, toluaInterfaces_[i].first.c_str());
     340    }
     341  }
     342
    317343}
  • code/trunk/src/core/LuaBind.h

    r3196 r3370  
    4040#include <cassert>
    4141#include <string>
     42#include <vector>
    4243extern "C" {
    4344#include <lua.h>
    4445}
    4546
     47#include "util/Singleton.h"
     48
    4649// tolua_begin
    4750namespace orxonox
    4851{
    49   class _CoreExport LuaBind
     52  class _CoreExport LuaBind : public Singleton<LuaBind>
    5053  {
     54// tolua_end
     55    friend class Singleton<LuaBind>;
    5156
    52 // tolua_end
    5357    struct LoadS {
    5458      const char *s;
     
    5862    public:
    5963      LuaBind();
    60       inline ~LuaBind() { assert(singletonRef_s); LuaBind::singletonRef_s = NULL; };
     64      ~LuaBind();
    6165
    62       inline static LuaBind& getInstance() { assert(singletonRef_s); return *LuaBind::singletonRef_s; } // tolua_export
     66      static LuaBind& getInstance() { return Singleton<LuaBind>::getInstance(); } // tolua_export
    6367
    6468    void loadFile(const std::string& filename, bool luaTags);
     
    8387        { this->includePath_ = includepath; }
    8488
     89    void addToluaInterface(int (*function)(lua_State*), const std::string& name);
     90    void openToluaInterfaces(lua_State* state);
     91    void closeToluaInterfaces(lua_State* state);
     92
    8593    private:
    86       static LuaBind* singletonRef_s;
     94      static LuaBind* singletonPtr_s;
    8795
    8896      std::string luaSource_;
     
    9199      bool isRunning_;
    92100      std::string includePath_;
     101      std::vector<std::pair<std::string, int (*)(lua_State *L)> > toluaInterfaces_;
    93102
    94103  }; // tolua_export
  • code/trunk/src/core/Shell.cc

    r3301 r3370  
    5151    SetConsoleCommandShortcut(OutputHandler, debug);
    5252
    53     Shell* Shell::singletonRef_s = 0;
     53    Shell* Shell::singletonPtr_s = 0;
    5454
    5555    Shell::Shell()
    5656    {
    57         assert(singletonRef_s == 0);
    58         singletonRef_s = this;
    59 
    6057        int level = Core::getSoftDebugLevel(OutputHandler::LD_Shell);
    6158        Core::setSoftDebugLevel(OutputHandler::LD_Shell, -1);
     
    9289        if (this->inputBuffer_)
    9390            delete this->inputBuffer_;
    94         singletonRef_s = 0;
    9591    }
    9692
  • code/trunk/src/core/Shell.h

    r3280 r3370  
    6060    };
    6161
    62     class _CoreExport Shell : virtual public OrxonoxClass, public OutputBufferListener
     62    class _CoreExport Shell : public Singleton<Shell>, virtual public OrxonoxClass, public OutputBufferListener
    6363    {
     64        friend class Singleton<Shell>;
    6465        public:
    6566            Shell();
    6667            virtual ~Shell();
    67 
    68             static Shell& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
    6968
    7069            static void clearShell();
     
    148147            ConfigFileType commandHistoryConfigFileType_;
    149148
    150             static Shell* singletonRef_s;
     149            static Shell* singletonPtr_s;
    151150    };
    152151}
  • code/trunk/src/core/TclBind.cc

    r3318 r3370  
    3333#include <cpptcl/cpptcl.h>
    3434
     35#include "SpecialConfig.h"
    3536#include "util/Debug.h"
    3637#include "util/StringUtils.h"
    3738#include "CommandExecutor.h"
    3839#include "ConsoleCommand.h"
     40#include "Core.h"
    3941#include "TclThreadManager.h"
    4042
     
    4446    SetConsoleCommandShortcut(TclBind, bgerror);
    4547
    46     TclBind* TclBind::singletonRef_s = 0;
     48    TclBind* TclBind::singletonPtr_s = 0;
    4749
    4850    TclBind::TclBind(const std::string& datapath)
    4951    {
    50         assert(singletonRef_s == 0);
    51         singletonRef_s = this;
    5252        this->interpreter_ = 0;
    53         this->bSetTclLibPath_ = false;
     53        this->bSetTclDataPath_ = false;
    5454        this->setDataPath(datapath);
    5555    }
     
    5959        if (this->interpreter_)
    6060            delete this->interpreter_;
    61         singletonRef_s = 0;
    6261    }
    6362
     
    6564    {
    6665        // String has POSIX slashes
    67         this->tclLibPath_ = datapath + "tcl" + TCL_VERSION + '/';
    68         this->bSetTclLibPath_ = true;
    69 
    70         this->createTclInterpreter();
    71     }
    72 
    73     void TclBind::createTclInterpreter()
    74     {
    75         if (this->bSetTclLibPath_ && !this->interpreter_)
    76         {
    77             this->interpreter_ = new Tcl::interpreter(this->tclLibPath_);
    78             this->interpreter_->def("orxonox::query", TclBind::tcl_query, Tcl::variadic());
    79             this->interpreter_->def("orxonox::crossquery", TclThreadManager::tcl_crossquery, Tcl::variadic());
     66        this->tclDataPath_ = datapath + "tcl" + '/';
     67        this->bSetTclDataPath_ = true;
     68
     69        this->initializeTclInterpreter();
     70    }
     71
     72    void TclBind::initializeTclInterpreter()
     73    {
     74        if (this->bSetTclDataPath_ && !this->interpreter_)
     75        {
     76            this->interpreter_ = this->createTclInterpreter();
     77
     78            this->interpreter_->def("::orxonox::query", TclBind::tcl_query, Tcl::variadic());
     79            this->interpreter_->def("::orxonox::crossquery", TclThreadManager::tcl_crossquery, Tcl::variadic());
    8080            this->interpreter_->def("execute", TclBind::tcl_execute, Tcl::variadic());
    81             this->interpreter_->def("orxonox::crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
     81            this->interpreter_->def("::orxonox::crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
    8282
    8383            try
    8484            {
    85                 this->interpreter_->eval("proc query args { orxonox::query [join $args] }");
    86                 this->interpreter_->eval("proc crossquery {id args} { orxonox::crossquery 0 $id [join $args] }");
    87                 this->interpreter_->eval("proc crossexecute {id args} { orxonox::crossquery 0 $id [join $args] }");
     85                this->interpreter_->eval("proc query        {args}    { ::orxonox::query $args }");
     86                this->interpreter_->eval("proc crossquery   {id args} { ::orxonox::crossquery 0 $id $args }");
     87                this->interpreter_->eval("proc crossexecute {id args} { ::orxonox::crossquery 0 $id $args }");
     88                this->interpreter_->eval("proc running      {}        { return 1 }");
    8889                this->interpreter_->eval("set id 0");
    89                 this->interpreter_->eval("rename exit tcl::exit; proc exit {} { execute exit }");
    90                 this->interpreter_->eval("redef_puts");
     90                this->interpreter_->eval("rename exit ::tcl::exit; proc exit {} { execute exit }");
    9191            }
    9292            catch (Tcl::tcl_error const &e)
     
    9494            catch (std::exception const &e)
    9595            {   COUT(1) << "Error while creating Tcl-interpreter: " << e.what() << std::endl;   }
    96         }
    97     }
    98 
    99     void TclBind::createNewTclInterpreter()
    100     {
    101         if (this->interpreter_)
    102         {
    103             delete this->interpreter_;
    104             this->interpreter_ = 0;
    105         }
    106 
    107         this->createTclInterpreter();
     96            catch (...)
     97            {   COUT(1) << "Error while creating Tcl-interpreter." << std::endl;   }
     98        }
     99    }
     100
     101    Tcl::interpreter* TclBind::createTclInterpreter()
     102    {
     103        Tcl::interpreter* interpreter = new Tcl::interpreter();
     104        std::string libpath = TclBind::getTclLibraryPath();
     105
     106        try
     107        {
     108            if (libpath != "")
     109                interpreter->eval("set tcl_library \"" + libpath + "\"");
     110
     111            Tcl_Init(interpreter->get());
     112
     113            interpreter->eval("source \"" + TclBind::getInstance().tclDataPath_ + "/init.tcl\"");
     114        }
     115        catch (Tcl::tcl_error const &e)
     116        {   COUT(1) << "Tcl error while creating Tcl-interpreter: " << e.what() << std::endl; COUT(1) << "Error: Tcl isn't properly initialized. Orxonox might possibly not work like that." << std::endl;   }
     117        catch (std::exception const &e)
     118        {   COUT(1) << "Error while creating Tcl-interpreter: " << e.what() << std::endl; COUT(1) << "Error: Tcl isn't properly initialized. Orxonox might possibly not work like that." << std::endl;   }
     119        catch (...)
     120        {   COUT(1) << "Error while creating Tcl-interpreter." << std::endl; COUT(1) << "Error: Tcl isn't properly initialized. Orxonox might possibly not work like that." << std::endl;   }
     121
     122        return interpreter;
     123    }
     124
     125    std::string TclBind::getTclLibraryPath()
     126    {
     127#ifdef DEPENDENCY_PACKAGE_ENABLE
     128        if (Core::isDevelopmentRun())
     129            return (std::string(ORXONOX_DEP_LIB_PATH) + "/tcl");
     130        else
     131            return (Core::getRootPathString() + "lib/tcl");
     132#else
     133        return "";
     134#endif
    108135    }
    109136
     
    142169            try
    143170            {
    144                 std::string output = TclBind::getInstance().interpreter_->eval(tclcode);
     171                std::string output = TclBind::getInstance().interpreter_->eval("uplevel #0 " + tclcode);
    145172                if (output != "")
    146173                {
  • code/trunk/src/core/TclBind.h

    r3196 r3370  
    3434#include <cassert>
    3535#include <string>
     36#include "util/Singleton.h"
    3637
    3738namespace orxonox
    3839{
    39     class _CoreExport TclBind
     40    class _CoreExport TclBind : public Singleton<TclBind>
    4041    {
     42        friend class Singleton<TclBind>;
    4143        public:
    4244            TclBind(const std::string& datapath);
    4345            ~TclBind();
    44 
    45             static TclBind& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
    4646
    4747            static std::string tcl(const std::string& tclcode);
     
    4949
    5050            void setDataPath(const std::string& datapath);
    51             std::string getTclLibPath() const { return this->tclLibPath_; }
    52             void createTclInterpreter();
    53             void createNewTclInterpreter();
     51            const std::string& getTclDataPath() const { return this->tclDataPath_; }
     52            static std::string getTclLibraryPath();
     53
     54            void initializeTclInterpreter();
     55            static Tcl::interpreter* createTclInterpreter();
    5456            Tcl::interpreter* getTclInterpreter() const { return this->interpreter_; }
    5557
     
    6365
    6466            Tcl::interpreter* interpreter_;
    65             std::string tclLibPath_;
    66             bool bSetTclLibPath_;
     67            std::string tclDataPath_;
     68            bool bSetTclDataPath_;
    6769
    68             static TclBind* singletonRef_s;
     70            static TclBind* singletonPtr_s;
    6971    };
    7072}
  • code/trunk/src/core/TclThreadManager.cc

    r3326 r3370  
    5454    SetConsoleCommand(TclThreadManager, execute, false).argumentCompleter(0, autocompletion::tclthreads());
    5555    SetConsoleCommand(TclThreadManager, query,   false).argumentCompleter(0, autocompletion::tclthreads());
     56    SetConsoleCommand(TclThreadManager, source,  false).argumentCompleter(0, autocompletion::tclthreads());
    5657
    5758    /**
     
    9091        RegisterRootObject(TclThreadManager);
    9192
    92         assert(TclThreadManager::singletonPtr_s == 0);
    93         TclThreadManager::singletonPtr_s = this;
    94 
    9593        this->numInterpreterBundles_ = 0;
    9694
     
    115113    TclThreadManager::~TclThreadManager()
    116114    {
    117         TclThreadManager::singletonPtr_s = 0;
    118 
    119115        delete this->interpreterBundlesMutex_;
    120116//        delete this->mainInterpreterMutex_; // <-- temporary disabled to avoid crash if a thread is still actively queriyng
     
    240236        TclInterpreterBundle* newbundle = new TclInterpreterBundle();
    241237        newbundle->id_ = id;
    242         newbundle->interpreter_ = new Tcl::interpreter(TclBind::getInstance().getTclLibPath());
    243 
    244         // Initialize the new interpreter
    245         try
    246         {
    247             std::string id_string = getConvertedValue<unsigned int, std::string>(id);
    248 
    249             // Define the functions which are implemented in C++
    250             newbundle->interpreter_->def("orxonox::execute",      TclThreadManager::tcl_execute,      Tcl::variadic());
    251             newbundle->interpreter_->def("orxonox::crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
    252             newbundle->interpreter_->def("orxonox::query",        TclThreadManager::tcl_query,        Tcl::variadic());
    253             newbundle->interpreter_->def("orxonox::crossquery",   TclThreadManager::tcl_crossquery,   Tcl::variadic());
    254             newbundle->interpreter_->def("orxonox::running",      TclThreadManager::tcl_running);
    255 
    256             // Create threadspecific shortcuts for the functions above
    257             newbundle->interpreter_->def("execute",      TclThreadManager::tcl_execute,      Tcl::variadic());
    258             newbundle->interpreter_->def("crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
    259             newbundle->interpreter_->eval("proc query       args     { orxonox::query " + id_string + " $args }");
    260             newbundle->interpreter_->eval("proc crossquery {id args} { orxonox::crossquery " + id_string + " $id $args }");
    261 
    262             // Define a variable containing the thread id
    263             newbundle->interpreter_->eval("set id " + id_string);
    264 
    265             // Use our own exit function to avoid shutting down the whole program instead of just the interpreter
    266             newbundle->interpreter_->eval("rename exit tcl::exit");
    267             newbundle->interpreter_->eval("proc exit {} { execute TclThreadManager destroy " + id_string + " }");
    268 
    269             // Redefine some native functions
    270             newbundle->interpreter_->eval("redef_puts");
    271 
    272 //            newbundle->interpreter_->eval("rename while tcl::while");
    273 //            newbundle->interpreter_->eval("proc while {test command} { tcl::while {[uplevel 1 expr $test]} {uplevel 1 $command} }"); // (\"$test\" && [orxonox::running " + id + "]])
    274 //            newbundle->interpreter_->eval("rename for tcl::for");
    275 //            newbundle->interpreter_->eval("proc for {start test next command} { uplevel tcl::for \"$start\" \"$test\" \"$next\" \"$command\" }");
    276         }
    277         catch (const Tcl::tcl_error& e)
    278         {   newbundle->interpreter_ = 0; COUT(1) << "Tcl error while creating Tcl-interpreter (" << id << "): " << e.what() << std::endl;   }
    279         catch (const std::exception& e)
    280         {   newbundle->interpreter_ = 0; COUT(1) << "Error while creating Tcl-interpreter (" << id << "): " << e.what() << std::endl;   }
    281         catch (...)
    282         {   newbundle->interpreter_ = 0; COUT(1) << "An error occurred while creating a new Tcl-interpreter (" << id << ")" << std::endl;   }
     238        newbundle->interpreter_ = TclBind::createTclInterpreter();
     239
     240        TclThreadManager::initialize(newbundle);
    283241
    284242        {
     
    291249    }
    292250
     251    void TclThreadManager::initialize(TclInterpreterBundle* bundle)
     252    {
     253        std::string id_string = getConvertedValue<unsigned int, std::string>(bundle->id_);
     254
     255        // Initialize the new interpreter
     256        try
     257        {
     258            // Define the functions which are implemented in C++
     259            bundle->interpreter_->def("::orxonox::execute",      TclThreadManager::tcl_execute,      Tcl::variadic());
     260            bundle->interpreter_->def("::orxonox::crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
     261            bundle->interpreter_->def("::orxonox::query",        TclThreadManager::tcl_query,        Tcl::variadic());
     262            bundle->interpreter_->def("::orxonox::crossquery",   TclThreadManager::tcl_crossquery,   Tcl::variadic());
     263            bundle->interpreter_->def("::orxonox::running",      TclThreadManager::tcl_running);
     264
     265            // Create threadspecific shortcuts for the functions above
     266            bundle->interpreter_->def("execute",      TclThreadManager::tcl_execute,      Tcl::variadic());
     267            bundle->interpreter_->def("crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
     268            bundle->interpreter_->eval("proc query      {args}    { ::orxonox::query " + id_string + " $args }");
     269            bundle->interpreter_->eval("proc crossquery {id args} { ::orxonox::crossquery " + id_string + " $id $args }");
     270            bundle->interpreter_->eval("proc running    {}        { return [::orxonox::running " + id_string + "] }");
     271
     272            // Define a variable containing the thread id
     273            bundle->interpreter_->eval("set id " + id_string);
     274
     275            // Use our own exit function to avoid shutting down the whole program instead of just the interpreter
     276            bundle->interpreter_->eval("rename exit ::tcl::exit");
     277            bundle->interpreter_->eval("proc exit {} { execute TclThreadManager destroy " + id_string + " }");
     278
     279            // Redefine some native functions
     280            bundle->interpreter_->eval("rename while ::tcl::while");
     281            bundle->interpreter_->eval("rename ::orxonox::while while");
     282            bundle->interpreter_->eval("rename for ::tcl::for");
     283            bundle->interpreter_->eval("rename ::orxonox::for for");
     284        }
     285        catch (const Tcl::tcl_error& e)
     286        {   bundle->interpreter_ = 0; COUT(1) << "Tcl error while creating Tcl-interpreter (" << id_string << "): " << e.what() << std::endl;   }
     287        catch (const std::exception& e)
     288        {   bundle->interpreter_ = 0; COUT(1) << "Error while creating Tcl-interpreter (" << id_string << "): " << e.what() << std::endl;   }
     289        catch (...)
     290        {   bundle->interpreter_ = 0; COUT(1) << "An error occurred while creating a new Tcl-interpreter (" << id_string << ")" << std::endl;   }
     291    }
     292
    293293    /**
    294294        @brief Stops and destroys a given Tcl-interpreter
     
    298298        // TODO
    299299        // Not yet implemented
     300        TclInterpreterBundle* bundle = TclThreadManager::getInstance().getInterpreterBundle(id);
     301        if (bundle)
     302        {
     303            bundle->bRunning_ = false;
     304        }
    300305    }
    301306
     
    399404            {
    400405                // This query would lead to a deadlock - return with an error
    401                 this->error("Error: Circular query (" + this->dumpList(source_bundle->queriers_.getList()) + " " + getConvertedValue<unsigned int, std::string>(source_bundle->id_) \
     406                TclThreadManager::error("Error: Circular query (" + this->dumpList(source_bundle->queriers_.getList()) + " " + getConvertedValue<unsigned int, std::string>(source_bundle->id_) \
    402407                            + " -> " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) \
    403408                            + "), couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) \
     
    435440                    {
    436441                        // It's a query to the CommandExecutor
    437                         this->debug("TclThread_query -> CE: " + command);
     442                        TclThreadManager::debug("TclThread_query -> CE: " + command);
    438443                        if (!CommandExecutor::execute(command, false))
    439                             this->error("Error: Can't execute command \"" + command + "\"!");
     444                            TclThreadManager::error("Error: Can't execute command \"" + command + "\"!");
    440445
    441446                        if (CommandExecutor::getLastEvaluation().hasReturnvalue())
     
    445450                    {
    446451                        // It's a query to a Tcl interpreter
    447                         this->debug("TclThread_query: " + command);
    448 
    449                         output = this->eval(target_bundle, command);
     452                        TclThreadManager::debug("TclThread_query: " + command);
     453
     454                        output = TclThreadManager::eval(target_bundle, command, "query");
    450455                    }
    451456
     
    464469                    // This happens if the main thread tries to query a busy interpreter
    465470                    // To avoid a lock of the main thread, we simply don't proceed with the query in this case
    466                     this->error("Error: Couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) + ", interpreter is busy right now.");
     471                    TclThreadManager::error("Error: Couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) + ", interpreter is busy right now.");
    467472                }
    468473            }
     
    471476
    472477        return output;
     478    }
     479
     480    /**
     481        @brief Creates a non-interactive Tcl-interpreter which executes a file.
     482    */
     483    void TclThreadManager::source(const std::string& file)
     484    {
     485        boost::thread(boost::bind(&sourceThread, file));
    473486    }
    474487
     
    502515        else
    503516        {
    504             this->error("Error: No Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(id) + " existing.");
     517            TclThreadManager::error("Error: No Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(id) + " existing.");
    505518            return 0;
    506519        }
     
    544557    void TclThreadManager::error(const std::string& error)
    545558    {
    546         this->messageQueue_->push_back("error " + error);
     559        TclThreadManager::getInstance().messageQueue_->push_back("error " + error);
    547560    }
    548561
     
    552565    void TclThreadManager::debug(const std::string& error)
    553566    {
    554         this->messageQueue_->push_back("debug " + error);
     567        TclThreadManager::getInstance().messageQueue_->push_back("debug " + error);
    555568    }
    556569
     
    561574        Errors are reported through the @ref error function.
    562575    */
    563     std::string TclThreadManager::eval(TclInterpreterBundle* bundle, const std::string& command)
     576    std::string TclThreadManager::eval(TclInterpreterBundle* bundle, const std::string& command, const std::string& action)
    564577    {
    565578        Tcl_Interp* interpreter = bundle->interpreter_->get();
     
    570583        if (cc != TCL_OK)
    571584        {
    572             this->error("Tcl error (execute, ID " + getConvertedValue<unsigned int, std::string>(bundle->id_) + "): " + static_cast<std::string>(result));
     585            TclThreadManager::error("Tcl error (" + action + ", ID " + getConvertedValue<unsigned int, std::string>(bundle->id_) + "): " + static_cast<std::string>(result));
    573586            return "";
    574587        }
     
    590603    void tclThread(TclInterpreterBundle* bundle, std::string command)
    591604    {
    592         TclThreadManager::getInstance().debug("TclThread_execute: " + command);
    593 
    594         TclThreadManager::getInstance().eval(bundle, command);
     605        TclThreadManager::debug("TclThread_execute: " + command);
     606
     607        TclThreadManager::eval(bundle, command, "execute");
    595608
    596609        bundle->lock_->unlock();
    597610    }
     611
     612    /**
     613        @brief The main function of a non-interactive source thread. Executes the file.
     614        @param file The name of the file that should be executed by the non-interactive interpreter.
     615    */
     616    void sourceThread(std::string file)
     617    {
     618        TclThreadManager::debug("TclThread_source: " + file);
     619
     620        // Prepare the command-line arguments
     621        const int argc = 2;
     622        char* argv[argc];
     623        argv[0] = "tclthread";
     624        argv[1] = const_cast<char*>(file.c_str());
     625
     626        // Start the Tcl-command Tcl_Main with the Tcl_OrxonoxAppInit hook
     627        Tcl_Main(argc, argv, Tcl_OrxonoxAppInit);
     628
     629//        Tcl::object object(file);
     630//        int cc = Tcl_FSEvalFile(bundle->interpreter_->get(), object.get_object());
     631//        Tcl::details::result result(bundle->interpreter_->get());
     632//        if (cc != TCL_OK)
     633//            TclThreadManager::error("Tcl error (source, ID " + getConvertedValue<unsigned int, std::string>(bundle->id_) + "): " + static_cast<std::string>(result));
     634//
     635//        // Unlock the mutex
     636//        bundle->lock_->unlock();
     637    }
     638
     639    /**
     640        @brief A tcl-init hook to inject the non-interactive Tcl-interpreter into the TclThreadManager.
     641    */
     642    int Tcl_OrxonoxAppInit(Tcl_Interp* interp)
     643    {
     644        // Create a new interpreter bundle
     645        unsigned int id = TclThreadManager::create();
     646        TclInterpreterBundle* bundle = TclThreadManager::getInstance().getInterpreterBundle(id);
     647
     648        // Replace the default interpreter in the bundle with the non-interactive one (passed as an argument to this function)
     649        if (bundle->interpreter_)
     650            delete bundle->interpreter_;
     651        bundle->interpreter_ = new Tcl::interpreter(interp, true);
     652
     653        // Initialize the non-interactive interpreter (like in @ref TclBind::createTclInterpreter but exception safe)
     654        std::string libpath = TclBind::getTclLibraryPath();
     655        if (libpath != "")
     656            TclThreadManager::eval(bundle, "set tcl_library \"" + libpath + "\"", "source");
     657        int cc = Tcl_Init(interp);
     658        TclThreadManager::eval(bundle, "source \"" + TclBind::getInstance().getTclDataPath() + "/init.tcl\"", "source");
     659
     660        // Initialize the non-interactive interpreter also with the thread-specific stuff
     661        TclThreadManager::initialize(bundle);
     662
     663        // Lock the mutex (this will be locked until the thread finishes - no chance to interact with the interpreter)
     664        bundle->lock_->lock();
     665
     666        // Return to Tcl_Main
     667        if (!bundle->interpreter_)
     668            return TCL_ERROR;
     669        else
     670            return cc;
     671    }
    598672}
  • code/trunk/src/core/TclThreadManager.h

    r3321 r3370  
    3333
    3434#include <cassert>
     35#include <list>
    3536#include <map>
    3637#include <string>
    3738
     39#include "util/Singleton.h"
    3840#include "OrxonoxClass.h"
     41
     42struct Tcl_Interp;
    3943
    4044namespace orxonox
    4145{
    42     class _CoreExport TclThreadManager : public OrxonoxClass
     46    class _CoreExport TclThreadManager : public Singleton<TclThreadManager>, public OrxonoxClass
    4347    {
     48        friend class Singleton<TclThreadManager>;
    4449        friend class TclBind;
    4550        friend _CoreExport void tclThread(TclInterpreterBundle* bundle, std::string command);
     51        friend _CoreExport void sourceThread(std::string file);
     52        friend _CoreExport int Tcl_OrxonoxAppInit(Tcl_Interp* interp);
    4653
    4754        public:
    4855            TclThreadManager(Tcl::interpreter* interpreter);
    4956            virtual ~TclThreadManager();
    50 
    51             static TclThreadManager& getInstance() { assert(TclThreadManager::singletonPtr_s); return *TclThreadManager::singletonPtr_s; }
    5257
    5358            static unsigned int      create();
     
    5661            static void              execute(unsigned int target_id, const std::string& command);
    5762            static std::string       query(unsigned int target_id, const std::string& command);
     63            static void              source(const std::string& file);
    5864
    59             void error(const std::string& error);
    60             void debug(const std::string& error);
     65            static void error(const std::string& error);
     66            static void debug(const std::string& error);
    6167
    6268            void update(const Clock& time);
     
    7783            std::string dumpList(const std::list<unsigned int>& list);
    7884
    79             std::string eval(TclInterpreterBundle* bundle, const std::string& command);
     85            static void initialize(TclInterpreterBundle* bundle);
     86            static std::string eval(TclInterpreterBundle* bundle, const std::string& command, const std::string& action);
    8087
    8188            static TclThreadManager* singletonPtr_s;                            ///< Singleton pointer
     
    8996
    9097    _CoreExport void tclThread(TclInterpreterBundle* bundle, std::string command);
     98    _CoreExport void sourceThread(std::string file);
     99    _CoreExport int Tcl_OrxonoxAppInit(Tcl_Interp* interp);
    91100}
    92101
  • code/trunk/src/core/input/InputManager.cc

    r3331 r3370  
    6464    InputHandler InputHandler::EMPTY;
    6565
    66     InputManager* InputManager::singletonRef_s = 0;
     66    InputManager* InputManager::singletonPtr_s = 0;
    6767
    6868    //! Defines the |= operator for easier use.
     
    9393        RegisterRootObject(InputManager);
    9494
    95         assert(singletonRef_s == 0);
    96         singletonRef_s = this;
    97 
    9895        CCOUT(4) << "Constructing..." << std::endl;
    9996
     
    138135        }
    139136
     137        CCOUT(4) << "Construction complete." << std::endl;
    140138        internalState_ = Nothing;
    141         CCOUT(4) << "Construction complete." << std::endl;
    142139    }
    143140
     
    297294
    298295        CCOUT(4) << "Destruction complete." << std::endl;
    299         singletonRef_s = 0;
    300296    }
    301297
  • code/trunk/src/core/input/InputManager.h

    r3327 r3370  
    3737#include <vector>
    3838
     39#include "util/Singleton.h"
    3940#include "core/WindowEventListener.h"
    4041#include "InputState.h"
     
    6263          If the OIS::InputManager or the Keyboard fail, an exception is thrown.
    6364    */
    64     class _CoreExport InputManager : public WindowEventListener
     65    class _CoreExport InputManager : public Singleton<InputManager>, public WindowEventListener
    6566    {
     67        friend class Singleton<InputManager>;
    6668    public:
    6769        //! Represents internal states of the InputManager.
     
    168170            { return this->oisInputManager_; }
    169171
    170         //! Returns a reference to the singleton instance
    171         static InputManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
    172 
    173172    private: // functions
    174173        // don't mess with a Singleton
     
    211210        std::set<InputState*>               stateDestroyRequests_; //!< Requests to destroy a state
    212211
    213         static InputManager*                singletonRef_s;        //!< Pointer reference to the singleton
     212        static InputManager*                singletonPtr_s;        //!< Pointer reference to the singleton
    214213    };
    215214}
  • code/trunk/src/cpptcl/changes_orxonox.diff

    r2710 r3370  
    2828           Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE);
    2929           return TCL_ERROR;
    30 @@ -858,6 +858,18 @@
    31       owner_ = true;
    32  }
    33  
    34 +interpreter::interpreter(string const &libpath)
    35 +{
    36 +     interp_ =  Tcl_CreateInterp();
    37 +     owner_ = true;
    38 +
    39 +     try
    40 +     {
    41 +        this->eval("set tcl_library \"" + libpath + "\"");
    42 +        Tcl_Init(this->interp_);
    43 +     } catch (...) {}
    44 +}
    45 +
    46  interpreter::interpreter(Tcl_Interp *interp, bool owner)
    47  {
    48       interp_ =  interp;
    49 --- cpptcl.h    Wed Jan 28 20:56:11 2009
    50 +++ cpptcl.h    Sat Jan 24 12:52:54 2009
    51 @@ -467,6 +467,7 @@
    52  {
    53  public:
    54       interpreter();
    55 +     interpreter(std::string const &libpath);
    56       interpreter(Tcl_Interp *, bool owner = true);
    57       ~interpreter();
    58      
  • code/trunk/src/cpptcl/cpptcl.cc

    r3068 r3370  
    859859}
    860860
    861 interpreter::interpreter(string const &libpath)
    862 {
    863      interp_ =  Tcl_CreateInterp();
    864      owner_ = true;
    865 
    866      try
    867      {
    868         this->eval("set tcl_library \"" + libpath + "\"");
    869         Tcl_Init(this->interp_);
    870      } catch (...) {}
    871 }
    872 
    873861interpreter::interpreter(Tcl_Interp *interp, bool owner)
    874862{
  • code/trunk/src/cpptcl/cpptcl.h

    r3068 r3370  
    468468public:
    469469     interpreter();
    470      interpreter(std::string const &libpath);
    471470     interpreter(Tcl_Interp *, bool owner = true);
    472471     ~interpreter();
  • code/trunk/src/orxonox/CMakeLists.txt

    r3280 r3370  
    2020SET_SOURCE_FILES(ORXONOX_SRC_FILES
    2121  CameraManager.cc
    22   GraphicsManager.cc
    2322  LevelManager.cc
    2423  Main.cc
     
    2726)
    2827ADD_SUBDIRECTORY(gamestates)
    29 ADD_SUBDIRECTORY(gui)
    3028ADD_SUBDIRECTORY(interfaces)
    3129ADD_SUBDIRECTORY(objects)
     
    4341  TOLUA_FILES
    4442    LevelManager.h
    45     gui/GUIManager.h
    4643    objects/pickup/BaseItem.h
    4744    objects/pickup/PickupInventory.h
     
    5350  ${ORXONOX_WIN32}
    5451  LINK_LIBRARIES
     52    ${Boost_FILESYSTEM_LIBRARY}
     53    ${Boost_SYSTEM_LIBRARY} # Filesystem dependency
     54    ${Boost_THREAD_LIBRARY}
     55    ${Boost_DATE_TIME_LIBRARY} # Thread dependency
    5556    ${OGRE_LIBRARY}
    56     ${CEGUI_LIBRARY}
    57     ${LUA_LIBRARIES}
    58     ${CEGUILUA_LIBRARY}
    59     ${Boost_SYSTEM_LIBRARY}
    6057    ${OPENAL_LIBRARY}
    6158    ${ALUT_LIBRARY}
     
    6360    ${VORBIS_LIBRARY}
    6461    ${OGG_LIBRARY}
    65     ogreceguirenderer_orxonox
    6662    tinyxml++_orxonox
    6763    tolua++_orxonox
  • code/trunk/src/orxonox/CameraManager.cc

    r3280 r3370  
    3434#include "util/StringUtils.h"
    3535#include "core/GameMode.h"
     36#include "core/GUIManager.h"
    3637#include "core/ObjectList.h"
    3738#include "tools/Shader.h"
    3839#include "objects/worldentities/Camera.h"
    3940#include "objects/Scene.h"
    40 #include "gui/GUIManager.h"
    4141
    4242namespace orxonox
    4343{
    44     CameraManager* CameraManager::singletonRef_s = 0;
     44    CameraManager* CameraManager::singletonPtr_s = 0;
    4545
    4646    CameraManager::CameraManager(Ogre::Viewport* viewport)
    4747        : viewport_(viewport)
    4848    {
    49         assert(singletonRef_s == 0);
    50         singletonRef_s = this;
    51 
    5249        this->fallbackCamera_ = 0;
    5350    }
     
    5552    CameraManager::~CameraManager()
    5653    {
    57         assert(singletonRef_s != 0);
    58         singletonRef_s = 0;
    59 
    6054        if (this->fallbackCamera_)
    6155            this->fallbackCamera_->getSceneManager()->destroyCamera(this->fallbackCamera_);
  • code/trunk/src/orxonox/CameraManager.h

    r3196 r3370  
    4141#include <list>
    4242#include "util/OgreForwardRefs.h"
     43#include "util/Singleton.h"
    4344
    4445namespace orxonox
    4546{
    46     class _OrxonoxExport CameraManager
     47    class _OrxonoxExport CameraManager : public Singleton<CameraManager>
    4748    {
     49            friend class Singleton<CameraManager>;
    4850        public:
    4951            CameraManager(Ogre::Viewport* viewport);
     
    5759            void useCamera(Ogre::Camera* camera);
    5860
    59             static CameraManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
    60             static CameraManager* getInstancePtr() { return singletonRef_s; }
     61            static CameraManager* getInstancePtr() { return singletonPtr_s; }
    6162
    6263        private:
     
    6768            Ogre::Camera*         fallbackCamera_;
    6869
    69             static CameraManager* singletonRef_s;
     70            static CameraManager* singletonPtr_s;
    7071    };
    7172}
  • code/trunk/src/orxonox/LevelManager.cc

    r3280 r3370  
    3030
    3131#include <map>
     32#include <boost/filesystem.hpp>
    3233
    3334#include "core/CommandLine.h"
    3435#include "core/ConfigValueIncludes.h"
     36#include "core/Core.h"
    3537#include "core/CoreIncludes.h"
     38#include "core/Loader.h"
    3639#include "PlayerManager.h"
    3740#include "objects/Level.h"
     
    4245    SetCommandLineArgument(level, "").shortcut("l").information("Default level file (overrides LevelManager::defaultLevelName_ configValue)");
    4346
    44     LevelManager* LevelManager::singletonRef_s = 0;
     47    LevelManager* LevelManager::singletonPtr_s = 0;
    4548
    4649    LevelManager::LevelManager()
    4750    {
    48         assert(singletonRef_s == 0);
    49         singletonRef_s = this;
    50 
    5151        RegisterRootObject(LevelManager);
    5252        this->setConfigValues();
     
    6161    LevelManager::~LevelManager()
    6262    {
    63         assert(singletonRef_s != 0);
    64         singletonRef_s = 0;
    6563    }
    6664
     
    120118    }
    121119
    122     const std::string& LevelManager::getDefaultLevel()
     120    const std::string& LevelManager::getDefaultLevel() const
    123121    {
    124122        return defaultLevelName_;
    125123    }
     124
     125    std::string LevelManager::getAvailableLevelListItem(unsigned int index) const
     126    {
     127        if (index >= availableLevels_.size())
     128            return std::string();
     129        else
     130            return availableLevels_[index];
     131    }
     132
     133    void LevelManager::compileAvailableLevelList()
     134    {
     135        availableLevels_.clear();
     136
     137        boost::filesystem::directory_iterator file(Core::getMediaPathString() + "levels");
     138        boost::filesystem::directory_iterator end;
     139
     140        while (file != end)
     141        {
     142            if (!boost::filesystem::is_directory(*file) && file->string()[file->string().length()-1] != '~')
     143            {
     144                std::string filename = file->path().leaf();
     145                if (filename.length() > 4)
     146                    availableLevels_.push_back(filename.substr(0,filename.length()-4));
     147            }
     148            ++file;
     149        }
     150    }
    126151}
  • code/trunk/src/orxonox/LevelManager.h

    r3304 r3370  
    3535#include <list>
    3636#include <string>
     37
     38#include "util/Singleton.h"
    3739#include "core/OrxonoxClass.h"
    3840
     
    4244    class _OrxonoxExport LevelManager
    4345    // tolua_end
    44         : public OrxonoxClass
     46        : public Singleton<LevelManager>, public OrxonoxClass
    4547    { // tolua_export
     48            friend class Singleton<LevelManager>;
    4649        public:
    4750            LevelManager();
     
    5558
    5659            void setDefaultLevel(const std::string& levelName); //tolua_export
    57             const std::string& getDefaultLevel(); //tolua_export
     60            const std::string& getDefaultLevel() const; //tolua_export
     61            void compileAvailableLevelList(); //tolua_export
     62            std::string getAvailableLevelListItem(unsigned int index) const; //tolua_export
    5863
    59             static LevelManager* getInstancePtr() { return singletonRef_s; }
    60             static LevelManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; } // tolua_export
     64            static LevelManager* getInstancePtr() { return singletonPtr_s; }
     65            static LevelManager& getInstance()    { return Singleton<LevelManager>::getInstance(); } // tolua_export
    6166
    6267        private:
     
    6671
    6772            std::list<Level*> levels_s;
     73            std::vector<std::string> availableLevels_;
    6874
    6975            // config values
    7076            std::string defaultLevelName_;
    7177
    72             static LevelManager* singletonRef_s;
     78            static LevelManager* singletonPtr_s;
    7379    }; // tolua_export
    7480} // tolua_export
  • code/trunk/src/orxonox/Main.cc

    r3323 r3370  
    4646#include "util/Debug.h"
    4747#include "util/Exception.h"
     48#include "core/CommandLine.h"
    4849#include "core/Game.h"
     50
     51SetCommandLineSwitch(console).information("Start in console mode (text IO only)");
     52// Shortcuts for easy direct loading
     53SetCommandLineSwitch(server).information("Start in server mode");
     54SetCommandLineSwitch(client).information("Start in client mode");
     55SetCommandLineSwitch(dedicated).information("Start in dedicated server mode");
     56SetCommandLineSwitch(standalone).information("Start in standalone mode");
    4957
    5058/*
     
    8694
    8795        game->requestState("root");
     96
     97        // Some development hacks (not really, but in the future, this calls won't make sense anymore)
     98        if (CommandLine::getValue("standalone").getBool())
     99            Game::getInstance().requestStates("graphics, standalone, level");
     100        else if (CommandLine::getValue("server").getBool())
     101            Game::getInstance().requestStates("graphics, server, level");
     102        else if (CommandLine::getValue("client").getBool())
     103            Game::getInstance().requestStates("graphics, client, level");
     104        else if (CommandLine::getValue("dedicated").getBool())
     105            Game::getInstance().requestStates("dedicated, level");
     106        else if (CommandLine::getValue("console").getBool())
     107            Game::getInstance().requestStates("ioConsole");
     108        else
     109            Game::getInstance().requestStates("graphics, mainMenu");
    88110    }
    89111    catch (const std::exception& ex)
  • code/trunk/src/orxonox/OrxonoxPrecompiledHeaders.h

    r3322 r3370  
    9090//#include "core/ConfigValueIncludes.h" // 19
    9191//#include "core/ConsoleCommand.h" // 15
    92 #include "core/Core.h"
     92//#include "core/Core.h" // ?, but not many times
    9393#include "core/CoreIncludes.h"
    94 #include "core/GameMode.h"
    9594#include "core/XMLPort.h"
    9695
  • code/trunk/src/orxonox/OrxonoxPrereqs.h

    r3327 r3370  
    7373        };
    7474    }
    75 
    76     class GraphicsManager;
    77     class OgreWindowEventListener;
    78     class Settings;
    7975
    8076    class RadarViewable;
     
    277273    class Map;
    278274
    279     //gui
    280     class GUIManager;
    281 
    282275    //sound
    283276    class SoundBase;
     
    293286}
    294287
    295 namespace CEGUI
    296 {
    297     class DefaultLogger;
    298     class Logger;
    299     class LuaScriptModule;
    300 
    301     class OgreCEGUIRenderer;
    302     class OgreCEGUIResourceProvider;
    303     class OgreCEGUITexture;
    304 }
    305 
    306288// Bullet Physics Engine
    307289class btTransform;
     
    330312typedef int ALint;
    331313
    332 // Lua
    333 struct lua_State;
    334 
    335314#endif /* _OrxonoxPrereqs_H__ */
  • code/trunk/src/orxonox/PawnManager.cc

    r3196 r3370  
    3434namespace orxonox
    3535{
    36     PawnManager* PawnManager::singletonRef_s = 0;
     36    PawnManager* PawnManager::singletonPtr_s = 0;
    3737
    3838    PawnManager::PawnManager()
    3939    {
    4040        RegisterRootObject(PawnManager);
    41 
    42         assert(PawnManager::singletonRef_s == 0);
    43         PawnManager::singletonRef_s = this;
    4441    }
    4542
    4643    PawnManager::~PawnManager()
    4744    {
    48         assert(PawnManager::singletonRef_s != 0);
    49         PawnManager::singletonRef_s = 0;
    5045    }
    5146
    5247    void PawnManager::touch()
    5348    {
    54         if (!PawnManager::singletonRef_s)
     49        if (!PawnManager::singletonPtr_s)
    5550            new PawnManager();
    5651    }
  • code/trunk/src/orxonox/PawnManager.h

    r3196 r3370  
    3131
    3232#include "OrxonoxPrereqs.h"
     33
     34#include "util/Singleton.h"
    3335#include "interfaces/Tickable.h"
    3436
    3537namespace orxonox
    3638{
    37     class _OrxonoxExport PawnManager : public Tickable
     39    class _OrxonoxExport PawnManager : protected Singleton<PawnManager>, public Tickable
    3840    {
     41            friend class Singleton<PawnManager>;
    3942        public:
    4043            static void touch();
     
    4649            virtual ~PawnManager();
    4750
    48             static PawnManager* singletonRef_s;
     51            static PawnManager* singletonPtr_s;
    4952    };
    5053}
  • code/trunk/src/orxonox/PlayerManager.cc

    r3297 r3370  
    3737namespace orxonox
    3838{
    39     PlayerManager* PlayerManager::singletonRef_s = 0;
     39    PlayerManager* PlayerManager::singletonPtr_s = 0;
    4040
    4141    PlayerManager::PlayerManager()
    4242    {
    4343        RegisterRootObject(PlayerManager);
    44 
    45         assert(singletonRef_s == 0);
    46         singletonRef_s = this;
    4744
    4845        this->getConnectedClients();
     
    5148    PlayerManager::~PlayerManager()
    5249    {
    53         assert(singletonRef_s);
    54         singletonRef_s = 0;
    5550    }
    5651
  • code/trunk/src/orxonox/PlayerManager.h

    r3196 r3370  
    3434#include <cassert>
    3535#include <map>
     36#include "util/Singleton.h"
    3637#include "network/ClientConnectionListener.h"
    3738
    3839namespace orxonox
    3940{
    40     class _OrxonoxExport PlayerManager : public ClientConnectionListener
     41    class _OrxonoxExport PlayerManager : public Singleton<PlayerManager>, public ClientConnectionListener
    4142    {
     43            friend class Singleton<PlayerManager>;
    4244        public:
    4345            PlayerManager();
    4446            virtual ~PlayerManager();
    45 
    46             inline static PlayerManager& getInstance()
    47                 { assert(singletonRef_s); return *singletonRef_s; }
    4847
    4948            PlayerInfo* getClient(unsigned int clientID) const;
     
    5756            std::map<unsigned int, PlayerInfo*> clients_;
    5857
    59             static PlayerManager* singletonRef_s;
     58            static PlayerManager* singletonPtr_s;
    6059    };
    6160}
  • code/trunk/src/orxonox/gamestates/GSClient.cc

    r3280 r3370  
    4242    SetCommandLineArgument(ip, "127.0.0.1").information("Sever IP as strin in the form #.#.#.#");
    4343
    44     GSClient::GSClient(const GameStateConstrParams& params)
    45         : GameState(params)
     44    GSClient::GSClient(const GameStateInfo& info)
     45        : GameState(info)
    4646        , client_(0)
    4747    {
  • code/trunk/src/orxonox/gamestates/GSClient.h

    r3280 r3370  
    4040    {
    4141    public:
    42         GSClient(const GameStateConstrParams& params);
     42        GSClient(const GameStateInfo& info);
    4343        ~GSClient();
    4444
  • code/trunk/src/orxonox/gamestates/GSDedicated.cc

    r3351 r3370  
    5555    termios* GSDedicated::originalTerminalSettings_;
    5656
    57     GSDedicated::GSDedicated(const GameStateConstrParams& params)
    58         : GameState(params)
     57    GSDedicated::GSDedicated(const GameStateInfo& info)
     58        : GameState(info)
    5959        , server_(0)
    6060        , closeThread_(false)
  • code/trunk/src/orxonox/gamestates/GSDedicated.h

    r3304 r3370  
    4848    {
    4949    public:
    50         GSDedicated(const GameStateConstrParams& params);
     50        GSDedicated(const GameStateInfo& info);
    5151        ~GSDedicated();
    5252
  • code/trunk/src/orxonox/gamestates/GSGraphics.cc

    r3327 r3370  
    3535#include "GSGraphics.h"
    3636
    37 #include <boost/filesystem.hpp>
    38 #include <OgreRenderWindow.h>
    39 
    4037#include "util/Convert.h"
    4138#include "core/Clock.h"
     
    4441#include "core/Core.h"
    4542#include "core/Game.h"
    46 #include "core/GameMode.h"
     43#include "core/GUIManager.h"
    4744#include "core/input/InputManager.h"
    4845#include "core/input/KeyBinder.h"
     
    5148#include "core/XMLFile.h"
    5249#include "overlays/console/InGameConsole.h"
    53 #include "gui/GUIManager.h"
    5450#include "sound/SoundManager.h"
    55 #include "GraphicsManager.h"
     51
     52// HACK:
     53#include "overlays/map/Map.h"
    5654
    5755namespace orxonox
    5856{
    59     DeclareGameState(GSGraphics, "graphics", true, true);
     57    DeclareGameState(GSGraphics, "graphics", false, true);
    6058
    61     GSGraphics::GSGraphics(const GameStateConstrParams& params)
    62         : GameState(params)
    63         , inputManager_(0)
     59    GSGraphics::GSGraphics(const GameStateInfo& info)
     60        : GameState(info)
    6461        , console_(0)
    65         , guiManager_(0)
    66         , graphicsManager_(0)
    6762        , soundManager_(0)
    6863        , masterKeyBinder_(0)
     
    7065        , debugOverlay_(0)
    7166    {
     67        // load master key bindings
     68        masterInputState_ = InputManager::getInstance().createInputState("master", true);
     69        masterKeyBinder_ = new KeyBinder();
     70        masterInputState_->setKeyHandler(masterKeyBinder_);
    7271    }
    7372
    7473    GSGraphics::~GSGraphics()
    7574    {
     75        InputManager::getInstance().destroyState("master");
     76        delete this->masterKeyBinder_;
    7677    }
    7778
     
    9394    void GSGraphics::activate()
    9495    {
    95         GameMode::setShowsGraphics(true);
    96 
    97         // Load OGRE including the render window
    98         this->graphicsManager_ = new GraphicsManager();
    99 
    10096        // load debug overlay
    10197        COUT(3) << "Loading Debug Overlay..." << std::endl;
    102         this->debugOverlay_ = new XMLFile((Core::getMediaPath() / "overlay" / "debug.oxo").string());
     98        this->debugOverlay_ = new XMLFile(Core::getMediaPathString() + "overlay/debug.oxo");
    10399        Loader::open(debugOverlay_);
    104100
    105         // The render window width and height are used to set up the mouse movement.
    106         size_t windowHnd = 0;
    107         Ogre::RenderWindow* renderWindow = GraphicsManager::getInstance().getRenderWindow();
    108         renderWindow->getCustomAttribute("WINDOW", &windowHnd);
    109 
    110         // Calls the InputManager which sets up the input devices.
    111         inputManager_ = new InputManager(windowHnd);
    112 
    113         // load master key bindings
    114         masterInputState_ = InputManager::getInstance().createInputState("master", true);
    115         masterKeyBinder_ = new KeyBinder();
    116101        masterKeyBinder_->loadBindings("masterKeybindings.ini");
    117         masterInputState_->setKeyHandler(masterKeyBinder_);
    118102
    119103        // Load the SoundManager
     
    123107        console_ = new InGameConsole();
    124108        console_->initialise();
    125 
    126         // load the CEGUI interface
    127         guiManager_ = new GUIManager();
    128         guiManager_->initialise(renderWindow);
    129109
    130110        // add console command to toggle GUI
     
    154134*/
    155135
    156         masterInputState_->setHandler(0);
    157         InputManager::getInstance().destroyState("master");
    158         delete this->masterKeyBinder_;
    159 
    160         delete this->guiManager_;
    161136        delete this->console_;
    162137
     
    166141        delete this->soundManager_;
    167142
    168         delete this->inputManager_;
    169         this->inputManager_ = 0;
    170 
    171         delete graphicsManager_;
    172 
    173         GameMode::setShowsGraphics(false);
     143        // HACK: (destroys a resource smart pointer)
     144        Map::hackDestroyMap();
    174145    }
    175146
     
    203174        }
    204175
    205         uint64_t timeBeforeTick = time.getRealMicroseconds();
    206 
    207         this->inputManager_->update(time);
    208176        this->console_->update(time);
    209 
    210         uint64_t timeAfterTick = time.getRealMicroseconds();
    211 
    212         // Also add our tick time
    213         Game::getInstance().addTickTime(timeAfterTick - timeBeforeTick);
    214 
    215         // Process gui events
    216         this->guiManager_->update(time);
    217         // Render
    218         this->graphicsManager_->update(time);
    219177    }
    220178}
  • code/trunk/src/orxonox/gamestates/GSGraphics.h

    r3327 r3370  
    5050    {
    5151    public:
    52         GSGraphics(const GameStateConstrParams& params);
     52        GSGraphics(const GameStateInfo& info);
    5353        ~GSGraphics();
    5454
     
    6161    private:
    6262        // managed singletons
    63         InputManager*         inputManager_;        //!< Reference to input management
    6463        InGameConsole*        console_;
    65         GUIManager*           guiManager_;          //!< Interface to GUI
    66         GraphicsManager*      graphicsManager_;     //!< Interface to Ogre
    6764        SoundManager*         soundManager_;        //!< Keeps track of SoundBase objects
    6865
  • code/trunk/src/orxonox/gamestates/GSIOConsole.cc

    r3280 r3370  
    3838    DeclareGameState(GSIOConsole, "ioConsole", false, false);
    3939
    40     GSIOConsole::GSIOConsole(const GameStateConstrParams& params)
    41         : GameState(params)
     40    GSIOConsole::GSIOConsole(const GameStateInfo& info)
     41        : GameState(info)
    4242    {
    4343    }
  • code/trunk/src/orxonox/gamestates/GSIOConsole.h

    r3280 r3370  
    3838    {
    3939    public:
    40         GSIOConsole(const GameStateConstrParams& params);
     40        GSIOConsole(const GameStateInfo& info);
    4141        ~GSIOConsole();
    4242
  • code/trunk/src/orxonox/gamestates/GSLevel.cc

    r3327 r3370  
    4040#include "core/GameMode.h"
    4141#include "core/Core.h"
     42#include "core/GraphicsManager.h"
     43#include "core/GUIManager.h"
    4244#include "core/Loader.h"
    4345#include "core/XMLFile.h"
     
    4749#include "objects/quest/QuestManager.h"
    4850#include "overlays/notifications/NotificationManager.h"
    49 #include "gui/GUIManager.h"
    5051#include "CameraManager.h"
    51 #include "GraphicsManager.h"
    5252#include "LevelManager.h"
    5353#include "PlayerManager.h"
     
    5555namespace orxonox
    5656{
    57     DeclareGameState(GSLevel, "level", false, true);
     57    DeclareGameState(GSLevel, "level", false, false);
    5858    SetConsoleCommand(GSLevel, showIngameGUI, true);
    5959
    6060    XMLFile* GSLevel::startFile_s = NULL;
    6161
    62     GSLevel::GSLevel(const GameStateConstrParams& params)
    63         : GameState(params)
     62    GSLevel::GSLevel(const GameStateInfo& info)
     63        : GameState(info)
    6464        , keyBinder_(0)
    6565        , gameInputState_(0)
  • code/trunk/src/orxonox/gamestates/GSLevel.h

    r3327 r3370  
    4141    {
    4242    public:
    43         GSLevel(const GameStateConstrParams& params);
     43        GSLevel(const GameStateInfo& info);
    4444        ~GSLevel();
    4545        void setConfigValues();
  • code/trunk/src/orxonox/gamestates/GSMainMenu.cc

    r3327 r3370  
    3636#include "core/Clock.h"
    3737#include "core/ConsoleCommand.h"
     38#include "core/GraphicsManager.h"
     39#include "core/GUIManager.h"
    3840#include "objects/Scene.h"
    39 #include "gui/GUIManager.h"
    4041#include "sound/SoundMainMenu.h"
    41 #include "GraphicsManager.h"
    4242
    4343namespace orxonox
     
    4545    DeclareGameState(GSMainMenu, "mainMenu", false, true);
    4646
    47     GSMainMenu::GSMainMenu(const GameStateConstrParams& params)
    48         : GameState(params)
     47    GSMainMenu::GSMainMenu(const GameStateInfo& info)
     48        : GameState(info)
    4949        , inputState_(0)
    50     {
    51     }
    52 
    53     GSMainMenu::~GSMainMenu()
    54     {
    55     }
    56 
    57     void GSMainMenu::activate()
    5850    {
    5951        inputState_ = InputManager::getInstance().createInputState("mainMenu");
     
    6557        // and a Camera
    6658        this->camera_ = this->scene_->getSceneManager()->createCamera("mainMenu/Camera");
     59    }
    6760
     61    GSMainMenu::~GSMainMenu()
     62    {
     63        InputManager::getInstance().destroyState("mainMenu");
     64
     65        this->scene_->getSceneManager()->destroyCamera(this->camera_);
     66        delete this->scene_;
     67    }
     68
     69    void GSMainMenu::activate()
     70    {
    6871        // show main menu
    69         GUIManager::getInstance().showGUI("mainmenu_3");
     72        GUIManager::getInstance().showGUI("mainmenu_4");
    7073        GUIManager::getInstance().setCamera(this->camera_);
    7174        GraphicsManager::getInstance().setCamera(this->camera_);
     
    107110
    108111        InputManager::getInstance().leaveState("mainMenu");
    109         InputManager::getInstance().destroyState("mainMenu");
    110112
    111113        GUIManager::getInstance().setCamera(0);
    112114        GraphicsManager::getInstance().setCamera(0);
    113         this->scene_->getSceneManager()->destroyCamera(this->camera_);
    114         delete this->scene_;
    115115
    116116/*
  • code/trunk/src/orxonox/gamestates/GSMainMenu.h

    r3327 r3370  
    4040    {
    4141    public:
    42         GSMainMenu(const GameStateConstrParams& params);
     42        GSMainMenu(const GameStateInfo& info);
    4343        ~GSMainMenu();
    4444
  • code/trunk/src/orxonox/gamestates/GSRoot.cc

    r3304 r3370  
    3030
    3131#include "core/Clock.h"
    32 #include "core/CommandLine.h"
    3332#include "core/ConsoleCommand.h"
    3433#include "core/Game.h"
    3534#include "core/GameMode.h"
     35#include "core/LuaBind.h"
    3636#include "network/NetworkFunction.h"
     37#include "ToluaBindCore.h"
     38#include "ToluaBindOrxonox.h"
    3739#include "tools/Timer.h"
    3840#include "interfaces/TimeFactorListener.h"
     
    4244namespace orxonox
    4345{
    44     DeclareGameState(GSRoot, "root", true, false);
    45     SetCommandLineSwitch(console).information("Start in console mode (text IO only)");
    46     // Shortcuts for easy direct loading
    47     SetCommandLineSwitch(server).information("Start in server mode");
    48     SetCommandLineSwitch(client).information("Start in client mode");
    49     SetCommandLineSwitch(dedicated).information("Start in dedicated server mode");
    50     SetCommandLineSwitch(standalone).information("Start in standalone mode");
     46    DeclareGameState(GSRoot, "root", false, false);
    5147
    52     GSRoot::GSRoot(const GameStateConstrParams& params)
    53         : GameState(params)
     48    GSRoot::GSRoot(const GameStateInfo& info)
     49        : GameState(info)
    5450        , timeFactor_(1.0f)
    5551        , bPaused_(false)
     
    5854        this->ccSetTimeFactor_ = 0;
    5955        this->ccPause_ = 0;
     56
     57        // Tell LuaBind about all tolua interfaces
     58        LuaBind::getInstance().addToluaInterface(&tolua_Core_open, "Core");
     59        LuaBind::getInstance().addToluaInterface(&tolua_Orxonox_open, "Orxonox");
    6060    }
    6161
     
    8888        // create the global LevelManager
    8989        this->levelManager_ = new LevelManager();
    90 
    91         // Load level directly?
    92         bool loadLevel = false;
    93         if (CommandLine::getValue("standalone").getBool())
    94         {
    95             Game::getInstance().requestStates("graphics, standalone, level");
    96             loadLevel = true;
    97         }
    98         if (CommandLine::getValue("server").getBool())
    99         {
    100             Game::getInstance().requestStates("graphics, server, level");
    101             loadLevel = true;
    102         }
    103         if (CommandLine::getValue("client").getBool())
    104         {
    105             Game::getInstance().requestStates("graphics, client, level");
    106             loadLevel = true;
    107         }
    108         if (CommandLine::getValue("dedicated").getBool())
    109         {
    110             Game::getInstance().requestStates("dedicated, level");
    111             loadLevel = true;
    112         }
    113        
    114         // Determine where to start otherwise
    115         if (!loadLevel && !CommandLine::getValue("console").getBool())
    116         {
    117             // Also load graphics
    118             Game::getInstance().requestState("graphics");
    119         }
    12090    }
    12191
     
    148118        }
    149119
    150         uint64_t timeBeforeTick = time.getRealMicroseconds();
    151 
    152120        for (ObjectList<TimerBase>::iterator it = ObjectList<TimerBase>::begin(); it; ++it)
    153121            it->tick(time);
     
    164132            it->tick(leveldt * this->timeFactor_);
    165133        /*** HACK *** HACK ***/
    166 
    167         uint64_t timeAfterTick = time.getRealMicroseconds();
    168 
    169         // Also add our tick time
    170         Game::getInstance().addTickTime(timeAfterTick - timeBeforeTick);
    171134    }
    172135
     
    174137    @brief
    175138        Changes the speed of Orxonox
     139    @remark
     140        This function is a hack when placed here!
     141        Timefactor should be related to the scene (level or so), not the game
    176142    */
    177143    void GSRoot::setTimeFactor(float factor)
  • code/trunk/src/orxonox/gamestates/GSRoot.h

    r3280 r3370  
    3838    {
    3939    public:
    40         GSRoot(const GameStateConstrParams& params);
     40        GSRoot(const GameStateInfo& info);
    4141        ~GSRoot();
    4242
  • code/trunk/src/orxonox/gamestates/GSServer.cc

    r3280 r3370  
    4141    SetCommandLineArgument(port, 55556).shortcut("p").information("Network communication port to be used 0-65535 (default: 55556)");
    4242
    43     GSServer::GSServer(const GameStateConstrParams& params)
    44         : GameState(params)
     43    GSServer::GSServer(const GameStateInfo& info)
     44        : GameState(info)
    4545        , server_(0)
    4646    {
  • code/trunk/src/orxonox/gamestates/GSServer.h

    r3280 r3370  
    4040    {
    4141    public:
    42         GSServer(const GameStateConstrParams& params);
     42        GSServer(const GameStateInfo& info);
    4343        ~GSServer();
    4444
  • code/trunk/src/orxonox/gamestates/GSStandalone.cc

    r3280 r3370  
    3636    DeclareGameState(GSStandalone, "standalone", false, true);
    3737
    38     GSStandalone::GSStandalone(const GameStateConstrParams& params)
    39         : GameState(params)
     38    GSStandalone::GSStandalone(const GameStateInfo& info)
     39        : GameState(info)
    4040    {
    4141    }
  • code/trunk/src/orxonox/gamestates/GSStandalone.h

    r3280 r3370  
    3838    {
    3939    public:
    40         GSStandalone(const GameStateConstrParams& params);
     40        GSStandalone(const GameStateInfo& info);
    4141        ~GSStandalone();
    4242
  • code/trunk/src/orxonox/objects/pickup/BaseItem.h

    r3196 r3370  
    5151            Daniel 'Huty' Haggenmueller
    5252    */
    53     class _OrxonoxExport BaseItem
    54 // tolua_end
    55         : public BaseObject
    56 // tolua_begin
     53    class _OrxonoxExport BaseItem : public BaseObject
    5754    {
    5855// tolua_end
  • code/trunk/src/orxonox/objects/pickup/PickupInventory.cc

    r3327 r3370  
    3737
    3838#include "core/ConsoleCommand.h"
     39#include "core/GUIManager.h"
    3940#include "core/input/InputManager.h"
    40 #include "gui/GUIManager.h"
    4141#include "objects/controllers/HumanController.h"
    4242#include "objects/worldentities/pawns/Pawn.h"
  • code/trunk/src/orxonox/objects/pickup/PickupInventory.h

    r3196 r3370  
    4343namespace orxonox
    4444{
    45 // tolua_end
    4645    /**
    4746        @brief Static class for the inventory GUI window.
    4847        @author Daniel 'Huty' Haggenmueller
    4948    */
    50 // tolua_begin
    5149    class _OrxonoxExport PickupInventory
    5250    {
  • code/trunk/src/orxonox/objects/pickup/PickupSpawner.cc

    r3325 r3370  
    3737
    3838#include "core/CoreIncludes.h"
     39#include "core/GUIManager.h"     // HACK; see below
    3940#include "core/Template.h"
    4041#include "core/XMLPort.h"
    41 #include "gui/GUIManager.h"     // HACK; see below
    4242#include "objects/worldentities/pawns/Pawn.h"
    4343#include "PickupInventory.h"    // HACK; Only for hack, remove later
  • code/trunk/src/orxonox/objects/quest/QuestDescription.h

    r3196 r3370  
    5454        Damian 'Mozork' Frick
    5555    */
    56     class _OrxonoxExport QuestDescription
     56    class _OrxonoxExport QuestDescription : public BaseObject
     57    {
    5758// tolua_end
    58         : public BaseObject
    59     { // tolua_export
    6059        public:
    6160            QuestDescription(BaseObject* creator);
  • code/trunk/src/orxonox/objects/quest/QuestListener.cc

    r3280 r3370  
    8181    /**
    8282    @brief
    83         Makes all QuestListener in the list aware that a certain status change has occured and executes them if the status change affects them.
     83        Makes all QuestListener in the list aware that a certain status change has occurred and executes them if the status change affects them.
    8484    @param listeners
    8585        The list of QuestListeners that have to be made aware of the status change.
     
    182182        else
    183183        {
    184             COUT(1) << "An unforseen, never to happen, Error has occured. This is impossible!" << std::endl;
     184            COUT(1) << "An unforseen, never to happen, Error has occurred. This is impossible!" << std::endl;
    185185        return "";
    186186        }
  • code/trunk/src/orxonox/objects/quest/QuestManager.cc

    r3325 r3370  
    3636#include "util/Exception.h"
    3737#include "core/CoreIncludes.h"
    38 #include "gui/GUIManager.h"
    3938
    4039#include "objects/infos/PlayerInfo.h"
     
    4847{
    4948    //! Pointer to the current (and single) instance of this class.
    50     /*static*/ QuestManager* QuestManager::singletonRef_s = NULL;
     49    /*static*/ QuestManager* QuestManager::singletonPtr_s = NULL;
    5150
    5251    /**
     
    5958    {
    6059        RegisterRootObject(QuestManager);
    61 
    62         assert(singletonRef_s == 0);
    63         singletonRef_s = this;
    6460    }
    6561
     
    7167    {
    7268
    73     }
    74 
    75     /**
    76     @brief
    77         Returns a reference to the current (and single) instance of the QuestManager, and creates one if there isn't one to begin with.
    78     @return
    79         Returns a reference to the single instance of the Quest Manager.
    80     */
    81     /*static*/ QuestManager & QuestManager::getInstance()
    82     {
    83         assert(singletonRef_s);
    84         return *singletonRef_s;
    8569    }
    8670
     
    225209    QuestContainer* QuestManager::getQuestTree(std::string & name)
    226210    {
    227         GUIOverlay* gui = GUIManager::getInstance().getOverlay(name);
     211        GUIOverlay* gui = NULL;
     212        for (ObjectList<GUIOverlay>::iterator it = ObjectList<GUIOverlay>::begin(); it != ObjectList<GUIOverlay>::end(); ++it)
     213            if (it->getGUIName() == name)
     214                gui = *it;
    228215
    229216        PlayerInfo* player;
     
    321308        {
    322309            container->status = "";
    323             COUT(1) << "An error occured. A Quest of un-specified status wanted to be displayed." << std::endl;
     310            COUT(1) << "An error occurred. A Quest of un-specified status wanted to be displayed." << std::endl;
    324311        }
    325312       
  • code/trunk/src/orxonox/objects/quest/QuestManager.h

    r3196 r3370  
    4040#include <map>
    4141#include <string>
     42
     43#include "util/Singleton.h"
    4244#include "core/OrxonoxClass.h"
    4345
     
    7173        Damian 'Mozork' Frick
    7274    */
    73     class _OrxonoxExport QuestManager
    74 // tolua_end
    75         : public OrxonoxClass
    76 // tolua_begin
     75    class _OrxonoxExport QuestManager : public Singleton<QuestManager>, public orxonox::OrxonoxClass
    7776    {
    7877// tolua_end
     78            friend class Singleton<QuestManager>;
    7979        public:
    8080            QuestManager();
    8181            virtual ~QuestManager();
    8282
    83             static QuestManager& getInstance(); // tolua_export //!< Returns a reference to the single instance of the Quest Manager.
     83            //! Returns a reference to the single instance of the Quest Manager.
     84            static QuestManager& getInstance() { return Singleton<QuestManager>::getInstance(); } // tolua_export
    8485
    8586            bool registerQuest(Quest* quest); //!< Registers a Quest in the QuestManager.
     
    9293
    9394        private:
    94             static QuestManager* singletonRef_s;
     95            static QuestManager* singletonPtr_s;
    9596
    9697            std::map<std::string, Quest*> questMap_; //!< All Quests registered by their id's.
  • code/trunk/src/orxonox/overlays/GUIOverlay.cc

    r3327 r3370  
    3434#include "core/input/InputManager.h"
    3535#include "core/CoreIncludes.h"
     36#include "core/GUIManager.h"
    3637#include "core/XMLPort.h"
    37 #include "gui/GUIManager.h"
    3838
    3939namespace orxonox
     
    5555
    5656        XMLPortParam(GUIOverlay, "guiname", setGUIName, getGUIName, xmlElement, mode);
    57        
    58         GUIManager::getInstance().registerOverlay(this->guiName_, this);
    5957    }
    6058
  • code/trunk/src/orxonox/overlays/console/InGameConsole.cc

    r3327 r3370  
    6060    SetConsoleCommand(InGameConsole, closeConsole, true);
    6161
    62     InGameConsole* InGameConsole::singletonRef_s = 0;
     62    InGameConsole* InGameConsole::singletonPtr_s = 0;
    6363
    6464    /**
     
    7676        RegisterObject(InGameConsole);
    7777
    78         assert(singletonRef_s == 0);
    79         singletonRef_s = this;
    80 
    8178        this->bActive_ = false;
    8279        this->cursor_ = 0.0f;
     
    131128        if (this->consoleOverlay_)
    132129            Ogre::OverlayManager::getSingleton().destroy(consoleOverlay_);
    133 
    134         singletonRef_s = 0;
    135130    }
    136131
  • code/trunk/src/orxonox/overlays/console/InGameConsole.h

    r3327 r3370  
    3434
    3535#include <string>
     36
    3637#include "util/OgreForwardRefs.h"
     38#include "util/Singleton.h"
    3739#include "core/Shell.h"
    3840#include "core/WindowEventListener.h"
     
    4042namespace orxonox
    4143{
    42     class _OrxonoxExport InGameConsole : public ShellListener, public WindowEventListener
     44    class _OrxonoxExport InGameConsole : public Singleton<InGameConsole>, public ShellListener, public WindowEventListener
    4345    {
     46        friend class Singleton<InGameConsole>;
    4447    public: // functions
    4548        InGameConsole();
     
    5154
    5255        void update(const Clock& time);
    53 
    54         static InGameConsole& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
    55         static InGameConsole* getInstancePtr() { return singletonRef_s; }
    5656
    5757        static void openConsole();
     
    112112        bool bHidesAllInput_;
    113113
    114         static InGameConsole* singletonRef_s;
     114        static InGameConsole* singletonPtr_s;
    115115    };
    116116}
  • code/trunk/src/orxonox/overlays/notifications/NotificationManager.cc

    r3196 r3370  
    4646    const std::string NotificationManager::NONE = "none";
    4747
    48     NotificationManager* NotificationManager::singletonRef_s = NULL;
     48    NotificationManager* NotificationManager::singletonPtr_s = NULL;
    4949
    5050    /**
     
    5555    {
    5656        RegisterRootObject(NotificationManager);
    57 
    58         assert(singletonRef_s == 0);
    59         singletonRef_s = this;
    6057
    6158        this->highestIndex_ = 0;
     
    7067    }
    7168
    72     /**
    73     @brief
    74         Returns the current (and single) instance of the NotificationManager. Creates one, if there isn't one to begin with.
    75     @return
    76         Returns a reference to the single instance of the NotificationManager.
    77     */
    78     /*static*/ NotificationManager & NotificationManager::getInstance()
    79     {
    80         assert(singletonRef_s);
    81         return *singletonRef_s;
    82     }
    83    
    8469    /**
    8570    @brief
  • code/trunk/src/orxonox/overlays/notifications/NotificationManager.h

    r3196 r3370  
    4040#include <map>
    4141#include <string>
     42
     43#include "util/Singleton.h"
    4244#include "core/OrxonoxClass.h"
    4345
     
    5254        Damian 'Mozork' Frick
    5355    */
    54     class _OrxonoxExport NotificationManager : public OrxonoxClass
     56    class _OrxonoxExport NotificationManager : public Singleton<NotificationManager>, public OrxonoxClass
    5557    {
     58            friend class Singleton<NotificationManager>;
    5659        public:
    5760            NotificationManager();
     
    6063            static const std::string ALL;
    6164            static const std::string NONE;
    62 
    63             static NotificationManager & getInstance(); //! Returns a reference to the single instance of the NotificationManager.
    6465
    6566            bool registerNotification(Notification* notification); //!< Registers a Notification within the NotificationManager.
     
    8889
    8990        private:
    90             static NotificationManager* singletonRef_s;
     91            static NotificationManager* singletonPtr_s;
    9192
    9293            int highestIndex_; //!< This variable holds the highest index (resp. key) in notificationLists_s, to secure that  no key appears twice.
  • code/trunk/src/orxonox/sound/SoundBase.cc

    r3196 r3370  
    6565    void SoundBase::update() {
    6666        if(this->entity_ != NULL && alIsSource(this->source_)) {
    67             Vector3 pos = this->entity_->getPosition();
     67            const Vector3& pos = this->entity_->getPosition();
    6868            alSource3f(this->source_, AL_POSITION, pos.x, pos.y, pos.z);
    6969            ALenum error = alGetError();
     
    7171                COUT(2) << "Sound: OpenAL: Invalid sound position" << std::endl;
    7272
    73             Vector3 vel = this->entity_->getVelocity();
     73            const Vector3& vel = this->entity_->getVelocity();
    7474            alSource3f(this->source_, AL_VELOCITY, vel.x, vel.y, vel.z);
    7575            error = alGetError();
     
    7777                COUT(2) << "Sound: OpenAL: Invalid sound velocity" << std::endl;
    7878
    79             Quaternion orient = this->entity_->getOrientation();
     79            const Quaternion& orient = this->entity_->getOrientation();
    8080            Vector3 at = orient.zAxis();
    8181            alSource3f(this->source_, AL_DIRECTION, at.x, at.y, at.z);
     
    190190        if(ov_open(f, &vf, NULL, 0) < 0)
    191191        {
    192             COUT(2) << "Sound: libvorbisfile: File seems not to be an Ogg Vorbis bitstream" << std::endl;
     192            COUT(2) << "Sound: libvorbisfile: File does not seem to be an Ogg Vorbis bitstream" << std::endl;
    193193            ov_clear(&vf);
    194194            return AL_NONE;
  • code/trunk/src/orxonox/sound/SoundManager.cc

    r3280 r3370  
    3838namespace orxonox
    3939{
    40     SoundManager* SoundManager::singletonRef_s = NULL;
     40    SoundManager* SoundManager::singletonPtr_s = NULL;
    4141
    4242    /**
     
    4545    SoundManager::SoundManager()
    4646    {
    47         assert(singletonRef_s == NULL);
    48         singletonRef_s = this;
    49 
    5047        this->device_ = NULL;
    5148        this->soundavailable_ = true;
     
    9390    SoundManager::~SoundManager()
    9491    {
    95         assert(singletonRef_s != NULL);
    96         singletonRef_s = NULL;
    97 
    9892        alcDestroyContext(this->context_);
    9993        alcCloseDevice(this->device_);
     
    148142
    149143        // update listener orientation
    150         Quaternion orient = camera->getOrientation();
     144        const Quaternion& orient = camera->getOrientation();
    151145        Vector3 up = orient.xAxis(); // just a wild guess
    152146        Vector3 at = orient.zAxis();
  • code/trunk/src/orxonox/sound/SoundManager.h

    r3280 r3370  
    3232#include <cassert>
    3333#include <list>
     34#include "util/Singleton.h"
    3435#include "interfaces/Tickable.h"
    3536
     
    4243     *
    4344     */
    44     class _OrxonoxExport SoundManager : public Tickable
     45    class _OrxonoxExport SoundManager : public Singleton<SoundManager>, public Tickable
    4546    {
     47        friend class Singleton<SoundManager>;
    4648    public:
    4749        SoundManager();
     
    5254        bool isSoundAvailable();
    5355
    54         static SoundManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
    55 
    5656    private:
    5757        ALCdevice* device_;
     
    6060        bool soundavailable_;
    6161
    62         static SoundManager* singletonRef_s;
     62        static SoundManager* singletonPtr_s;
    6363    }; // class SoundManager
    6464} // namespace orxonox
  • code/trunk/src/orxonox/tools/ParticleInterface.cc

    r3301 r3370  
    4343#include "util/Math.h"
    4444#include "core/CoreIncludes.h"
     45#include "core/ConfigValueIncludes.h"
    4546#include "core/GameMode.h"
    46 #include "GraphicsManager.h"
    4747
    4848namespace orxonox
     
    9191    }
    9292
     93    void ParticleInterface::setConfigValues()
     94    {
     95        SetConfigValue(globalDetailLevel_, 2)
     96            .description("O: off, 1: low, 2: normal, 3: high").callback(this, &ParticleInterface::detailLevelChanged);
     97    }
     98
    9399    Ogre::ParticleEmitter* ParticleInterface::createNewEmitter()
    94100    {
     
    180186        this->detaillevel_ = level;
    181187        if (GameMode::showsGraphics())
    182             this->detailLevelChanged(GraphicsManager::getInstance().getDetailLevelParticle());
    183     }
    184 
    185     void ParticleInterface::detailLevelChanged(unsigned int newlevel)
    186     {
    187         if (newlevel >= static_cast<unsigned int>(this->detaillevel_))
     188            this->detailLevelChanged();
     189    }
     190
     191    void ParticleInterface::detailLevelChanged()
     192    {
     193        if (this->globalDetailLevel_ >= this->detaillevel_)
    188194            this->bAllowedByLOD_ = true;
    189195        else
  • code/trunk/src/orxonox/tools/ParticleInterface.h

    r3280 r3370  
    4747            ParticleInterface(Ogre::SceneManager* scenemanager, const std::string& templateName, LODParticle::Value detaillevel);
    4848            virtual ~ParticleInterface();
     49            void setConfigValues();
    4950
    5051            inline Ogre::ParticleSystem* getParticleSystem()
     
    7778                { return this->bVisible_; }
    7879
    79             void detailLevelChanged(unsigned int newlevel);
    8080            void setDetailLevel(unsigned int level);
    8181
     
    9090        private:
    9191            void updateVisibility();
     92            void detailLevelChanged();
    9293
    9394            Ogre::ParticleSystem*     particleSystem_;
     
    9697            bool                      bEnabled_;
    9798            bool                      bAllowedByLOD_;
    98             unsigned int              detaillevel_;     //!< Detail level of this particle effect (0: off, 1: low, 2: normal, 3: high)
     99            unsigned int              detaillevel_;       //!< Detail level of this particle effect (0: off, 1: low, 2: normal, 3: high)
    99100            float                     speedFactor_;
     101
     102            // config values
     103            unsigned int              globalDetailLevel_; //!< Global maximum detail level of particle effects (0: off, 1: low, 2: normal, 3: high)
    100104
    101105            static ParticleInterface* currentParticleInterface_s;
  • code/trunk/src/orxonox/tools/Shader.cc

    r3301 r3370  
    4141#include "core/CoreIncludes.h"
    4242#include "core/GameMode.h"
    43 #include "GraphicsManager.h"
     43#include "core/GraphicsManager.h"
    4444
    4545namespace orxonox
  • code/trunk/src/util/ScopeGuard.h

    r3280 r3370  
    124124        }
    125125
    126     protected:
    127126        ScopeGuardImpl0(F fun) : fun_(fun)
    128127        {}
    129128
     129    protected:
    130130        F fun_;
    131131    };
     
    171171        }
    172172
    173     protected:
    174173        ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1)
    175174        {}
    176175
     176    protected:
    177177        F fun_;
    178178        const P1 p1_;
     
    219219        }
    220220
    221     protected:
    222221        ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2)
    223222        {}
    224223
     224    protected:
    225225        F fun_;
    226226        const P1 p1_;
     
    268268        }
    269269
    270     protected:
    271270        ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3)
    272271        {}
    273272
     273    protected:
    274274        F fun_;
    275275        const P1 p1_;
     
    319319        }
    320320
    321     protected:
    322321        ScopeGuardImpl4( F fun, P1 p1, P2 p2, P3 p3, P4 p4 ) :
    323322             fun_( fun ), p1_( p1 ), p2_( p2 ), p3_( p3 ), p4_( p4 )
    324323        {}
    325324
     325    protected:
    326326        F fun_;
    327327        const P1 p1_;
     
    372372        }
    373373
    374     protected:
    375374        ScopeGuardImpl5( F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 ) :
    376375             fun_( fun ), p1_( p1 ), p2_( p2 ), p3_( p3 ), p4_( p4 ), p5_( p5 )
    377376        {}
    378377
     378    protected:
    379379        F fun_;
    380380        const P1 p1_;
     
    426426        }
    427427
    428     protected:
    429428        ObjScopeGuardImpl0(Obj& obj, MemFun memFun) : obj_(obj), memFun_(memFun)
    430429        {}
    431430
     431    protected:
    432432        Obj& obj_;
    433433        MemFun memFun_;
     
    488488        }
    489489
    490     protected:
    491490        ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) : obj_(obj), memFun_(memFun), p1_(p1)
    492491        {}
    493492       
     493    protected:
    494494        Obj& obj_;
    495495        MemFun memFun_;
     
    551551        }
    552552
    553     protected:
    554553        ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2)
    555554        {}
    556555
     556    protected:
    557557        Obj& obj_;
    558558        MemFun memFun_;
     
    616616        }
    617617
    618     protected:
    619618        ObjScopeGuardImpl3( Obj & obj, MemFun memFun, P1 p1, P2 p2, P3 p3 ) :
    620619             obj_( obj ), memFun_( memFun ), p1_( p1 ), p2_( p2 ), p3_( p3 )
    621620        {}
    622621
     622    protected:
    623623        Obj& obj_;
    624624        MemFun memFun_;
  • code/trunk/src/util/SignalHandler.cc

    r3301 r3370  
    4141namespace orxonox
    4242{
    43     SignalHandler* SignalHandler::singletonRef_s = NULL;
     43    SignalHandler* SignalHandler::singletonPtr_s = NULL;
    4444}
    4545
     
    122122      }
    123123      // if the signalhandler has already been destroyed then don't do anything
    124       if( SignalHandler::singletonRef_s == 0 )
     124      if( SignalHandler::singletonPtr_s == 0 )
    125125      {
    126126        COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "can't write backtrace because SignalHandler already destroyed" << std::endl;
  • code/trunk/src/util/SignalHandler.h

    r3068 r3370  
    4040#include <list>
    4141#include <string>
     42#include "Singleton.h"
    4243
    4344namespace orxonox
     
    6768    typedef std::list<SignalCallbackRec> SignalCallbackList;
    6869
    69     class SignalHandler
     70    class SignalHandler : public Singleton<SignalHandler>
    7071    {
     72        friend class Singleton<SignalHandler>;
    7173    public:
    72         SignalHandler()  { assert(SignalHandler::singletonRef_s == 0); SignalHandler::singletonRef_s = this; }
    73         ~SignalHandler() { assert(SignalHandler::singletonRef_s != 0); SignalHandler::singletonRef_s = NULL; }
    74         inline static SignalHandler& getInstance() { assert(SignalHandler::singletonRef_s); return *SignalHandler::singletonRef_s; }
     74        SignalHandler()  { }
     75        ~SignalHandler() { }
    7576
    7677        void registerCallback( SignalCallback cb, void * someData );
     
    8788        SignalCallbackList callbackList;
    8889
    89         static SignalHandler* singletonRef_s;
     90        static SignalHandler* singletonPtr_s;
    9091
    9192        std::string appName;
     
    9899namespace orxonox
    99100{
    100     class _UtilExport SignalHandler
     101    class _UtilExport SignalHandler : public Singleton<SignalHandler>
    101102    {
     103        friend class Singleton<SignalHandler>;
    102104    public:
    103         SignalHandler()  { assert(SignalHandler::singletonRef_s == 0); SignalHandler::singletonRef_s = this; }
    104         ~SignalHandler() { assert(SignalHandler::singletonRef_s != 0); SignalHandler::singletonRef_s = 0; }
    105         inline static SignalHandler& getInstance() { assert(SignalHandler::singletonRef_s); return *SignalHandler::singletonRef_s; }
     105        SignalHandler()  { }
     106        ~SignalHandler() { }
    106107        void doCatch( const std::string & appName, const std::string & filename ) {}
    107108        void dontCatch() {}
     
    109110
    110111    private:
    111         static SignalHandler* singletonRef_s;
     112        static SignalHandler* singletonPtr_s;
    112113    };
    113114}
Note: See TracChangeset for help on using the changeset viewer.