[Orxonox-commit 860] r3370 - in trunk: . cmake src src/core src/core/input src/cpptcl src/orxonox src/orxonox/gamestates src/orxonox/objects/pickup src/orxonox/objects/quest src/orxonox/overlays src/orxonox/overlays/console src/orxonox/overlays/notifications src/orxonox/sound src/orxonox/tools src/util
rgrieder at orxonox.net
rgrieder at orxonox.net
Thu Jul 30 14:10:45 CEST 2009
Author: rgrieder
Date: 2009-07-30 14:10:44 +0200 (Thu, 30 Jul 2009)
New Revision: 3370
Added:
trunk/src/core/GUIManager.cc
trunk/src/core/GUIManager.h
trunk/src/core/GraphicsManager.cc
trunk/src/core/GraphicsManager.h
trunk/src/util/Singleton.h
Removed:
trunk/src/orxonox/GraphicsManager.cc
trunk/src/orxonox/GraphicsManager.h
trunk/src/orxonox/gui/
Modified:
trunk/
trunk/cmake/Media.cmake
trunk/cmake/PackageConfig.cmake
trunk/cmake/PackageConfigMSVC.cmake
trunk/src/SpecialConfig.h.in
trunk/src/core/CMakeLists.txt
trunk/src/core/Clock.h
trunk/src/core/ConfigFileManager.cc
trunk/src/core/ConfigFileManager.h
trunk/src/core/ConsoleCommandCompilation.cc
trunk/src/core/Core.cc
trunk/src/core/Core.h
trunk/src/core/CorePrereqs.h
trunk/src/core/Game.cc
trunk/src/core/Game.h
trunk/src/core/GameMode.h
trunk/src/core/GameState.cc
trunk/src/core/GameState.h
trunk/src/core/IRC.cc
trunk/src/core/Identifier.h
trunk/src/core/Language.cc
trunk/src/core/Language.h
trunk/src/core/Loader.cc
trunk/src/core/Loader.h
trunk/src/core/LuaBind.cc
trunk/src/core/LuaBind.h
trunk/src/core/Shell.cc
trunk/src/core/Shell.h
trunk/src/core/TclBind.cc
trunk/src/core/TclBind.h
trunk/src/core/TclThreadManager.cc
trunk/src/core/TclThreadManager.h
trunk/src/core/input/InputManager.cc
trunk/src/core/input/InputManager.h
trunk/src/cpptcl/changes_orxonox.diff
trunk/src/cpptcl/cpptcl.cc
trunk/src/cpptcl/cpptcl.h
trunk/src/orxonox/CMakeLists.txt
trunk/src/orxonox/CameraManager.cc
trunk/src/orxonox/CameraManager.h
trunk/src/orxonox/LevelManager.cc
trunk/src/orxonox/LevelManager.h
trunk/src/orxonox/Main.cc
trunk/src/orxonox/OrxonoxPrecompiledHeaders.h
trunk/src/orxonox/OrxonoxPrereqs.h
trunk/src/orxonox/PawnManager.cc
trunk/src/orxonox/PawnManager.h
trunk/src/orxonox/PlayerManager.cc
trunk/src/orxonox/PlayerManager.h
trunk/src/orxonox/gamestates/GSClient.cc
trunk/src/orxonox/gamestates/GSClient.h
trunk/src/orxonox/gamestates/GSDedicated.cc
trunk/src/orxonox/gamestates/GSDedicated.h
trunk/src/orxonox/gamestates/GSGraphics.cc
trunk/src/orxonox/gamestates/GSGraphics.h
trunk/src/orxonox/gamestates/GSIOConsole.cc
trunk/src/orxonox/gamestates/GSIOConsole.h
trunk/src/orxonox/gamestates/GSLevel.cc
trunk/src/orxonox/gamestates/GSLevel.h
trunk/src/orxonox/gamestates/GSMainMenu.cc
trunk/src/orxonox/gamestates/GSMainMenu.h
trunk/src/orxonox/gamestates/GSRoot.cc
trunk/src/orxonox/gamestates/GSRoot.h
trunk/src/orxonox/gamestates/GSServer.cc
trunk/src/orxonox/gamestates/GSServer.h
trunk/src/orxonox/gamestates/GSStandalone.cc
trunk/src/orxonox/gamestates/GSStandalone.h
trunk/src/orxonox/objects/pickup/BaseItem.h
trunk/src/orxonox/objects/pickup/PickupInventory.cc
trunk/src/orxonox/objects/pickup/PickupInventory.h
trunk/src/orxonox/objects/pickup/PickupSpawner.cc
trunk/src/orxonox/objects/quest/QuestDescription.h
trunk/src/orxonox/objects/quest/QuestListener.cc
trunk/src/orxonox/objects/quest/QuestManager.cc
trunk/src/orxonox/objects/quest/QuestManager.h
trunk/src/orxonox/overlays/GUIOverlay.cc
trunk/src/orxonox/overlays/console/InGameConsole.cc
trunk/src/orxonox/overlays/console/InGameConsole.h
trunk/src/orxonox/overlays/notifications/NotificationManager.cc
trunk/src/orxonox/overlays/notifications/NotificationManager.h
trunk/src/orxonox/sound/SoundBase.cc
trunk/src/orxonox/sound/SoundManager.cc
trunk/src/orxonox/sound/SoundManager.h
trunk/src/orxonox/tools/ParticleInterface.cc
trunk/src/orxonox/tools/ParticleInterface.h
trunk/src/orxonox/tools/Shader.cc
trunk/src/util/ScopeGuard.h
trunk/src/util/SignalHandler.cc
trunk/src/util/SignalHandler.h
Log:
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!
Property changes on: trunk
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/buildsystem:1875-2277,2279-2401
/branches/buildsystem2:2507-2659
/branches/buildsystem3:2663-2709
/branches/ceguilua:1803-1809
/branches/core3:1573-1740
/branches/core4:3222-3225,3228,3235-3239,3243,3245-3251,3253-3255,3257,3260-3262,3265-3266,3269-3276,3278-3279,3281,3285-3286,3288,3290-3295,3306,3310-3311
/branches/gametypes:2827-3032
/branches/gcc43:1581
/branches/gui:1636-1724,2796-2895
/branches/input:1630-1637
/branches/lodfinal:2373-2412
/branches/map:2802-3087,3090
/branches/miniprojects:2755-2825
/branches/netp2:2836-2989
/branches/netp3:2989-3083
/branches/netp6:3215-3303
/branches/network:2357
/branches/network64:2211-2356
/branches/objecthierarchy:1912-2086,2101,2111-2170
/branches/objecthierarchy2:2172-2480
/branches/overlay:2118-2386
/branches/particles:2830-3086
/branches/pch:3114-3195
/branches/physics:1913-2056,2108-2440
/branches/physics_merge:2437-2458
/branches/pickups:1927-2087,2128,2828-2916
/branches/pickups2:2108-2498,2916-3072
/branches/presentation:2370-2653,2655-2661
/branches/questsystem:1895-2089
/branches/questsystem2:2108-2260
/branches/questsystem5:2777-2906
/branches/script_trigger:1296-1954,1956
/branches/sound:2830-3011
/branches/weapon:1926-2095
/branches/weapon2:2108-2489
/branches/weapons:2898-3052
/branches/weaponsystem:2743-2891
+ /branches/buildsystem:1875-2277,2279-2401
/branches/buildsystem2:2507-2659
/branches/buildsystem3:2663-2709
/branches/ceguilua:1803-1809
/branches/core3:1573-1740
/branches/core4:3222-3225,3228,3235-3239,3243,3245-3251,3253-3255,3257,3260-3262,3265-3266,3269-3276,3278-3279,3281,3285-3286,3288,3290-3295,3306,3310-3311
/branches/gametypes:2827-3032
/branches/gcc43:1581
/branches/gui:1636-1724,2796-2895
/branches/input:1630-1637
/branches/lodfinal:2373-2412
/branches/map:2802-3087,3090
/branches/miniprojects:2755-2825
/branches/netp2:2836-2989
/branches/netp3:2989-3083
/branches/netp6:3215-3303
/branches/network:2357
/branches/network64:2211-2356
/branches/objecthierarchy:1912-2086,2101,2111-2170
/branches/objecthierarchy2:2172-2480
/branches/overlay:2118-2386
/branches/particles:2830-3086
/branches/pch:3114-3195
/branches/physics:1913-2056,2108-2440
/branches/physics_merge:2437-2458
/branches/pickups:1927-2087,2128,2828-2916
/branches/pickups2:2108-2498,2916-3072
/branches/presentation:2370-2653,2655-2661
/branches/questsystem:1895-2089
/branches/questsystem2:2108-2260
/branches/questsystem5:2777-2906
/branches/resource:3328-3367
/branches/script_trigger:1296-1954,1956
/branches/sound:2830-3011
/branches/weapon:1926-2095
/branches/weapon2:2108-2489
/branches/weapons:2898-3052
/branches/weaponsystem:2743-2891
Modified: trunk/cmake/Media.cmake
===================================================================
--- trunk/cmake/Media.cmake 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/cmake/Media.cmake 2009-07-30 12:10:44 UTC (rev 3370)
@@ -44,15 +44,8 @@
################ Installation #################
-# Try no to copy both tcl script file libraries
-IF(TCL_LIBRARY MATCHES "85|8\\.5")
- SET(TCL_EXCLUDE_PATTERN "tcl8\\.4")
-ELSEIF(TCL_LIBRARY MATCHES "84|8\\.4")
- SET(TCL_EXCLUDE_PATTERN "tcl8\\.5")
-ENDIF()
-
INSTALL(
DIRECTORY ${CMAKE_MEDIA_OUTPUT_DIRECTORY}/
DESTINATION ${ORXONOX_MEDIA_INSTALL_PATH}
- REGEX "\\.svn$|_svn$|backToPNG|${TCL_EXCLUDE_PATTERN}" EXCLUDE
+ REGEX "\\.svn$|_svn$|backToPNG" EXCLUDE
)
Modified: trunk/cmake/PackageConfig.cmake
===================================================================
--- trunk/cmake/PackageConfig.cmake 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/cmake/PackageConfig.cmake 2009-07-30 12:10:44 UTC (rev 3370)
@@ -4,7 +4,7 @@
# Check package version info
# MAJOR: Interface breaking change somewhere (library version changed, etc.)
# MINOR: Bug fix or small conformant changes
-SET(DEPENDENCY_VERSION_REQUIRED 2)
+SET(DEPENDENCY_VERSION_REQUIRED 3)
IF(NOT EXISTS ${DEPENDENCY_PACKAGE_DIR}/version.txt)
SET(DEPENDENCY_VERSION 1.0)
ELSE()
@@ -30,21 +30,28 @@
MESSAGE(STATUS "Using library package for the dependencies.")
# Include paths and other special treatments
-SET(ENV{ALUTDIR} ${DEP_INCLUDE_DIR}/freealut-1.1.0)
-SET(ENV{BOOST_ROOT} ${DEP_INCLUDE_DIR}/boost-1.39.0)
-SET(ENV{CEGUIDIR} ${DEP_INCLUDE_DIR}/cegui-0.6.2)
-SET(ENV{DXSDK_DIR} ${DEP_INCLUDE_DIR}/directx-2007.aug)
-SET(ENV{ENETDIR} ${DEP_INCLUDE_DIR}/enet-1.2)
-SET(ENV{LUA_DIR} ${DEP_INCLUDE_DIR}/lua-5.1.4)
-SET(ENV{OGGDIR} ${DEP_INCLUDE_DIR}/libogg-1.1.3)
-SET(ENV{VORBISDIR} ${DEP_INCLUDE_DIR}/libvorbis-1.2.0)
-SET(ENV{OGRE_HOME} ${DEP_INCLUDE_DIR}/ogre-1.4.9)
+SET(ENV{ALUTDIR} ${DEP_INCLUDE_DIR}/freealut)
+SET(ENV{BOOST_ROOT} ${DEP_INCLUDE_DIR}/boost)
+SET(ENV{CEGUIDIR} ${DEP_INCLUDE_DIR}/cegui)
+SET(ENV{DXSDK_DIR} ${DEP_INCLUDE_DIR}/directx)
+SET(ENV{ENETDIR} ${DEP_INCLUDE_DIR}/enet)
+SET(ENV{LUA_DIR} ${DEP_INCLUDE_DIR}/lua)
+SET(ENV{OGGDIR} ${DEP_INCLUDE_DIR}/libogg)
+SET(ENV{VORBISDIR} ${DEP_INCLUDE_DIR}/libvorbis)
+SET(ENV{OGRE_HOME} ${DEP_INCLUDE_DIR}/ogre)
SET(ENV{OGRE_PLUGIN_DIR} ${DEP_BINARY_DIR})
-SET(ENV{OPENALDIR} ${DEP_INCLUDE_DIR}/openal-1.1)
-LIST(APPEND CMAKE_INCLUDE_PATH ${DEP_INCLUDE_DIR}/tcl-8.5.2/include)
-LIST(APPEND CMAKE_INCLUDE_PATH ${DEP_INCLUDE_DIR}/zlib-1.2.3/include)
+SET(ENV{OPENALDIR} ${DEP_INCLUDE_DIR}/openal)
+LIST(APPEND CMAKE_INCLUDE_PATH ${DEP_INCLUDE_DIR}/tcl/include)
+LIST(APPEND CMAKE_INCLUDE_PATH ${DEP_INCLUDE_DIR}/zlib/include)
### INSTALL ###
+
+# Tcl script library
+INSTALL(
+ DIRECTORY ${DEP_LIBRARY_DIR}/tcl/
+ DESTINATION lib/tcl
+)
+
# On Windows, DLLs have to be in the executable folder, install them
IF(WIN32 AND DEP_BINARY_DIR)
## DEBUG
Modified: trunk/cmake/PackageConfigMSVC.cmake
===================================================================
--- trunk/cmake/PackageConfigMSVC.cmake 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/cmake/PackageConfigMSVC.cmake 2009-07-30 12:10:44 UTC (rev 3370)
@@ -57,8 +57,8 @@
SET(ZLIB_LIBRARY ${DEP_LIBRARY_DIR}/zdll.lib CACHE FILEPATH "")
# Visual Leak Detector
- SET(VLD_INCLUDE_DIR ${DEP_INCLUDE_DIR}/vld-1.9h CACHE PATH "")
- SET(VLD_LIBRARY_DIR ${DEP_LIBRARY_DIR} CACHE PATH "")
+ SET(VLD_INCLUDE_DIR ${DEP_INCLUDE_DIR}/vld CACHE PATH "")
+ SET(VLD_LIBRARY_DIR ${DEP_LIBRARY_DIR} CACHE PATH "")
LINK_DIRECTORIES(${VLD_LIBRARY_DIR}) # Used for auto-linking
MARK_AS_ADVANCED(VLD_INCLUDE_DIR VLD_LIBRARY_DIR)
Modified: trunk/src/SpecialConfig.h.in
===================================================================
--- trunk/src/SpecialConfig.h.in 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/SpecialConfig.h.in 2009-07-30 12:10:44 UTC (rev 3370)
@@ -87,8 +87,11 @@
const char ORXONOX_CONFIG_DEV_PATH[] = "@CMAKE_CONFIG_OUTPUT_DIRECTORY@";
const char ORXONOX_LOG_DEV_PATH[] = "@CMAKE_LOG_OUTPUT_DIRECTORY@";
#endif
-
- /* OGRE Plugins */
+#ifdef DEPENDENCY_PACKAGE_ENABLE
+ const char ORXONOX_DEP_LIB_PATH[] = "@DEP_LIBRARY_DIR@";
+#endif
+
+ // OGRE PLUGINS
#ifdef NDEBUG
const char ORXONOX_OGRE_PLUGINS[] = "@OGRE_PLUGINS_RELEASE@";
# ifdef DEPENDENCY_PACKAGE_ENABLE
Modified: trunk/src/core/CMakeLists.txt
===================================================================
--- trunk/src/core/CMakeLists.txt 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/CMakeLists.txt 2009-07-30 12:10:44 UTC (rev 3370)
@@ -26,6 +26,8 @@
Game.cc
GameMode.cc
GameState.cc
+ GraphicsManager.cc
+ GUIManager.cc
Language.cc
LuaBind.cc
ObjectListBase.cc
@@ -79,12 +81,15 @@
CorePrecompiledHeaders.h
LINK_LIBRARIES
${OGRE_LIBRARY}
+ ${Boost_FILESYSTEM_LIBRARY}
+ ${Boost_SYSTEM_LIBRARY} # Filesystem dependency
${Boost_THREAD_LIBRARY}
- ${Boost_FILESYSTEM_LIBRARY}
- ${Boost_SYSTEM_LIBRARY}
- ${Boost_DATE_TIME_LIBRARY} # MSVC only
+ ${Boost_DATE_TIME_LIBRARY} # Thread dependency
+ ${CEGUI_LIBRARY}
+ ${CEGUILUA_LIBRARY}
${LUA_LIBRARIES}
cpptcl_orxonox
+ ogreceguirenderer_orxonox
ois_orxonox
tinyxml++_orxonox
tolua++_orxonox
Modified: trunk/src/core/Clock.h
===================================================================
--- trunk/src/core/Clock.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/Clock.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -26,14 +26,6 @@
*
*/
-/**
- @file
- @brief Declaration of the Core class.
-
- The Core class is a singleton, only used to configure some variables
- in the core through the config-file.
-*/
-
#ifndef _Clock_H__
#define _Clock_H__
Modified: trunk/src/core/ConfigFileManager.cc
===================================================================
--- trunk/src/core/ConfigFileManager.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/ConfigFileManager.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -41,7 +41,7 @@
{
const char* const DEFAULT_CONFIG_FILE = "default.ini";
- ConfigFileManager* ConfigFileManager::singletonRef_s = 0;
+ ConfigFileManager* ConfigFileManager::singletonPtr_s = 0;
SetConsoleCommandShortcutExtern(config).argumentCompleter(0, autocompletion::configvalueclasses()).argumentCompleter(1, autocompletion::configvalues()).argumentCompleter(2, autocompletion::configvalue());
SetConsoleCommandShortcutExtern(tconfig).argumentCompleter(0, autocompletion::configvalueclasses()).argumentCompleter(1, autocompletion::configvalues()).argumentCompleter(2, autocompletion::configvalue());
@@ -481,17 +481,12 @@
ConfigFileManager::ConfigFileManager()
: mininmalFreeType_(ConfigFileType::numberOfReservedTypes)
{
- assert(singletonRef_s == 0);
- singletonRef_s = this;
}
ConfigFileManager::~ConfigFileManager()
{
for(std::map<ConfigFileType, ConfigFile*>::const_iterator it = this->configFiles_.begin(); it != this->configFiles_.end(); )
delete (it++)->second;
-
- assert(singletonRef_s != 0);
- singletonRef_s = 0;
}
void ConfigFileManager::setFilename(ConfigFileType type, const std::string& filename)
Modified: trunk/src/core/ConfigFileManager.h
===================================================================
--- trunk/src/core/ConfigFileManager.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/ConfigFileManager.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -37,6 +37,7 @@
#include <map>
#include "util/OrxEnum.h"
+#include "util/Singleton.h"
namespace orxonox
{
@@ -266,8 +267,9 @@
///////////////////////
// ConfigFileManager //
///////////////////////
- class _CoreExport ConfigFileManager
+ class _CoreExport ConfigFileManager : public Singleton<ConfigFileManager>
{
+ friend class Singleton<ConfigFileManager>;
public:
ConfigFileManager();
~ConfigFileManager();
@@ -304,8 +306,6 @@
void updateConfigValues();
void updateConfigValues(ConfigFileType type);
- static ConfigFileManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
-
private:
ConfigFileManager(const ConfigFileManager&);
@@ -314,7 +314,7 @@
std::map<ConfigFileType, ConfigFile*> configFiles_;
unsigned int mininmalFreeType_;
- static ConfigFileManager* singletonRef_s;
+ static ConfigFileManager* singletonPtr_s;
};
}
Modified: trunk/src/core/ConsoleCommandCompilation.cc
===================================================================
--- trunk/src/core/ConsoleCommandCompilation.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/ConsoleCommandCompilation.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -93,11 +93,11 @@
{
if (newline)
{
- COUT(0) << text << std::endl;
+ COUT(0) << stripEnclosingBraces(text) << std::endl;
}
else
{
- COUT(0) << text;
+ COUT(0) << stripEnclosingBraces(text);
}
}
Modified: trunk/src/core/Core.cc
===================================================================
--- trunk/src/core/Core.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/Core.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -40,6 +40,7 @@
#include <cstdlib>
#include <cstdio>
#include <boost/filesystem.hpp>
+#include <OgreRenderWindow.h>
#ifdef ORXONOX_PLATFORM_WINDOWS
# ifndef WIN32_LEAN_AND_MEAN
@@ -67,17 +68,21 @@
#include "ConfigValueIncludes.h"
#include "CoreIncludes.h"
#include "Factory.h"
+#include "GameMode.h"
+#include "GraphicsManager.h"
+#include "GUIManager.h"
#include "Identifier.h"
#include "Language.h"
#include "LuaBind.h"
#include "Shell.h"
#include "TclBind.h"
#include "TclThreadManager.h"
+#include "input/InputManager.h"
namespace orxonox
{
//! Static pointer to the singleton
- Core* Core::singletonRef_s = 0;
+ Core* Core::singletonPtr_s = 0;
SetCommandLineArgument(mediaPath, "").information("Path to the media/data files");
SetCommandLineOnlyArgument(writingPathSuffix, "").information("Additional subfolder for config and log files");
@@ -133,16 +138,20 @@
.description("The maximal level of debug output shown in the ingame shell")
.callback(this, &CoreConfiguration::debugLevelChanged);
- SetConfigValue(language_, Language::getLanguage().defaultLanguage_)
+ SetConfigValue(language_, Language::getInstance().defaultLanguage_)
.description("The language of the ingame text")
.callback(this, &CoreConfiguration::languageChanged);
SetConfigValue(bInitializeRandomNumberGenerator_, true)
.description("If true, all random actions are different each time you start the game")
.callback(this, &CoreConfiguration::initializeRandomNumberGenerator);
- SetConfigValue(mediaPathString_, mediaPath_.string())
- .description("Relative path to the game data.")
- .callback(this, &CoreConfiguration::mediaPathChanged);
+ // Only show this config value for development builds
+ if (Core::isDevelopmentRun())
+ {
+ SetConfigValue(mediaPathString_, mediaPath_.string())
+ .description("Relative path to the game data.")
+ .callback(this, &CoreConfiguration::mediaPathChanged);
+ }
}
/**
@@ -169,7 +178,7 @@
void languageChanged()
{
// Read the translation file after the language was configured
- Language::getLanguage().readTranslatedLanguageFile();
+ Language::getInstance().readTranslatedLanguageFile();
}
/**
@@ -197,7 +206,16 @@
*/
void tsetMediaPath(const std::string& path)
{
- ModifyConfigValue(mediaPathString_, tset, path);
+ if (Core::isDevelopmentRun())
+ {
+ ModifyConfigValue(mediaPathString_, tset, path);
+ }
+ else
+ {
+ // Manual 'config' value without the file entry
+ mediaPathString_ = path;
+ this->mediaPathChanged();
+ }
}
void initializeRandomNumberGenerator()
@@ -229,17 +247,14 @@
Core::Core(const std::string& cmdLine)
+ // Cleanup guard for identifier destruction (incl. XMLPort, configValues, consoleCommands)
+ : identifierDestroyer_(Identifier::destroyAllIdentifiers)
+ // Cleanup guard for external console commands that don't belong to an Identifier
+ , consoleCommandDestroyer_(CommandExecutor::destroyExternalCommands)
+ , configuration_(new CoreConfiguration()) // Don't yet create config values!
+ , bDevRun_(false)
+ , bGraphicsLoaded_(false)
{
- if (singletonRef_s != 0)
- {
- COUT(0) << "Error: The Core singleton cannot be recreated! Shutting down." << std::endl;
- abort();
- }
- Core::singletonRef_s = this;
-
- // We need the variables very soon. But don't configure them yet!
- this->configuration_ = new CoreConfiguration();
-
// Parse command line arguments first
CommandLine::parseCommandLine(cmdLine);
@@ -255,7 +270,7 @@
// create a signal handler (only active for linux)
// This call is placed as soon as possible, but after the directories are set
- this->signalHandler_ = new SignalHandler();
+ this->signalHandler_.reset(new SignalHandler());
this->signalHandler_->doCatch(configuration_->executablePath_.string(), Core::getLogPathString() + "orxonox_crash.log");
// Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used
@@ -274,56 +289,76 @@
#endif
// Manage ini files and set the default settings file (usually orxonox.ini)
- this->configFileManager_ = new ConfigFileManager();
+ this->configFileManager_.reset(new ConfigFileManager());
this->configFileManager_->setFilename(ConfigFileType::Settings,
CommandLine::getValue("settingsFile").getString());
// Required as well for the config values
- this->languageInstance_ = new Language();
+ this->languageInstance_.reset(new Language());
// Do this soon after the ConfigFileManager has been created to open up the
// possibility to configure everything below here
this->configuration_->initialise();
// Create the lua interface
- this->luaBind_ = new LuaBind();
+ this->luaBind_.reset(new LuaBind());
// initialise Tcl
- this->tclBind_ = new TclBind(Core::getMediaPathString());
- this->tclThreadManager_ = new TclThreadManager(tclBind_->getTclInterpreter());
+ this->tclBind_.reset(new TclBind(Core::getMediaPathString()));
+ this->tclThreadManager_.reset(new TclThreadManager(tclBind_->getTclInterpreter()));
// create a shell
- this->shell_ = new Shell();
+ this->shell_.reset(new Shell());
// creates the class hierarchy for all classes with factories
Factory::createClassHierarchy();
}
/**
- @brief Sets the bool to true to avoid static functions accessing a deleted object.
+ @brief
+ All destruction code is handled by scoped_ptrs and SimpleScopeGuards.
*/
Core::~Core()
{
- delete this->shell_;
- delete this->tclThreadManager_;
- delete this->tclBind_;
- delete this->luaBind_;
- delete this->configuration_;
- delete this->languageInstance_;
- delete this->configFileManager_;
+ }
- // Destroy command line arguments
- CommandLine::destroyAllArguments();
- // Also delete external console command that don't belong to an Identifier
- CommandExecutor::destroyExternalCommands();
- // Clean up class hierarchy stuff (identifiers, XMLPort, configValues, consoleCommand)
- Identifier::destroyAllIdentifiers();
+ void Core::loadGraphics()
+ {
+ if (bGraphicsLoaded_)
+ return;
- delete this->signalHandler_;
+ // Load OGRE including the render window
+ scoped_ptr<GraphicsManager> graphicsManager(new GraphicsManager());
- // Don't assign singletonRef_s with NULL! Recreation is not supported
+ // The render window width and height are used to set up the mouse movement.
+ size_t windowHnd = 0;
+ graphicsManager->getRenderWindow()->getCustomAttribute("WINDOW", &windowHnd);
+
+ // Calls the InputManager which sets up the input devices.
+ scoped_ptr<InputManager> inputManager(new InputManager(windowHnd));
+
+ // load the CEGUI interface
+ guiManager_.reset(new GUIManager(graphicsManager->getRenderWindow()));
+
+ // Dismiss scoped pointers
+ graphicsManager_.swap(graphicsManager);
+ inputManager_.swap(inputManager);
+
+ bGraphicsLoaded_ = true;
}
+ void Core::unloadGraphics()
+ {
+ if (!bGraphicsLoaded_)
+ return;
+
+ this->guiManager_.reset();;
+ this->inputManager_.reset();;
+ this->graphicsManager_.reset();
+
+ bGraphicsLoaded_ = false;
+ }
+
/**
@brief Returns the softDebugLevel for the given device (returns a default-value if the class is right about to be created).
@param device The device
@@ -414,6 +449,15 @@
return getInstance().configuration_->logPath_.string() + '/';
}
+ /*static*/ const boost::filesystem::path& Core::getRootPath()
+ {
+ return getInstance().configuration_->rootPath_;
+ }
+ /*static*/ std::string Core::getRootPathString()
+ {
+ return getInstance().configuration_->rootPath_.string() + '/';
+ }
+
/**
@note
The code of this function has been copied and adjusted from OGRE, an open source graphics engine.
@@ -523,7 +567,7 @@
if (boost::filesystem::exists(configuration_->executablePath_ / "orxonox_dev_build.keep_me"))
{
COUT(1) << "Running from the build tree." << std::endl;
- Core::isDevBuild_ = true;
+ Core::bDevRun_ = true;
configuration_->mediaPath_ = ORXONOX_MEDIA_DEV_PATH;
configuration_->configPath_ = ORXONOX_CONFIG_DEV_PATH;
configuration_->logPath_ = ORXONOX_LOG_DEV_PATH;
@@ -602,8 +646,55 @@
}
}
- void Core::update(const Clock& time)
+ bool Core::preUpdate(const Clock& time) throw()
{
- this->tclThreadManager_->update(time);
+ std::string exceptionMessage;
+ try
+ {
+ if (this->bGraphicsLoaded_)
+ {
+ // process input events
+ this->inputManager_->update(time);
+ // process gui events
+ this->guiManager_->update(time);
+ }
+ // process thread commands
+ this->tclThreadManager_->update(time);
+ }
+ catch (const std::exception& ex)
+ { exceptionMessage = ex.what(); }
+ catch (...)
+ { exceptionMessage = "Unknown exception"; }
+ if (!exceptionMessage.empty())
+ {
+ COUT(0) << "An exception occurred in the Core preUpdate: " << exceptionMessage << std::endl;
+ COUT(0) << "This should really never happen! Closing the program." << std::endl;
+ return false;
+ }
+ return true;
}
+
+ bool Core::postUpdate(const Clock& time) throw()
+ {
+ std::string exceptionMessage;
+ try
+ {
+ if (this->bGraphicsLoaded_)
+ {
+ // Render (doesn't throw)
+ this->graphicsManager_->update(time);
+ }
+ }
+ catch (const std::exception& ex)
+ { exceptionMessage = ex.what(); }
+ catch (...)
+ { exceptionMessage = "Unknown exception"; }
+ if (!exceptionMessage.empty())
+ {
+ COUT(0) << "An exception occurred in the Core postUpdate: " << exceptionMessage << std::endl;
+ COUT(0) << "This should really never happen! Closing the program." << std::endl;
+ return false;
+ }
+ return true;
+ }
}
Modified: trunk/src/core/Core.h
===================================================================
--- trunk/src/core/Core.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/Core.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -42,11 +42,15 @@
#include "CorePrereqs.h"
#include <cassert>
+#include <boost/scoped_ptr.hpp>
#include "util/OutputHandler.h"
+#include "util/ScopeGuard.h"
+#include "util/Singleton.h"
namespace orxonox
{
class CoreConfiguration;
+ using boost::scoped_ptr;
/**
@brief
@@ -54,9 +58,14 @@
@details
The class provides information about the media, config and log path.
It determines those by the use of platform specific functions.
+ @remark
+ You should only create this singleton once because it destroys the identifiers!
*/
- class _CoreExport Core
+ class _CoreExport Core : public Singleton<Core>
{
+ typedef Loki::ScopeGuardImpl0<void (*)()> SimpleScopeGuard;
+ friend class Singleton<Core>;
+
public:
/**
@brief
@@ -70,9 +79,11 @@
void setConfigValues();
- void update(const Clock& time);
+ bool preUpdate(const Clock& time) throw();
+ bool postUpdate(const Clock& time) throw();
- static Core& getInstance() { assert(Core::singletonRef_s); return *Core::singletonRef_s; }
+ void loadGraphics();
+ void unloadGraphics();
static int getSoftDebugLevel(OutputHandler::OutputDevice device = OutputHandler::LD_All);
static void setSoftDebugLevel(OutputHandler::OutputDevice device, int level);
@@ -86,13 +97,19 @@
static const boost::filesystem::path& getConfigPath();
//! Returns the path to the log files as boost::filesystem::path
static const boost::filesystem::path& getLogPath();
+ //! Returns the path to the root folder as boost::filesystem::path
+ static const boost::filesystem::path& getRootPath();
//! Returns the path to the data files as std::string
static std::string getMediaPathString();
//! Returns the path to the config files as std::string
static std::string getConfigPathString();
//! Returns the path to the log files as std::string
static std::string getLogPathString();
+ //! Returns the path to the root folder as std::string
+ static std::string getRootPathString();
+ static bool isDevelopmentRun() { return getInstance().bDevRun_; }
+
private:
Core(const Core&); //!< Don't use (undefined symbol)
@@ -101,19 +118,26 @@
void createDirectories();
void setThreadAffinity(int limitToCPU);
- // Singletons
- ConfigFileManager* configFileManager_;
- Language* languageInstance_;
- LuaBind* luaBind_;
- Shell* shell_;
- SignalHandler* signalHandler_;
- TclBind* tclBind_;
- TclThreadManager* tclThreadManager_;
+ // Mind the order for the destruction!
+ scoped_ptr<SignalHandler> signalHandler_;
+ SimpleScopeGuard identifierDestroyer_;
+ SimpleScopeGuard consoleCommandDestroyer_;
+ scoped_ptr<ConfigFileManager> configFileManager_;
+ scoped_ptr<Language> languageInstance_;
+ scoped_ptr<CoreConfiguration> configuration_;
+ scoped_ptr<LuaBind> luaBind_;
+ scoped_ptr<TclBind> tclBind_;
+ scoped_ptr<TclThreadManager> tclThreadManager_;
+ scoped_ptr<Shell> shell_;
+ // graphical
+ scoped_ptr<GraphicsManager> graphicsManager_; //!< Interface to OGRE
+ scoped_ptr<InputManager> inputManager_; //!< Interface to OIS
+ scoped_ptr<GUIManager> guiManager_; //!< Interface to GUI
- bool isDevBuild_; //!< True for builds in the build directory (not installed)
- CoreConfiguration* configuration_;
+ bool bDevRun_; //!< True for runs in the build directory (not installed)
+ bool bGraphicsLoaded_;
- static Core* singletonRef_s;
+ static Core* singletonPtr_s;
};
}
Modified: trunk/src/core/CorePrereqs.h
===================================================================
--- trunk/src/core/CorePrereqs.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/CorePrereqs.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -122,6 +122,8 @@
template <class T>
class FunctorMember;
class FunctorStatic;
+ class GraphicsManager;
+ class GUIManager;
class Identifier;
class IRC;
template <class T>
@@ -143,6 +145,7 @@
class ObjectListElement;
template <class T>
class ObjectListIterator;
+ class OgreWindowEventListener;
class OrxonoxClass;
class Shell;
class ShellListener;
@@ -166,8 +169,8 @@
// game states
class Game;
- struct GameStateConstrParams;
class GameState;
+ struct GameStateInfo;
struct GameStateTreeNode;
// input
@@ -219,6 +222,21 @@
class condition_variable;
}
+// CEGUI
+namespace CEGUI
+{
+ class DefaultLogger;
+ class Logger;
+ class LuaScriptModule;
+
+ class OgreCEGUIRenderer;
+ class OgreCEGUIResourceProvider;
+ class OgreCEGUITexture;
+}
+
+// Lua
+struct lua_State;
+
// TinyXML and TinyXML++
class TiXmlString;
class TiXmlOutStream;
Copied: trunk/src/core/GUIManager.cc (from rev 3367, branches/resource/src/core/GUIManager.cc)
===================================================================
--- trunk/src/core/GUIManager.cc (rev 0)
+++ trunk/src/core/GUIManager.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -0,0 +1,347 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Reto Grieder
+ * Benjamin Knecht
+ * Co-authors:
+ * ...
+ *
+ */
+
+/**
+ at file
+ at brief
+ Implementation of the GUIManager class.
+*/
+
+#include "GUIManager.h"
+
+#include <memory>
+extern "C" {
+#include <lua.h>
+}
+#include <CEGUIDefaultLogger.h>
+#include <CEGUIExceptions.h>
+#include <CEGUIInputEvent.h>
+#include <CEGUIResourceProvider.h>
+#include <CEGUISystem.h>
+#include <ogreceguirenderer/OgreCEGUIRenderer.h>
+
+#include "SpecialConfig.h" // Configures the macro below
+#ifdef CEGUILUA_USE_INTERNAL_LIBRARY
+# include <ceguilua/CEGUILua.h>
+#else
+# include <CEGUILua.h>
+#endif
+
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/OrxAssert.h"
+#include "Core.h"
+#include "Clock.h"
+#include "LuaBind.h"
+
+namespace orxonox
+{
+ class CEGUILogger : public CEGUI::DefaultLogger
+ {
+ public:
+ void logEvent(const CEGUI::String& message, CEGUI::LoggingLevel level = CEGUI::Standard)
+ {
+ int orxonoxLevel = CEGUI::Standard;
+ switch (level)
+ {
+ case CEGUI::Errors: orxonoxLevel = 1; break;
+ case CEGUI::Warnings: orxonoxLevel = 2; break;
+ case CEGUI::Standard: orxonoxLevel = 4; break;
+ case CEGUI::Informative: orxonoxLevel = 5; break;
+ case CEGUI::Insane: orxonoxLevel = 6; break;
+ default: OrxAssert(false, "CEGUI log level out of range, inpect immediately!");
+ }
+ OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
+ << "CEGUI: " << message << std::endl;
+
+ CEGUI::DefaultLogger::logEvent(message, level);
+ }
+ };
+
+ static CEGUI::MouseButton convertButton(MouseButtonCode::ByEnum button);
+
+ GUIManager* GUIManager::singletonPtr_s = 0;
+
+ /**
+ @brief
+ Constructs the GUIManager by starting up CEGUI
+
+ Creates the interface to Ogre, sets up the CEGUI renderer and the Lua script module together with the Lua engine.
+ The log is set up and connected to the CEGUILogger.
+ After Lua setup tolua++-elements are linked to Lua-state to give Lua access to C++-code.
+ Finally initial Lua code is executed (maybe we can do this with the CEGUI startup script automatically).
+ @param renderWindow
+ Ogre's render window. Without this, the GUI cannot be displayed.
+ @return true if success, otherwise false
+ */
+ GUIManager::GUIManager(Ogre::RenderWindow* renderWindow)
+ : renderWindow_(renderWindow)
+ , resourceProvider_(0)
+ {
+ using namespace CEGUI;
+
+ COUT(3) << "Initialising CEGUI." << std::endl;
+
+ try
+ {
+ // Note: No SceneManager specified yet
+ guiRenderer_.reset(new OgreCEGUIRenderer(renderWindow_, Ogre::RENDER_QUEUE_OVERLAY, false, 3000));
+ resourceProvider_ = guiRenderer_->createResourceProvider();
+ resourceProvider_->setDefaultResourceGroup("GUI");
+
+ // setup scripting
+ scriptModule_.reset(new LuaScriptModule());
+ luaState_ = scriptModule_->getLuaState();
+
+ // Create our own logger to specify the filepath
+ std::auto_ptr<CEGUILogger> ceguiLogger(new CEGUILogger());
+ ceguiLogger->setLogFilename(Core::getLogPathString() + "cegui.log");
+ // set the log level according to ours (translate by subtracting 1)
+ ceguiLogger->setLoggingLevel(
+ static_cast<LoggingLevel>(Core::getSoftDebugLevel(OutputHandler::LD_Logfile) - 1));
+ this->ceguiLogger_ = ceguiLogger.release();
+
+ // create the CEGUI system singleton
+ guiSystem_.reset(new System(guiRenderer_.get(), resourceProvider_, 0, scriptModule_.get()));
+
+ // do this after 'new CEGUI::Sytem' because that creates the lua state in the first place
+ LuaBind::getInstance().openToluaInterfaces(this->luaState_);
+
+ // initialise the basic lua code
+ this->loadLuaCode();
+ }
+ catch (CEGUI::Exception& ex)
+ {
+#if CEGUI_VERSION_MAJOR == 0 && CEGUI_VERSION_MINOR < 6
+ throw GeneralException(ex.getMessage().c_str());
+#else
+ throw GeneralException(ex.getMessage().c_str(), ex.getLine(),
+ ex.getFileName().c_str(), ex.getName().c_str());
+#endif
+ }
+ }
+
+ /**
+ @brief
+ Destructor of the GUIManager
+
+ Basically shuts down CEGUI (member smart pointers) but first unloads our Tolua modules.
+ */
+ GUIManager::~GUIManager()
+ {
+ // destroy our own tolua interfaces
+ LuaBind::getInstance().closeToluaInterfaces(this->luaState_);
+ }
+
+ /**
+ @brief
+ Calls main Lua script
+ @todo
+ This function calls the main Lua script for our GUI.
+
+ Additionally we set the datapath variable in Lua. This is needed so Lua can access the data used for the GUI.
+ */
+ void GUIManager::loadLuaCode()
+ {
+ // set datapath for GUI data
+ lua_pushfstring(this->scriptModule_->getLuaState(), Core::getMediaPathString().c_str());
+ lua_setglobal(this->scriptModule_->getLuaState(), "datapath");
+ // call main Lua script
+ this->scriptModule_->executeScriptFile("loadGUI_3.lua", "GUI");
+ }
+
+ /**
+ @brief
+ used to tick the GUI
+ @param time
+ clock which provides time value for the GUI System
+
+ Ticking the GUI means updating it with a certain regularity.
+ The elapsed time since the last call is given in the time value provided by the clock.
+ This time value is then used to provide a fluent animation of the GUI.
+ */
+ void GUIManager::update(const Clock& time)
+ {
+ assert(guiSystem_);
+ guiSystem_->injectTimePulse(time.getDeltaTime());
+ }
+
+ /**
+ @brief
+ Tells the GUIManager which SceneManager to use
+ @param camera
+ The current camera on which the GUI should be displayed on.
+
+ In fact the GUIManager needs the SceneManager and not the Camera to display the GUI.
+ This means the GUI is not bound to a camera but rather to the SceneManager.
+ Hiding the GUI when needed can therefore not be resolved by just NOT setting the current camera.
+ */
+ void GUIManager::setCamera(Ogre::Camera* camera)
+ {
+ if (camera == NULL)
+ this->guiRenderer_->setTargetSceneManager(0);
+ else
+ this->guiRenderer_->setTargetSceneManager(camera->getSceneManager());
+ }
+
+ /**
+ @brief
+ Executes Lua code
+ @param str
+ reference to string object holding the Lua code which is to be executed
+
+ This function gives total access to the GUI. You can execute ANY Lua code here.
+ */
+ void GUIManager::executeCode(const std::string& str)
+ {
+ try
+ {
+ this->scriptModule_->executeString(str);
+ }
+ catch (const CEGUI::Exception& ex)
+ {
+ COUT(2) << "CEGUI Error: \"" << ex.getMessage() << "\" while executing code \"" << str << "\"" << std::endl;
+ }
+ catch (...)
+ {
+ COUT(2) << "Couldn't execute GUI related Lua code due to unknown reasons." << std::endl;
+ }
+ }
+
+ /**
+ @brief
+ Displays specified GUI on screen
+ @param name
+ The name of the GUI
+
+ The function executes the Lua function with the same name in case the GUIManager is ready.
+ For more details check out loadGUI_2.lua where the function presides.
+ */
+ void GUIManager::showGUI(const std::string& name)
+ {
+ this->executeCode(std::string("showGUI(\"") + name + "\")");
+ }
+
+ void GUIManager::keyPressed(const KeyEvent& evt)
+ {
+ guiSystem_->injectKeyDown(evt.getKeyCode());
+ guiSystem_->injectChar(evt.getText());
+ }
+ void GUIManager::keyReleased(const KeyEvent& evt)
+ {
+ guiSystem_->injectKeyUp(evt.getKeyCode());
+ }
+
+ /**
+ @brief
+ Function receiving a mouse button pressed event.
+ @param id
+ ID of the mouse button which got pressed
+
+ This function is inherited by MouseHandler and injects the event into CEGUI.
+ It is for CEGUI to process the event.
+ */
+ void GUIManager::buttonPressed(MouseButtonCode::ByEnum id)
+ {
+ try
+ {
+ guiSystem_->injectMouseButtonDown(convertButton(id));
+ }
+ catch (CEGUI::ScriptException& ex)
+ {
+ // We simply ignore the exception and proceed
+ COUT(1) << ex.getMessage() << std::endl;
+ }
+ }
+
+ /**
+ @brief
+ Function receiving a mouse button released event.
+ @param id
+ ID of the mouse button which got released
+
+ This function is inherited by MouseHandler and injects the event into CEGUI.
+ It is for CEGUI to process the event.
+ */
+ void GUIManager::buttonReleased(MouseButtonCode::ByEnum id)
+ {
+ try
+ {
+ guiSystem_->injectMouseButtonUp(convertButton(id));
+ }
+ catch (CEGUI::ScriptException& ex)
+ {
+ // We simply ignore the exception and proceed
+ COUT(1) << ex.getMessage() << std::endl;
+ }
+ }
+
+ void GUIManager::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
+ {
+ guiSystem_->injectMouseMove(static_cast<float>(rel.x), static_cast<float>(rel.y));
+ }
+ void GUIManager::mouseScrolled(int abs, int rel)
+ {
+ guiSystem_->injectMouseWheelChange(static_cast<float>(rel));
+ }
+
+ /**
+ @brief
+ converts mouse event code to CEGUI event code
+ @param button
+ code of the mouse button as we use it in Orxonox
+ @return
+ code of the mouse button as it is used by CEGUI
+
+ Simple convertion from mouse event code in Orxonox to the one used in CEGUI.
+ */
+ static inline CEGUI::MouseButton convertButton(MouseButtonCode::ByEnum button)
+ {
+ switch (button)
+ {
+ case MouseButtonCode::Left:
+ return CEGUI::LeftButton;
+
+ case MouseButtonCode::Right:
+ return CEGUI::RightButton;
+
+ case MouseButtonCode::Middle:
+ return CEGUI::MiddleButton;
+
+ case MouseButtonCode::Button3:
+ return CEGUI::X1Button;
+
+ case MouseButtonCode::Button4:
+ return CEGUI::X2Button;
+
+ default:
+ return CEGUI::NoButton;
+ }
+ }
+}
Copied: trunk/src/core/GUIManager.h (from rev 3367, branches/resource/src/core/GUIManager.h)
===================================================================
--- trunk/src/core/GUIManager.h (rev 0)
+++ trunk/src/core/GUIManager.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -0,0 +1,107 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Reto Grieder
+ * Benjamin Knecht
+ * Co-authors:
+ * ...
+ *
+ */
+
+/**
+ at file
+ at brief
+ Declaration of the GUIManager class.
+*/
+
+#ifndef _GUIManager_H__
+#define _GUIManager_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include <string>
+#include <CEGUIForwardRefs.h>
+#include <boost/scoped_ptr.hpp>
+
+#include "util/OgreForwardRefs.h"
+#include "util/Singleton.h"
+#include "input/InputHandler.h"
+
+namespace orxonox
+{
+ /**
+ @class GUIManager
+ @brief
+ Provides a simple interface to CEGUI with tolua methods and console commands. It also acts as a key and mouse handler.
+
+ The GUIManager is a singleton and can be called anywhere when access on the GUI is needed.
+ Creation of the GUIManager is therefore not possible and the cunstructor is private.
+
+ Since the GUI needs user input, the GUIManager implements the functions needed to act as a key and/or mouse handler.
+ Those input events are then injected into CEGUI in Lua.
+ */
+ class _CoreExport GUIManager : public Singleton<GUIManager>, public InputHandler
+ {
+ friend class Singleton<GUIManager>;
+ public:
+ GUIManager(Ogre::RenderWindow* renderWindow);
+ ~GUIManager();
+
+ void update(const Clock& time);
+
+ void showGUI(const std::string& name);
+ void executeCode(const std::string& str);
+
+ void setCamera(Ogre::Camera* camera);
+
+ static GUIManager* getInstancePtr() { return singletonPtr_s; }
+
+ private:
+ GUIManager(const GUIManager& instance); //!< private and undefined copy c'tor (this is a singleton class)
+
+ void loadLuaCode();
+
+ // keyHandler functions
+ void keyPressed (const KeyEvent& evt);
+ void keyReleased(const KeyEvent& evt);
+
+ // mouseHandler functions
+ void buttonPressed (MouseButtonCode::ByEnum id);
+ void buttonReleased(MouseButtonCode::ByEnum id);
+ void mouseMoved (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
+ void mouseScrolled (int abs, int rel);
+
+ boost::scoped_ptr<CEGUI::OgreCEGUIRenderer> guiRenderer_; //!< CEGUI's interface to the Ogre Engine
+ boost::scoped_ptr<CEGUI::LuaScriptModule> scriptModule_; //!< CEGUI's script module to use Lua
+ boost::scoped_ptr<CEGUI::System> guiSystem_; //!< CEGUI's main system
+ Ogre::RenderWindow* renderWindow_; //!< Ogre's render window to give CEGUI access to it
+ CEGUI::ResourceProvider* resourceProvider_; //!< CEGUI's resource provider
+ CEGUI::Logger* ceguiLogger_; //!< CEGUI's logger to be able to log CEGUI errors in our log
+ lua_State* luaState_; //!< Lua state, access point to the Lua engine
+
+ static GUIManager* singletonPtr_s; //!< Singleton reference to GUIManager
+
+ };
+}
+
+#endif /* _GUIManager_H__ */
Modified: trunk/src/core/Game.cc
===================================================================
--- trunk/src/core/Game.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/Game.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -39,6 +39,7 @@
#include "util/Debug.h"
#include "util/Exception.h"
+#include "util/ScopeGuard.h"
#include "util/Sleep.h"
#include "util/SubString.h"
#include "Clock.h"
@@ -47,6 +48,7 @@
#include "Core.h"
#include "CoreIncludes.h"
#include "ConfigValueIncludes.h"
+#include "GameMode.h"
#include "GameState.h"
namespace orxonox
@@ -58,8 +60,8 @@
{ Game::getInstance().stop(); }
SetConsoleCommandShortcutExternAlias(stop_game, "exit");
- std::map<std::string, Game::GameStateInfo> Game::gameStateDeclarations_s;
- Game* Game::singletonRef_s = 0;
+ std::map<std::string, GameStateInfo> Game::gameStateDeclarations_s;
+ Game* Game::singletonPtr_s = 0;
/**
@@ -68,7 +70,7 @@
*/
struct GameStateTreeNode
{
- GameState* state_;
+ std::string name_;
weak_ptr<GameStateTreeNode> parent_;
std::vector<shared_ptr<GameStateTreeNode> > children_;
};
@@ -111,74 +113,48 @@
*/
Game::Game(const std::string& cmdLine)
{
- if (singletonRef_s != 0)
- {
- COUT(0) << "Error: The Game singleton cannot be recreated! Shutting down." << std::endl;
- abort();
- }
- singletonRef_s = this;
-
this->bAbort_ = false;
bChangingState_ = false;
+#ifdef ORXONOX_PLATFORM_WINDOWS
+ minimumSleepTime_ = 1000/*us*/;
+#else
+ minimumSleepTime_ = 0/*us*/;
+#endif
+
// Create an empty root state
- declareGameState<GameState>("GameState", "emptyRootGameState", true, false);
+ this->declareGameState<GameState>("GameState", "emptyRootGameState", true, false);
- // reset statistics
- this->statisticsStartTime_ = 0;
- this->statisticsTickTimes_.clear();
- this->periodTickTime_ = 0;
- this->periodTime_ = 0;
- this->avgFPS_ = 0.0f;
- this->avgTickTime_ = 0.0f;
-
// Set up a basic clock to keep time
- this->gameClock_ = new Clock();
+ this->gameClock_.reset(new Clock());
// Create the Core
- this->core_ = new Core(cmdLine);
+ this->core_.reset(new Core(cmdLine));
- // After the core has been created, we can safely instantiate the GameStates
+ // After the core has been created, we can safely instantiate the GameStates that don't require graphics
for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin();
it != gameStateDeclarations_s.end(); ++it)
{
- // Only create the states appropriate for the game mode
- //if (GameMode::showsGraphics || !it->second.bGraphicsMode)
- GameStateConstrParams params = { it->second.stateName, it->second.bIgnoreTickTime };
- gameStates_[getLowercase(it->second.stateName)] = GameStateFactory::fabricate(it->second.className, params);
+ if (!it->second.bGraphicsMode)
+ constructedStates_[it->second.stateName] = GameStateFactory::fabricate(it->second);
}
// The empty root state is ALWAYS loaded!
this->rootStateNode_ = shared_ptr<GameStateTreeNode>(new GameStateTreeNode());
- this->rootStateNode_->state_ = getState("emptyRootGameState");
- this->activeStateNode_ = this->rootStateNode_;
- this->activeStates_.push_back(this->rootStateNode_->state_);
+ this->rootStateNode_->name_ = "emptyRootGameState";
+ this->loadedTopStateNode_ = this->rootStateNode_;
+ this->loadedStates_.push_back(this->getState(rootStateNode_->name_));
// Do this after the Core creation!
- this->configuration_ = new GameConfiguration();
+ this->configuration_.reset(new GameConfiguration());
}
/**
@brief
+ All destruction code is handled by scoped_ptrs and SimpleScopeGuards.
*/
Game::~Game()
{
- // Destroy the configuration helper class instance
- delete this->configuration_;
-
- // Destroy the GameStates (note that the nodes still point to them, but doesn't matter)
- for (std::map<std::string, GameState*>::const_iterator it = gameStates_.begin();
- it != gameStates_.end(); ++it)
- delete it->second;
-
- // Destroy the Core and with it almost everything
- delete this->core_;
- delete this->gameClock_;
-
- // Take care of the GameStateFactories
- GameStateFactory::destroyFactories();
-
- // Don't assign singletonRef_s with NULL! Recreation is not supported
}
/**
@@ -194,148 +170,179 @@
if (this->requestedStateNodes_.empty())
COUT(0) << "Warning: Starting game without requesting GameState. This automatically terminates the program." << std::endl;
+ // reset statistics
+ this->statisticsStartTime_ = 0;
+ this->statisticsTickTimes_.clear();
+ this->periodTickTime_ = 0;
+ this->periodTime_ = 0;
+ this->avgFPS_ = 0.0f;
+ this->avgTickTime_ = 0.0f;
+ this->excessSleepTime_ = 0;
+
// START GAME
// first delta time should be about 0 seconds
this->gameClock_->capture();
// A first item is required for the fps limiter
StatisticsTickInfo tickInfo = {0, 0};
statisticsTickTimes_.push_back(tickInfo);
- while (!this->bAbort_ && (!this->activeStates_.empty() || this->requestedStateNodes_.size() > 0))
+ while (!this->bAbort_ && (!this->loadedStates_.empty() || this->requestedStateNodes_.size() > 0))
{
- uint64_t currentTime = this->gameClock_->getRealMicroseconds();
-
- uint64_t nextTickTime = statisticsTickTimes_.back().tickTime + static_cast<uint64_t>(1000000.0f / configuration_->fpsLimit_);
- if (currentTime < nextTickTime)
- {
- usleep(nextTickTime - currentTime);
- continue;
- }
+ // Generate the dt
this->gameClock_->capture();
- // STATISTICS
- StatisticsTickInfo tickInfo = {currentTime, 0};
+ // Statistics init
+ StatisticsTickInfo tickInfo = {gameClock_->getMicroseconds(), 0};
statisticsTickTimes_.push_back(tickInfo);
this->periodTime_ += this->gameClock_->getDeltaTimeMicroseconds();
- // UPDATE STATE STACK
- while (this->requestedStateNodes_.size() > 0)
+ // Update the GameState stack if required
+ this->updateGameStateStack();
+
+ // Core preUpdate (doesn't throw)
+ if (!this->core_->preUpdate(*this->gameClock_))
{
- shared_ptr<GameStateTreeNode> requestedStateNode = this->requestedStateNodes_.front();
- assert(this->activeStateNode_);
- if (!this->activeStateNode_->parent_.expired() && requestedStateNode == this->activeStateNode_->parent_.lock())
- this->unloadState(this->activeStateNode_->state_);
- else // has to be child
- {
- try
- {
- this->loadState(requestedStateNode->state_);
- }
- catch (const std::exception& ex)
- {
- COUT(1) << "Error: Loading GameState '" << requestedStateNode->state_->getName() << "' failed: " << ex.what() << std::endl;
- // All scheduled operations have now been rendered inert --> flush them and issue a warning
- if (this->requestedStateNodes_.size() > 1)
- COUT(1) << "All " << this->requestedStateNodes_.size() - 1 << " scheduled transitions have been ignored." << std::endl;
- this->requestedStateNodes_.clear();
- break;
- }
- }
- this->activeStateNode_ = requestedStateNode;
- this->requestedStateNodes_.erase(this->requestedStateNodes_.begin());
+ this->stop();
+ break;
}
- // UPDATE, Core first
- bool threwException = false;
- try
+ // Update the GameStates bottom up in the stack
+ this->updateGameStates();
+
+ // Core postUpdate (doesn't throw)
+ if (!this->core_->postUpdate(*this->gameClock_))
{
- this->core_->update(*this->gameClock_);
- }
- catch (const std::exception& ex)
- {
- threwException = true;
- COUT(0) << "Exception while ticking the Core: " << ex.what() << std::endl;
- }
- catch (...)
- {
- threwException = true;
- }
- if (threwException)
- {
- COUT(0) << "An exception occured while ticking the Core. This should really never happen!" << std::endl;
- COUT(0) << "Closing the program." << std::endl;
this->stop();
break;
}
- // UPDATE, GameStates bottom to top in the stack
- // Note: The first element is the empty root state, which doesn't need ticking
- for (std::vector<GameState*>::const_iterator it = this->activeStates_.begin() + 1;
- it != this->activeStates_.end(); ++it)
+ // Evaluate statistics
+ this->updateStatistics();
+
+ // Limit framerate
+ this->updateFPSLimiter();
+ }
+
+ // UNLOAD all remaining states
+ while (this->loadedStates_.size() > 1)
+ this->unloadState(this->loadedStates_.back()->getName());
+ this->loadedTopStateNode_ = this->rootStateNode_;
+ this->requestedStateNodes_.clear();
+ }
+
+ void Game::updateGameStateStack()
+ {
+ while (this->requestedStateNodes_.size() > 0)
+ {
+ shared_ptr<GameStateTreeNode> requestedStateNode = this->requestedStateNodes_.front();
+ assert(this->loadedTopStateNode_);
+ if (!this->loadedTopStateNode_->parent_.expired() && requestedStateNode == this->loadedTopStateNode_->parent_.lock())
+ this->unloadState(loadedTopStateNode_->name_);
+ else // has to be child
{
- bool threwException = false;
try
{
- // Add tick time for most of the states
- uint64_t timeBeforeTick;
- if (!(*it)->ignoreTickTime())
- timeBeforeTick = this->gameClock_->getRealMicroseconds();
- (*it)->update(*this->gameClock_);
- if (!(*it)->ignoreTickTime())
- this->addTickTime(static_cast<uint32_t>(this->gameClock_->getRealMicroseconds() - timeBeforeTick));
+ this->loadState(requestedStateNode->name_);
}
catch (const std::exception& ex)
{
- threwException = true;
- COUT(0) << "Exception while ticking: " << ex.what() << std::endl;
- }
- catch (...)
- {
- threwException = true;
- }
- if (threwException)
- {
- COUT(1) << "An exception occured while ticking GameState '" << (*it)->getName() << "'. This should really never happen!" << std::endl;
- COUT(1) << "Unloading all GameStates depending on the one that crashed." << std::endl;
- if ((*it)->getParent() != NULL)
- this->requestState((*it)->getParent()->getName());
- else
- this->stop();
+ COUT(1) << "Error: Loading GameState '" << requestedStateNode->name_ << "' failed: " << ex.what() << std::endl;
+ // All scheduled operations have now been rendered inert --> flush them and issue a warning
+ if (this->requestedStateNodes_.size() > 1)
+ COUT(1) << "All " << this->requestedStateNodes_.size() - 1 << " scheduled transitions have been ignored." << std::endl;
+ this->requestedStateNodes_.clear();
break;
}
+ }
+ this->loadedTopStateNode_ = requestedStateNode;
+ this->requestedStateNodes_.erase(this->requestedStateNodes_.begin());
+ }
+ }
+ void Game::updateGameStates()
+ {
+ // Note: The first element is the empty root state, which doesn't need ticking
+ for (GameStateVector::const_iterator it = this->loadedStates_.begin() + 1;
+ it != this->loadedStates_.end(); ++it)
+ {
+ std::string exceptionMessage;
+ try
+ {
+ // Add tick time for most of the states
+ uint64_t timeBeforeTick;
+ if ((*it)->getInfo().bIgnoreTickTime)
+ timeBeforeTick = this->gameClock_->getRealMicroseconds();
+ (*it)->update(*this->gameClock_);
+ if ((*it)->getInfo().bIgnoreTickTime)
+ this->subtractTickTime(static_cast<int32_t>(this->gameClock_->getRealMicroseconds() - timeBeforeTick));
}
+ catch (const std::exception& ex)
+ { exceptionMessage = ex.what(); }
+ catch (...)
+ { exceptionMessage = "Unknown exception"; }
+ if (!exceptionMessage.empty())
+ {
+ COUT(1) << "An exception occurred while updating '" << (*it)->getName() << "': " << exceptionMessage << std::endl;
+ COUT(1) << "This should really never happen!" << std::endl;
+ COUT(1) << "Unloading all GameStates depending on the one that crashed." << std::endl;
+ shared_ptr<GameStateTreeNode> current = this->loadedTopStateNode_;
+ while (current->name_ != (*it)->getName() && current)
+ current = current->parent_.lock();
+ if (current && current->parent_.lock())
+ this->requestState(current->parent_.lock()->name_);
+ else
+ this->stop();
+ break;
+ }
+ }
+ }
- // STATISTICS
- if (this->periodTime_ > this->configuration_->statisticsRefreshCycle_)
+ void Game::updateStatistics()
+ {
+ // Add the tick time of this frame (rendering time has already been subtracted)
+ uint64_t currentTime = gameClock_->getMicroseconds();
+ uint64_t currentRealTime = gameClock_->getRealMicroseconds();
+ this->statisticsTickTimes_.back().tickLength += currentRealTime - currentTime;
+ this->periodTickTime_ += currentRealTime - currentTime;
+ if (this->periodTime_ > this->configuration_->statisticsRefreshCycle_)
+ {
+ std::list<StatisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();
+ assert(it != this->statisticsTickTimes_.end());
+ int64_t lastTime = currentTime - this->configuration_->statisticsAvgLength_;
+ if (static_cast<int64_t>(it->tickTime) < lastTime)
{
- std::list<StatisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();
- assert(it != this->statisticsTickTimes_.end());
- int64_t lastTime = currentTime - this->configuration_->statisticsAvgLength_;
- if (static_cast<int64_t>(it->tickTime) < lastTime)
+ do
{
- do
- {
- assert(this->periodTickTime_ >= it->tickLength);
- this->periodTickTime_ -= it->tickLength;
- ++it;
- assert(it != this->statisticsTickTimes_.end());
- } while (static_cast<int64_t>(it->tickTime) < lastTime);
- this->statisticsTickTimes_.erase(this->statisticsTickTimes_.begin(), it);
- }
+ assert(this->periodTickTime_ >= it->tickLength);
+ this->periodTickTime_ -= it->tickLength;
+ ++it;
+ assert(it != this->statisticsTickTimes_.end());
+ } while (static_cast<int64_t>(it->tickTime) < lastTime);
+ this->statisticsTickTimes_.erase(this->statisticsTickTimes_.begin(), it);
+ }
- uint32_t framesPerPeriod = this->statisticsTickTimes_.size();
- this->avgFPS_ = static_cast<float>(framesPerPeriod) / (currentTime - this->statisticsTickTimes_.front().tickTime) * 1000000.0f;
- this->avgTickTime_ = static_cast<float>(this->periodTickTime_) / framesPerPeriod / 1000.0f;
+ uint32_t framesPerPeriod = this->statisticsTickTimes_.size();
+ this->avgFPS_ = static_cast<float>(framesPerPeriod) / (currentTime - this->statisticsTickTimes_.front().tickTime) * 1000000.0f;
+ this->avgTickTime_ = static_cast<float>(this->periodTickTime_) / framesPerPeriod / 1000.0f;
- this->periodTime_ -= this->configuration_->statisticsRefreshCycle_;
- }
+ this->periodTime_ -= this->configuration_->statisticsRefreshCycle_;
}
+ }
- // UNLOAD all remaining states
- while (this->activeStates_.size() > 1)
- this->unloadState(this->activeStates_.back());
- this->activeStateNode_ = this->rootStateNode_;
- this->requestedStateNodes_.clear();
+ void Game::updateFPSLimiter()
+ {
+ // Why configuration_->fpsLimit_ - 1? No idea, but otherwise the fps rate is always (from 10 to 200!) one frame too high
+ uint32_t nextTime = gameClock_->getMicroseconds() - excessSleepTime_ + static_cast<uint32_t>(1000000.0f / (configuration_->fpsLimit_ - 1));
+ uint64_t currentRealTime = gameClock_->getRealMicroseconds();
+ while (currentRealTime < nextTime - minimumSleepTime_)
+ {
+ usleep(nextTime - currentRealTime);
+ currentRealTime = gameClock_->getRealMicroseconds();
+ }
+ // Integrate excess to avoid steady state error
+ excessSleepTime_ = currentRealTime - nextTime;
+ // Anti windup
+ if (excessSleepTime_ > 50000) // 20ms is about the maximum time Windows would sleep for too long
+ excessSleepTime_ = 50000;
}
void Game::stop()
@@ -343,11 +350,11 @@
this->bAbort_ = true;
}
- void Game::addTickTime(uint32_t length)
+ void Game::subtractTickTime(int32_t length)
{
assert(!this->statisticsTickTimes_.empty());
- this->statisticsTickTimes_.back().tickLength += length;
- this->periodTickTime_+=length;
+ this->statisticsTickTimes_.back().tickLength -= length;
+ this->periodTickTime_ -= length;
}
@@ -355,22 +362,24 @@
void Game::requestState(const std::string& name)
{
- GameState* state = this->getState(name);
- if (state == NULL)
+ if (!this->checkState(name))
+ {
+ COUT(2) << "Warning: GameState named '" << name << "' doesn't exist!" << std::endl;
return;
+ }
- //if (this->bChangingState_)
- //{
- // COUT(2) << "Warning: Requesting GameStates while loading/unloading a GameState is illegal! Ignoring." << std::endl;
- // return;
- //}
+ if (this->bChangingState_)
+ {
+ COUT(2) << "Warning: Requesting GameStates while loading/unloading a GameState is illegal! Ignoring." << std::endl;
+ return;
+ }
shared_ptr<GameStateTreeNode> lastRequestedNode;
if (this->requestedStateNodes_.empty())
- lastRequestedNode = this->activeStateNode_;
+ lastRequestedNode = this->loadedTopStateNode_;
else
lastRequestedNode = this->requestedStateNodes_.back();
- if (state == lastRequestedNode->state_)
+ if (name == lastRequestedNode->name_)
{
COUT(2) << "Warning: Requesting the currently active state! Ignoring." << std::endl;
return;
@@ -380,7 +389,7 @@
std::vector<shared_ptr<GameStateTreeNode> > requestedNodes;
for (unsigned int i = 0; i < lastRequestedNode->children_.size(); ++i)
{
- if (lastRequestedNode->children_[i]->state_ == state)
+ if (lastRequestedNode->children_[i]->name_ == name)
{
requestedNodes.push_back(lastRequestedNode->children_[i]);
break;
@@ -393,7 +402,7 @@
shared_ptr<GameStateTreeNode> currentNode = lastRequestedNode;
while (currentNode != NULL)
{
- if (currentNode->state_ == state)
+ if (currentNode->name_ == name)
break;
currentNode = currentNode->parent_.lock();
requestedNodes.push_back(currentNode);
@@ -417,24 +426,28 @@
{
shared_ptr<GameStateTreeNode> lastRequestedNode;
if (this->requestedStateNodes_.empty())
- lastRequestedNode = this->activeStateNode_;
+ lastRequestedNode = this->loadedTopStateNode_;
else
lastRequestedNode = this->requestedStateNodes_.back();
if (lastRequestedNode != this->rootStateNode_)
- this->requestState(lastRequestedNode->parent_.lock()->state_->getName());
+ this->requestState(lastRequestedNode->parent_.lock()->name_);
else
COUT(2) << "Warning: Can't pop the internal dummy root GameState" << std::endl;
}
- GameState* Game::getState(const std::string& name)
+ shared_ptr<GameState> Game::getState(const std::string& name)
{
- std::map<std::string, GameState*>::const_iterator it = gameStates_.find(getLowercase(name));
- if (it != gameStates_.end())
+ GameStateMap::const_iterator it = constructedStates_.find(name);
+ if (it != constructedStates_.end())
return it->second;
else
{
- COUT(1) << "Error: Could not find GameState '" << name << "'. Ignoring." << std::endl;
- return 0;
+ std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(name);
+ if (it != gameStateDeclarations_s.end())
+ COUT(1) << "Error: GameState '" << name << "' has not yet been loaded." << std::endl;
+ else
+ COUT(1) << "Error: Could not find GameState '" << name << "'." << std::endl;
+ return shared_ptr<GameState>();
}
}
@@ -460,13 +473,12 @@
{
std::string newStateName = it->first;
unsigned newLevel = it->second + 1; // empty root is 0
- GameState* newState = this->getState(newStateName);
- if (!newState)
+ if (!this->checkState(newStateName))
ThrowException(GameState, "GameState with name '" << newStateName << "' not found!");
- if (newState == this->rootStateNode_->state_)
+ if (newStateName == this->rootStateNode_->name_)
ThrowException(GameState, "You shouldn't use 'emptyRootGameState' in the hierarchy...");
shared_ptr<GameStateTreeNode> newNode(new GameStateTreeNode);
- newNode->state_ = newState;
+ newNode->name_ = newStateName;
if (newLevel <= currentLevel)
{
@@ -479,7 +491,6 @@
// Add the child
newNode->parent_ = currentNode;
currentNode->children_.push_back(newNode);
- currentNode->state_->addChild(newNode->state_);
}
else
ThrowException(GameState, "Indentation error while parsing the hierarchy.");
@@ -490,49 +501,112 @@
/*** Internal ***/
- void Game::loadState(GameState* state)
+ void Game::loadGraphics()
{
+ if (!GameMode::bShowsGraphics_s)
+ {
+ core_->loadGraphics();
+ Loki::ScopeGuard graphicsUnloader = Loki::MakeObjGuard(*this, &Game::unloadGraphics);
+ GameMode::bShowsGraphics_s = true;
+
+ // Construct all the GameStates that require graphics
+ for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin();
+ it != gameStateDeclarations_s.end(); ++it)
+ {
+ if (it->second.bGraphicsMode)
+ {
+ // Game state loading failure is serious --> don't catch
+ shared_ptr<GameState> gameState = GameStateFactory::fabricate(it->second);
+ if (!constructedStates_.insert(std::make_pair(
+ it->second.stateName, gameState)).second)
+ assert(false); // GameState was already created!
+ }
+ }
+ graphicsUnloader.Dismiss();
+ }
+ }
+
+ void Game::unloadGraphics()
+ {
+ if (GameMode::bShowsGraphics_s)
+ {
+ // Destroy all the GameStates that require graphics
+ for (GameStateMap::iterator it = constructedStates_.begin(); it != constructedStates_.end();)
+ {
+ if (it->second->getInfo().bGraphicsMode)
+ constructedStates_.erase(it++);
+ else
+ ++it;
+ }
+
+ core_->unloadGraphics();
+ GameMode::bShowsGraphics_s = false;
+ }
+ }
+
+ bool Game::checkState(const std::string& name) const
+ {
+ std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(name);
+ if (it == gameStateDeclarations_s.end())
+ return false;
+ else
+ return true;
+ }
+
+ void Game::loadState(const std::string& name)
+ {
this->bChangingState_ = true;
+ LOKI_ON_BLOCK_EXIT_OBJ(*this, &Game::resetChangingState);
+
+ // If state requires graphics, load it
+ Loki::ScopeGuard graphicsUnloader = Loki::MakeObjGuard(*this, &Game::unloadGraphics);
+ if (gameStateDeclarations_s[name].bGraphicsMode && !GameMode::showsGraphics())
+ this->loadGraphics();
+ else
+ graphicsUnloader.Dismiss();
+
+ shared_ptr<GameState> state = this->getState(name);
state->activate();
- if (!this->activeStates_.empty())
- this->activeStates_.back()->activity_.topState = false;
- this->activeStates_.push_back(state);
+ if (!this->loadedStates_.empty())
+ this->loadedStates_.back()->activity_.topState = false;
+ this->loadedStates_.push_back(state);
state->activity_.topState = true;
- this->bChangingState_ = false;
+
+ graphicsUnloader.Dismiss();
}
- void Game::unloadState(orxonox::GameState* state)
+ void Game::unloadState(const std::string& name)
{
this->bChangingState_ = true;
- state->activity_.topState = false;
- this->activeStates_.pop_back();
- if (!this->activeStates_.empty())
- this->activeStates_.back()->activity_.topState = true;
try
{
+ shared_ptr<GameState> state = this->getState(name);
+ state->activity_.topState = false;
+ this->loadedStates_.pop_back();
+ if (!this->loadedStates_.empty())
+ this->loadedStates_.back()->activity_.topState = true;
state->deactivate();
}
catch (const std::exception& ex)
{
- COUT(2) << "Warning: Unloading GameState '" << state->getName() << "' threw an exception: " << ex.what() << std::endl;
+ COUT(2) << "Warning: Unloading GameState '" << name << "' threw an exception: " << ex.what() << std::endl;
COUT(2) << " There might be potential resource leaks involved! To avoid this, improve exception-safety." << std::endl;
}
+ // Check if graphics is still required
+ bool graphicsRequired = false;
+ for (unsigned i = 0; i < loadedStates_.size(); ++i)
+ graphicsRequired |= loadedStates_[i]->getInfo().bGraphicsMode;
+ if (!graphicsRequired)
+ this->unloadGraphics();
this->bChangingState_ = false;
}
- std::map<std::string, Game::GameStateFactory*> Game::GameStateFactory::factories_s;
+ std::map<std::string, shared_ptr<Game::GameStateFactory> > Game::GameStateFactory::factories_s;
- /*static*/ GameState* Game::GameStateFactory::fabricate(const std::string& className, const GameStateConstrParams& params)
+ /*static*/ shared_ptr<GameState> Game::GameStateFactory::fabricate(const GameStateInfo& info)
{
- std::map<std::string, GameStateFactory*>::const_iterator it = factories_s.find(className);
+ std::map<std::string, shared_ptr<Game::GameStateFactory> >::const_iterator it = factories_s.find(info.className);
assert(it != factories_s.end());
- return it->second->fabricate(params);
+ return it->second->fabricateInternal(info);
}
-
- /*static*/ void Game::GameStateFactory::destroyFactories()
- {
- for (std::map<std::string, GameStateFactory*>::const_iterator it = factories_s.begin(); it != factories_s.end(); ++it)
- delete it->second;
- factories_s.clear();
- }
}
Modified: trunk/src/core/Game.h
===================================================================
--- trunk/src/core/Game.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/Game.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -43,10 +43,11 @@
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
+#include <boost/scoped_ptr.hpp>
#include <boost/preprocessor/cat.hpp>
#include "util/Debug.h"
-#include "util/StringUtils.h"
+#include "util/Singleton.h"
/**
@def
@@ -59,19 +60,36 @@
namespace orxonox
{
class GameConfiguration;
+ using boost::scoped_ptr;
+ using boost::shared_ptr;
+ //! Helper object required before GameStates are being constructed
+ struct GameStateInfo
+ {
+ std::string stateName;
+ std::string className;
+ bool bIgnoreTickTime;
+ bool bGraphicsMode;
+ };
+
/**
@brief
Main class responsible for running the game.
+ @remark
+ You should only create this singleton once because it owns the Core class! (see remark there)
*/
- class _CoreExport Game
+ class _CoreExport Game : public Singleton<Game>
{
+ friend class Singleton<Game>;
+ typedef std::vector<shared_ptr<GameState> > GameStateVector;
+ typedef std::map<std::string, shared_ptr<GameState> > GameStateMap;
+ typedef boost::shared_ptr<GameStateTreeNode> GameStateTreeNodePtr;
public:
Game(const std::string& cmdLine);
~Game();
void setStateHierarchy(const std::string& str);
- GameState* getState(const std::string& name);
+ shared_ptr<GameState> getState(const std::string& name);
void run();
void stop();
@@ -85,42 +103,32 @@
float getAvgTickTime() { return this->avgTickTime_; }
float getAvgFPS() { return this->avgFPS_; }
- void addTickTime(uint32_t length);
+ void subtractTickTime(int32_t length);
template <class T>
static bool declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bConsoleMode);
- static Game& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
private:
class _CoreExport GameStateFactory
{
public:
virtual ~GameStateFactory() { }
- static GameState* fabricate(const std::string& className, const GameStateConstrParams& params);
+ static shared_ptr<GameState> fabricate(const GameStateInfo& info);
template <class T>
static void createFactory(const std::string& className)
- { factories_s[className] = new TemplateGameStateFactory<T>(); }
- static void destroyFactories();
+ { factories_s[className].reset(new TemplateGameStateFactory<T>()); }
private:
- virtual GameState* fabricate(const GameStateConstrParams& params) = 0;
- static std::map<std::string, GameStateFactory*> factories_s;
+ virtual shared_ptr<GameState> fabricateInternal(const GameStateInfo& info) = 0;
+ static std::map<std::string, shared_ptr<GameStateFactory> > factories_s;
};
template <class T>
class TemplateGameStateFactory : public GameStateFactory
{
public:
- GameState* fabricate(const GameStateConstrParams& params)
- { return new T(params); }
+ shared_ptr<GameState> fabricateInternal(const GameStateInfo& info)
+ { return shared_ptr<GameState>(new T(info)); }
};
- struct GameStateInfo
- {
- std::string stateName;
- std::string className;
- bool bIgnoreTickTime;
- bool bGraphicsMode;
- };
-
struct StatisticsTickInfo
{
uint64_t tickTime;
@@ -129,41 +137,56 @@
Game(Game&); // don't mess with singletons
- void loadState(GameState* state);
- void unloadState(GameState* state);
+ void loadGraphics();
+ void unloadGraphics();
- std::map<std::string, GameState*> gameStates_;
- std::vector<GameState*> activeStates_;
- boost::shared_ptr<GameStateTreeNode> rootStateNode_;
- boost::shared_ptr<GameStateTreeNode> activeStateNode_;
- std::vector<boost::shared_ptr<GameStateTreeNode> > requestedStateNodes_;
+ bool checkState(const std::string& name) const;
+ void loadState(const std::string& name);
+ void unloadState(const std::string& name);
- Core* core_;
- Clock* gameClock_;
- GameConfiguration* configuration_;
+ // Main loop structuring
+ void updateGameStateStack();
+ void updateGameStates();
+ void updateStatistics();
+ void updateFPSLimiter();
- bool bChangingState_;
- bool bAbort_;
+ // ScopeGuard helper function
+ void resetChangingState() { this->bChangingState_ = false; }
+ scoped_ptr<Clock> gameClock_;
+ scoped_ptr<Core> core_;
+ scoped_ptr<GameConfiguration> configuration_;
+
+ GameStateMap constructedStates_;
+ GameStateVector loadedStates_;
+ GameStateTreeNodePtr rootStateNode_;
+ GameStateTreeNodePtr loadedTopStateNode_;
+ std::vector<GameStateTreeNodePtr> requestedStateNodes_;
+
+ bool bChangingState_;
+ bool bAbort_;
+
// variables for time statistics
- uint64_t statisticsStartTime_;
- std::list<StatisticsTickInfo> statisticsTickTimes_;
- uint32_t periodTime_;
- uint32_t periodTickTime_;
- float avgFPS_;
- float avgTickTime_;
+ uint64_t statisticsStartTime_;
+ std::list<StatisticsTickInfo> statisticsTickTimes_;
+ uint32_t periodTime_;
+ uint32_t periodTickTime_;
+ float avgFPS_;
+ float avgTickTime_;
+ int excessSleepTime_;
+ unsigned int minimumSleepTime_;
static std::map<std::string, GameStateInfo> gameStateDeclarations_s;
- static Game* singletonRef_s; //!< Pointer to the Singleton
+ static Game* singletonPtr_s; //!< Pointer to the Singleton
};
template <class T>
/*static*/ bool Game::declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bGraphicsMode)
{
- std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(getLowercase(stateName));
+ std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(stateName);
if (it == gameStateDeclarations_s.end())
{
- GameStateInfo& info = gameStateDeclarations_s[getLowercase(stateName)];
+ GameStateInfo& info = gameStateDeclarations_s[stateName];
info.stateName = stateName;
info.className = className;
info.bIgnoreTickTime = bIgnoreTickTime;
Modified: trunk/src/core/GameMode.h
===================================================================
--- trunk/src/core/GameMode.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/GameMode.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -40,23 +40,29 @@
{
class _CoreExport GameMode
{
+ friend class Game;
+
public:
static bool showsGraphics() { return bShowsGraphics_s; }
static bool hasServer() { return bHasServer_s; }
static bool isClient() { return bIsClient_s; }
static bool isStandalone() { return bIsStandalone_s; }
static bool isMaster() { return bIsMaster_s; }
- static void setShowsGraphics(bool val) { bShowsGraphics_s = val; updateIsMaster(); }
+
static void setHasServer (bool val) { bHasServer_s = val; updateIsMaster(); }
static void setIsClient (bool val) { bIsClient_s = val; updateIsMaster(); }
static void setIsStandalone (bool val) { bIsStandalone_s = val; updateIsMaster(); }
- static void updateIsMaster () { bIsMaster_s = (bHasServer_s || bIsStandalone_s); }
private:
GameMode();
GameMode(const GameMode& inst);
~GameMode();
+ static void updateIsMaster()
+ {
+ bIsMaster_s = (bHasServer_s || bIsStandalone_s);
+ }
+
static bool bShowsGraphics_s; //!< global variable that tells whether to show graphics
static bool bHasServer_s; //!< global variable that tells whether this is a server
static bool bIsClient_s;
Modified: trunk/src/core/GameState.cc
===================================================================
--- trunk/src/core/GameState.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/GameState.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -37,6 +37,7 @@
#include "util/Debug.h"
#include "util/Exception.h"
#include "util/OrxAssert.h"
+#include "Game.h"
namespace orxonox
{
@@ -44,10 +45,8 @@
@brief
Constructor only initialises variables and sets the name permanently.
*/
- GameState::GameState(const GameStateConstrParams& params)
- : name_(params.name)
- , bIgnoreTickTime_(params.bIgnoreTickTime)
- , parent_(0)
+ GameState::GameState(const GameStateInfo& info)
+ : info_(info)
{
this->activity_.activating = false;
this->activity_.active = false;
@@ -66,51 +65,11 @@
OrxAssert(this->activity_.active == false, "Deleting an active GameState is a very bad idea..");
}
- /**
- @brief
- Adds a child to the current tree. The Child can contain children of its own.
- But you cannot a state tree that already has an active state.
- @param state
- The state to be added.
- */
- void GameState::addChild(GameState* state)
+ const std::string& GameState::getName() const
{
- assert(state != NULL);
-
- std::map<std::string, GameState*>::const_iterator it = this->children_.find(state->getName());
- if (it == this->children_.end())
- {
- this->children_[state->getName()] = state;
- // mark us as parent
- state->setParent(this);
- }
- else
- {
- ThrowException(GameState, "Cannot add two children with the same name");
- }
+ return info_.stateName;
}
- /**
- @brief
- Removes a child by instance. This splits the tree in two parts,
- each of them functional on its own.
- @param state
- GameState by instance pointer
- */
- void GameState::removeChild(GameState* state)
- {
- assert(state != NULL);
-
- std::map<std::string, GameState*>::iterator it = this->children_.find(state->getName());
- if (it != this->children_.end())
- this->children_.erase(it);
- else
- {
- ThrowException(GameState, "Game state '" + name_ + "' doesn't have a child named '"
- + state->getName() + "'.");
- }
- }
-
void GameState::activateInternal()
{
this->activity_.activating = true;
Modified: trunk/src/core/GameState.h
===================================================================
--- trunk/src/core/GameState.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/GameState.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -44,16 +44,6 @@
{
/**
@brief
- Helper class to group construction parameters for better genericity.
- */
- struct GameStateConstrParams
- {
- std::string name;
- bool bIgnoreTickTime;
- };
-
- /**
- @brief
An implementation of a tree to manage game states.
This leads to a certain hierarchy that is created at runtime.
To actually use the structure, you will have to derive from it and
@@ -86,35 +76,26 @@
};
public:
- GameState(const GameStateConstrParams& params);
+ GameState(const GameStateInfo& info);
virtual ~GameState();
- const std::string& getName() const { return name_; }
- State getActivity() const { return this->activity_; }
- GameState* getParent() const { return this->parent_; }
+ const std::string& getName() const;
+ State getActivity() const { return activity_; }
+ const GameStateInfo& getInfo() const { return info_; }
- bool ignoreTickTime() const { return this->bIgnoreTickTime_; }
-
- void addChild(GameState* state);
- void removeChild(GameState* state);
-
protected:
virtual void activate() { }
virtual void deactivate() { }
virtual void update(const Clock& time) { }
private:
- void setParent(GameState* state) { this->parent_ = state; }
void setActivity(State activity);
void activateInternal();
void deactivateInternal();
void updateInternal(const Clock& time);
- const std::string name_;
- State activity_;
- const bool bIgnoreTickTime_;
- GameState* parent_;
- std::map<std::string, GameState*> children_;
+ const GameStateInfo& info_;
+ State activity_;
};
}
Copied: trunk/src/core/GraphicsManager.cc (from rev 3367, branches/resource/src/core/GraphicsManager.cc)
===================================================================
--- trunk/src/core/GraphicsManager.cc (rev 0)
+++ trunk/src/core/GraphicsManager.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -0,0 +1,414 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Reto Grieder
+ * Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
+ * Co-authors:
+ * Felix Schulthess
+ *
+ */
+
+/**
+ at file
+ at brief
+ Implementation of an partial interface to Ogre.
+*/
+
+#include "GraphicsManager.h"
+
+#include <fstream>
+#include <memory>
+#include <boost/filesystem.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <OgreCompositorManager.h>
+#include <OgreConfigFile.h>
+#include <OgreFrameListener.h>
+#include <OgreRoot.h>
+#include <OgreLogManager.h>
+#include <OgreException.h>
+#include <OgreRenderWindow.h>
+#include <OgreRenderSystem.h>
+#include <OgreTextureManager.h>
+#include <OgreViewport.h>
+#include <OgreWindowEventUtilities.h>
+
+#include "SpecialConfig.h"
+#include "util/Exception.h"
+#include "util/StringUtils.h"
+#include "util/SubString.h"
+#include "Clock.h"
+#include "ConsoleCommand.h"
+#include "ConfigValueIncludes.h"
+#include "CoreIncludes.h"
+#include "Core.h"
+#include "Game.h"
+#include "GameMode.h"
+#include "WindowEventListener.h"
+
+namespace orxonox
+{
+ using boost::shared_ptr;
+
+ class OgreWindowEventListener : public Ogre::WindowEventListener
+ {
+ public:
+ void windowResized (Ogre::RenderWindow* rw)
+ { orxonox::WindowEventListener::resizeWindow(rw->getWidth(), rw->getHeight()); }
+ void windowFocusChange (Ogre::RenderWindow* rw)
+ { orxonox::WindowEventListener::changeWindowFocus(); }
+ void windowClosed (Ogre::RenderWindow* rw)
+ { orxonox::Game::getInstance().stop(); }
+ void windowMoved (Ogre::RenderWindow* rw)
+ { orxonox::WindowEventListener::moveWindow(); }
+ };
+
+ GraphicsManager* GraphicsManager::singletonPtr_s = 0;
+
+ /**
+ @brief
+ Non-initialising constructor.
+ */
+ GraphicsManager::GraphicsManager()
+ : ogreRoot_(0)
+ , ogreLogger_(0)
+ , renderWindow_(0)
+ , viewport_(0)
+ , ogreWindowEventListener_(new OgreWindowEventListener())
+ {
+ RegisterObject(GraphicsManager);
+
+ this->setConfigValues();
+
+ // Ogre setup procedure
+ setupOgre();
+
+ try
+ {
+ // load all the required plugins for Ogre
+ loadOgrePlugins();
+ // read resource declaration file
+ this->declareResources();
+ // Reads ogre config and creates the render window
+ this->loadRenderer();
+
+ // TODO: Spread this
+ this->initialiseResources();
+
+ // add console commands
+ FunctorMember<GraphicsManager>* functor1 = createFunctor(&GraphicsManager::printScreen);
+ functor1->setObject(this);
+ ccPrintScreen_ = createConsoleCommand(functor1, "printScreen");
+ CommandExecutor::addConsoleCommandShortcut(ccPrintScreen_);
+ }
+ catch (...)
+ {
+ // clean up
+ delete this->ogreRoot_;
+ delete this->ogreLogger_;
+ delete this->ogreWindowEventListener_;
+ throw;
+ }
+ }
+
+ /**
+ @brief
+ Destroys all the Ogre related objects
+ */
+ GraphicsManager::~GraphicsManager()
+ {
+/*
+ delete this->ccPrintScreen_;
+*/
+
+ // unload all compositors (this is only necessary because we don't yet destroy all resources!)
+ Ogre::CompositorManager::getSingleton().removeAll();
+
+ // Delete OGRE main control organ
+ delete this->ogreRoot_;
+
+ // delete the logManager (since we have created it in the first place).
+ delete this->ogreLogger_;
+
+ delete this->ogreWindowEventListener_;
+ }
+
+ void GraphicsManager::setConfigValues()
+ {
+ SetConfigValue(resourceFile_, "resources.cfg")
+ .description("Location of the resources file in the data path.");
+ SetConfigValue(ogreConfigFile_, "ogre.cfg")
+ .description("Location of the Ogre config file");
+ SetConfigValue(ogrePluginsFolder_, ORXONOX_OGRE_PLUGINS_FOLDER)
+ .description("Folder where the Ogre plugins are located.");
+ SetConfigValue(ogrePlugins_, ORXONOX_OGRE_PLUGINS)
+ .description("Comma separated list of all plugins to load.");
+ SetConfigValue(ogreLogFile_, "ogre.log")
+ .description("Logfile for messages from Ogre. Use \"\" to suppress log file creation.");
+ SetConfigValue(ogreLogLevelTrivial_ , 5)
+ .description("Corresponding orxonox debug level for ogre Trivial");
+ SetConfigValue(ogreLogLevelNormal_ , 4)
+ .description("Corresponding orxonox debug level for ogre Normal");
+ SetConfigValue(ogreLogLevelCritical_, 2)
+ .description("Corresponding orxonox debug level for ogre Critical");
+ }
+
+ void GraphicsManager::update(const Clock& time)
+ {
+ Ogre::FrameEvent evt;
+ evt.timeSinceLastFrame = time.getDeltaTime();
+ evt.timeSinceLastEvent = time.getDeltaTime(); // note: same time, but shouldn't matter anyway
+
+ // don't forget to call _fireFrameStarted to OGRE to make sure
+ // everything goes smoothly
+ ogreRoot_->_fireFrameStarted(evt);
+
+ // Pump messages in all registered RenderWindows
+ // This calls the WindowEventListener objects.
+ Ogre::WindowEventUtilities::messagePump();
+ // make sure the window stays active even when not focused
+ // (probably only necessary on windows)
+ this->renderWindow_->setActive(true);
+
+ // Time before rendering
+ uint64_t timeBeforeTick = time.getRealMicroseconds();
+
+ // Render frame
+ ogreRoot_->_updateAllRenderTargets();
+
+ uint64_t timeAfterTick = time.getRealMicroseconds();
+ // Subtract the time used for rendering from the tick time counter
+ Game::getInstance().subtractTickTime(timeAfterTick - timeBeforeTick);
+
+ // again, just to be sure OGRE works fine
+ ogreRoot_->_fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
+ }
+
+ void GraphicsManager::setCamera(Ogre::Camera* camera)
+ {
+ this->viewport_->setCamera(camera);
+ }
+
+ /**
+ @brief
+ Creates the Ogre Root object and sets up the ogre log.
+ */
+ void GraphicsManager::setupOgre()
+ {
+ COUT(3) << "Setting up Ogre..." << std::endl;
+
+ if (ogreConfigFile_ == "")
+ {
+ COUT(2) << "Warning: Ogre config file set to \"\". Defaulting to config.cfg" << std::endl;
+ ModifyConfigValue(ogreConfigFile_, tset, "config.cfg");
+ }
+ if (ogreLogFile_ == "")
+ {
+ COUT(2) << "Warning: Ogre log file set to \"\". Defaulting to ogre.log" << std::endl;
+ ModifyConfigValue(ogreLogFile_, tset, "ogre.log");
+ }
+
+ boost::filesystem::path ogreConfigFilepath(Core::getConfigPath() / this->ogreConfigFile_);
+ boost::filesystem::path ogreLogFilepath(Core::getLogPath() / this->ogreLogFile_);
+
+ // create a new logManager
+ // Ogre::Root will detect that we've already created a Log
+ std::auto_ptr<Ogre::LogManager> logger(new Ogre::LogManager());
+ COUT(4) << "Ogre LogManager created" << std::endl;
+
+ // create our own log that we can listen to
+ Ogre::Log *myLog;
+ myLog = logger->createLog(ogreLogFilepath.string(), true, false, false);
+ COUT(4) << "Ogre Log created" << std::endl;
+
+ myLog->setLogDetail(Ogre::LL_BOREME);
+ myLog->addListener(this);
+
+ COUT(4) << "Creating Ogre Root..." << std::endl;
+
+ // check for config file existence because Ogre displays (caught) exceptions if not
+ if (!boost::filesystem::exists(ogreConfigFilepath))
+ {
+ // create a zero sized file
+ std::ofstream creator;
+ creator.open(ogreConfigFilepath.string().c_str());
+ creator.close();
+ }
+
+ // Leave plugins file empty. We're going to do that part manually later
+ ogreRoot_ = new Ogre::Root("", ogreConfigFilepath.string(), ogreLogFilepath.string());
+ // In case that new Root failed the logger gets destroyed because of the std::auto_ptr
+ ogreLogger_ = logger.release();
+
+ COUT(3) << "Ogre set up done." << std::endl;
+ }
+
+ void GraphicsManager::loadOgrePlugins()
+ {
+ // just to make sure the next statement doesn't segfault
+ if (ogrePluginsFolder_ == "")
+ ogrePluginsFolder_ = ".";
+
+ boost::filesystem::path folder(ogrePluginsFolder_);
+ // Do some SubString magic to get the comma separated list of plugins
+ SubString plugins(ogrePlugins_, ",", " ", false, '\\', false, '"', false, '(', ')', false, '\0');
+ // Use backslash paths on Windows! file_string() already does that though.
+ for (unsigned int i = 0; i < plugins.size(); ++i)
+ ogreRoot_->loadPlugin((folder / plugins[i]).file_string());
+ }
+
+ void GraphicsManager::declareResources()
+ {
+ CCOUT(4) << "Declaring Resources" << std::endl;
+ //TODO: Specify layout of data file and maybe use xml-loader
+ //TODO: Work with ressource groups (should be generated by a special loader)
+
+ if (resourceFile_ == "")
+ {
+ COUT(2) << "Warning: Ogre resource file set to \"\". Defaulting to resources.cfg" << std::endl;
+ ModifyConfigValue(resourceFile_, tset, "resources.cfg");
+ }
+
+ // Load resource paths from data file using configfile ressource type
+ Ogre::ConfigFile cf;
+ try
+ {
+ cf.load((Core::getMediaPath() / resourceFile_).string());
+ }
+ catch (...)
+ {
+ //COUT(1) << ex.getFullDescription() << std::endl;
+ COUT(0) << "Have you forgotten to set the data path in orxnox.ini?" << std::endl;
+ throw;
+ }
+
+ // Go through all sections & settings in the file
+ Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
+
+ std::string secName, typeName, archName;
+ while (seci.hasMoreElements())
+ {
+ try
+ {
+ secName = seci.peekNextKey();
+ Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
+ Ogre::ConfigFile::SettingsMultiMap::iterator i;
+ for (i = settings->begin(); i != settings->end(); ++i)
+ {
+ typeName = i->first; // for instance "FileSystem" or "Zip"
+ archName = i->second; // name (and location) of archive
+
+ Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
+ (Core::getMediaPath() / archName).string(), typeName, secName);
+ }
+ }
+ catch (Ogre::Exception& ex)
+ {
+ COUT(1) << ex.getFullDescription() << std::endl;
+ }
+ }
+ }
+
+ void GraphicsManager::loadRenderer()
+ {
+ CCOUT(4) << "Configuring Renderer" << std::endl;
+
+ if (!ogreRoot_->restoreConfig())
+ if (!ogreRoot_->showConfigDialog())
+ ThrowException(InitialisationFailed, "OGRE graphics configuration dialogue failed.");
+
+ CCOUT(4) << "Creating render window" << std::endl;
+
+ this->renderWindow_ = ogreRoot_->initialise(true, "Orxonox");
+ this->ogreWindowEventListener_->windowResized(renderWindow_);
+
+ Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, ogreWindowEventListener_);
+
+ Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(0);
+
+ // create a full screen default viewport
+ this->viewport_ = this->renderWindow_->addViewport(0, 0);
+ }
+
+ void GraphicsManager::initialiseResources()
+ {
+ CCOUT(4) << "Initialising resources" << std::endl;
+ //TODO: Do NOT load all the groups, why are we doing that? And do we really do that? initialise != load...
+ //try
+ //{
+ Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
+ /*Ogre::StringVector str = Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
+ for (unsigned int i = 0; i < str.size(); i++)
+ {
+ Ogre::ResourceGroupManager::getSingleton().loadResourceGroup(str[i]);
+ }*/
+ //}
+ //catch (...)
+ //{
+ // CCOUT(2) << "Error: There was a serious error when initialising the resources." << std::endl;
+ // throw;
+ //}
+ }
+
+ /**
+ @brief
+ Method called by the LogListener interface from Ogre.
+ We use it to capture Ogre log messages and handle it ourselves.
+ @param message
+ The message to be logged
+ @param lml
+ The message level the log is using
+ @param maskDebug
+ If we are printing to the console or not
+ @param logName
+ The name of this log (so you can have several listeners
+ for different logs, and identify them)
+ */
+ void GraphicsManager::messageLogged(const std::string& message,
+ Ogre::LogMessageLevel lml, bool maskDebug, const std::string& logName)
+ {
+ int orxonoxLevel;
+ switch (lml)
+ {
+ case Ogre::LML_TRIVIAL:
+ orxonoxLevel = this->ogreLogLevelTrivial_;
+ break;
+ case Ogre::LML_NORMAL:
+ orxonoxLevel = this->ogreLogLevelNormal_;
+ break;
+ case Ogre::LML_CRITICAL:
+ orxonoxLevel = this->ogreLogLevelCritical_;
+ break;
+ default:
+ orxonoxLevel = 0;
+ }
+ OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
+ << "Ogre: " << message << std::endl;
+ }
+
+ void GraphicsManager::printScreen()
+ {
+ assert(this->renderWindow_);
+
+ this->renderWindow_->writeContentsToTimestampedFile(Core::getLogPathString() + "screenShot_", ".jpg");
+ }
+}
Copied: trunk/src/core/GraphicsManager.h (from rev 3367, branches/resource/src/core/GraphicsManager.h)
===================================================================
--- trunk/src/core/GraphicsManager.h (rev 0)
+++ trunk/src/core/GraphicsManager.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -0,0 +1,112 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Reto Grieder
+ * Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
+ * Co-authors:
+ * Felix Schulthess
+ *
+ */
+
+/**
+ at file
+ at brief
+ Declaration of GraphicsManager Singleton.
+ */
+
+#ifndef _GraphicsManager_H__
+#define _GraphicsManager_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include <string>
+#include <OgreLog.h>
+#include "util/Singleton.h"
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+ /**
+ @brief
+ Graphics engine manager class
+ */
+ class _CoreExport GraphicsManager : public Singleton<GraphicsManager>, public OrxonoxClass, public Ogre::LogListener
+ {
+ friend class Singleton<GraphicsManager>;
+ public:
+ GraphicsManager();
+ ~GraphicsManager();
+
+ void setConfigValues();
+
+ void update(const Clock& time);
+
+ inline Ogre::Viewport* getViewport()
+ { return this->viewport_; }
+ inline Ogre::RenderWindow* getRenderWindow()
+ { return this->renderWindow_; }
+
+ void setCamera(Ogre::Camera* camera);
+
+ private:
+ GraphicsManager(GraphicsManager&); // don't mess with singletons
+
+ // OGRE initialisation
+ void setupOgre();
+ void loadOgrePlugins();
+ void declareResources();
+ void loadRenderer();
+ void initialiseResources();
+
+ // event from Ogre::LogListener
+ void messageLogged(const std::string& message, Ogre::LogMessageLevel lml,
+ bool maskDebug, const std::string& logName);
+
+ // console commands
+ void printScreen();
+
+ private:
+ Ogre::Root* ogreRoot_; //!< Ogre's root
+ Ogre::LogManager* ogreLogger_;
+ Ogre::RenderWindow* renderWindow_; //!< the one and only render window
+ Ogre::Viewport* viewport_; //!< default full size viewport
+ OgreWindowEventListener* ogreWindowEventListener_; //!< Pimpl to hide OgreWindowUtilities.h
+
+ // config values
+ std::string resourceFile_; //!< resources file name
+ std::string ogreConfigFile_; //!< ogre config file name
+ std::string ogrePluginsFolder_; //!< Folder where the Ogre plugins are located
+ std::string ogrePlugins_; //!< Comma separated list of all plugins to load
+ std::string ogreLogFile_; //!< log file name for Ogre log messages
+ int ogreLogLevelTrivial_; //!< Corresponding Orxonx debug level for LL_TRIVIAL
+ int ogreLogLevelNormal_; //!< Corresponding Orxonx debug level for LL_NORMAL
+ int ogreLogLevelCritical_; //!< Corresponding Orxonx debug level for LL_CRITICAL
+
+ // console commands
+ ConsoleCommand* ccPrintScreen_;
+
+ static GraphicsManager* singletonPtr_s; //!< Pointer to the Singleton
+ };
+}
+
+#endif /* _GraphicsManager_H__ */
Modified: trunk/src/core/IRC.cc
===================================================================
--- trunk/src/core/IRC.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/IRC.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -56,10 +56,10 @@
try
{
- this->interpreter_->def("orxonox::irc::say", IRC::tcl_say, Tcl::variadic());
- this->interpreter_->def("orxonox::irc::privmsg", IRC::tcl_privmsg, Tcl::variadic());
- this->interpreter_->def("orxonox::irc::action", IRC::tcl_action, Tcl::variadic());
- this->interpreter_->def("orxonox::irc::info", IRC::tcl_info, Tcl::variadic());
+ this->interpreter_->def("::orxonox::irc::say", IRC::tcl_say, Tcl::variadic());
+ this->interpreter_->def("::orxonox::irc::privmsg", IRC::tcl_privmsg, Tcl::variadic());
+ this->interpreter_->def("::orxonox::irc::action", IRC::tcl_action, Tcl::variadic());
+ this->interpreter_->def("::orxonox::irc::info", IRC::tcl_info, Tcl::variadic());
}
catch (Tcl::tcl_error const &e)
{ COUT(1) << "Tcl (IRC) error: " << e.what(); }
Modified: trunk/src/core/Identifier.h
===================================================================
--- trunk/src/core/Identifier.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/Identifier.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -499,7 +499,10 @@
{
#ifdef ORXONOX_COMPILER_MSVC
typedef Loki::TypeTraits<typename Loki::TypeTraits<T>::PointeeType>::NonConstType ClassType;
- return source->template getDerivedPointer<ClassType>(ClassIdentifier<ClassType>::getIdentifier()->getClassID());
+ if (source != NULL)
+ return source->template getDerivedPointer<ClassType>(ClassIdentifier<ClassType>::getIdentifier()->getClassID());
+ else
+ return NULL;
#else
return dynamic_cast<T>(source);
#endif
Modified: trunk/src/core/Language.cc
===================================================================
--- trunk/src/core/Language.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/Language.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -88,16 +88,13 @@
// ### Language ###
// ###############################
- Language* Language::singletonRef_s = 0;
+ Language* Language::singletonPtr_s = 0;
/**
@brief Constructor: Reads the default language file and sets some values.
*/
Language::Language()
{
- assert(singletonRef_s == 0);
- singletonRef_s = this;
-
this->defaultLanguage_ = "default";
this->defaultLocalisation_ = "ERROR: LANGUAGE ENTRY DOESN'T EXIST!";
@@ -112,9 +109,6 @@
{
for (std::map<std::string, LanguageEntry*>::iterator it = this->languageEntries_.begin(); it != this->languageEntries_.end(); ++it)
delete (it->second);
-
- assert(singletonRef_s);
- singletonRef_s = 0;
}
/**
Modified: trunk/src/core/Language.h
===================================================================
--- trunk/src/core/Language.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/Language.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -36,10 +36,10 @@
Usage:
- Set the entry with the default string:
- Language::getLanguage()->addEntry("label of the entry", "the string to translate");
+ Language::getInstance()->addEntry("label of the entry", "the string to translate");
- Get the localisation of the entry in the configured language:
- std::cout << Language::getLanguage()->getLocalisation("name of the entry") << std::endl;
+ std::cout << Language::getInstance()->getLocalisation("name of the entry") << std::endl;
*/
#ifndef _Language_H__
@@ -50,12 +50,13 @@
#include <map>
#include <string>
#include <cassert>
+#include "util/Singleton.h"
#define AddLanguageEntry(label, fallbackstring) \
- orxonox::Language::getLanguage().addEntry(label, fallbackstring)
+ orxonox::Language::getInstance().addEntry(label, fallbackstring)
#define GetLocalisation(label) \
- orxonox::Language::getLanguage().getLocalisation(label)
+ orxonox::Language::getInstance().getLocalisation(label)
namespace orxonox
@@ -111,15 +112,15 @@
// ### Language ###
// ###############################
//! The Language class manges the language files and entries and stores the LanguageEntry objects in a map.
- class _CoreExport Language
+ class _CoreExport Language : public Singleton<Language>
{
+ friend class Singleton<Language>;
friend class CoreConfiguration;
public:
Language();
~Language();
- static Language& getLanguage() { assert(singletonRef_s); return *singletonRef_s; }
void addEntry(const LanguageEntryLabel& label, const std::string& entry);
const std::string& getLocalisation(const LanguageEntryLabel& label) const;
@@ -136,7 +137,7 @@
std::string defaultLocalisation_; //!< The returned string, if an entry unavailable entry is requested
std::map<std::string, LanguageEntry*> languageEntries_; //!< A map to store all LanguageEntry objects and their labels
- static Language* singletonRef_s;
+ static Language* singletonPtr_s;
};
}
Modified: trunk/src/core/Loader.cc
===================================================================
--- trunk/src/core/Loader.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/Loader.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -29,12 +29,10 @@
#include "Loader.h"
#include <tinyxml/ticpp.h>
-#include <boost/filesystem.hpp>
#include "util/Debug.h"
#include "util/Exception.h"
#include "BaseObject.h"
-#include "Core.h"
#include "Iterator.h"
#include "ObjectList.h"
#include "LuaBind.h"
@@ -209,24 +207,4 @@
Loader::unload(file, mask);
return Loader::load(file, mask);
}
-
- std::vector<std::string> Loader::getLevelList()
- {
- std::vector<std::string> levelList;
-
- boost::filesystem::directory_iterator file(Core::getMediaPathString() + "levels");
- boost::filesystem::directory_iterator end;
-
- while (file != end)
- {
- if (!boost::filesystem::is_directory(*file) && file->string()[file->string().length()-1] != '~')
- {
- std::string filename = file->path().leaf();
- if (filename.length() > 4)
- levelList.push_back(filename.substr(0,filename.length()-4));
- }
- ++file;
- }
- return levelList;
- }
}
Modified: trunk/src/core/Loader.h
===================================================================
--- trunk/src/core/Loader.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/Loader.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -55,7 +55,6 @@
static bool reload(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
static ClassTreeMask currentMask_s;
- static std::vector<std::string> getLevelList();
private:
static std::vector<std::pair<const XMLFile*, ClassTreeMask> > files_s;
Modified: trunk/src/core/LuaBind.cc
===================================================================
--- trunk/src/core/LuaBind.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/LuaBind.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -38,18 +38,14 @@
#include "util/Debug.h"
#include "util/StringUtils.h"
-#include "ToluaBindCore.h"
#include "Core.h"
namespace orxonox
{
- LuaBind* LuaBind::singletonRef_s = NULL;
+ LuaBind* LuaBind::singletonPtr_s = NULL;
LuaBind::LuaBind()
{
- assert(LuaBind::singletonRef_s == 0);
- LuaBind::singletonRef_s = this;
-
this->includePath_ = Core::getMediaPathString();
luaState_ = lua_open();
@@ -64,11 +60,19 @@
luaopen_io(luaState_);
luaopen_debug(luaState_);
#endif
- tolua_Core_open(luaState_);
+
+ // Open all available tolua interfaces
+ this->openToluaInterfaces(luaState_);
+
output_ = "";
isRunning_ = false;
}
+ LuaBind::~LuaBind()
+ {
+ this->closeToluaInterfaces(luaState_);
+ };
+
void LuaBind::luaPrint(const std::string& str)
{
output_ += str;
@@ -314,4 +318,26 @@
return output;
}
+ void LuaBind::addToluaInterface(int (*function)(lua_State*), const std::string& name)
+ {
+ toluaInterfaces_.push_back(std::make_pair(name, function));
+ // Apply changes to our own lua state as well
+ (*function)(luaState_);
+ }
+
+ void LuaBind::openToluaInterfaces(lua_State* state)
+ {
+ for (unsigned int i = 0; i < toluaInterfaces_.size(); ++i)
+ (*toluaInterfaces_[i].second)(state);
+ }
+
+ void LuaBind::closeToluaInterfaces(lua_State* state)
+ {
+ for (unsigned int i = 0; i < toluaInterfaces_.size(); ++i)
+ {
+ lua_pushnil(state);
+ lua_setglobal(state, toluaInterfaces_[i].first.c_str());
+ }
+ }
+
}
Modified: trunk/src/core/LuaBind.h
===================================================================
--- trunk/src/core/LuaBind.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/LuaBind.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -39,17 +39,21 @@
#include <cassert>
#include <string>
+#include <vector>
extern "C" {
#include <lua.h>
}
+#include "util/Singleton.h"
+
// tolua_begin
namespace orxonox
{
- class _CoreExport LuaBind
+ class _CoreExport LuaBind : public Singleton<LuaBind>
{
+// tolua_end
+ friend class Singleton<LuaBind>;
-// tolua_end
struct LoadS {
const char *s;
size_t size;
@@ -57,9 +61,9 @@
public:
LuaBind();
- inline ~LuaBind() { assert(singletonRef_s); LuaBind::singletonRef_s = NULL; };
+ ~LuaBind();
- inline static LuaBind& getInstance() { assert(singletonRef_s); return *LuaBind::singletonRef_s; } // tolua_export
+ static LuaBind& getInstance() { return Singleton<LuaBind>::getInstance(); } // tolua_export
void loadFile(const std::string& filename, bool luaTags);
void loadString(const std::string& code);
@@ -82,14 +86,19 @@
inline void setIncludePath(const std::string& includepath)
{ this->includePath_ = includepath; }
+ void addToluaInterface(int (*function)(lua_State*), const std::string& name);
+ void openToluaInterfaces(lua_State* state);
+ void closeToluaInterfaces(lua_State* state);
+
private:
- static LuaBind* singletonRef_s;
+ static LuaBind* singletonPtr_s;
std::string luaSource_;
std::string output_;
lua_State* luaState_;
bool isRunning_;
std::string includePath_;
+ std::vector<std::pair<std::string, int (*)(lua_State *L)> > toluaInterfaces_;
}; // tolua_export
} // tolua_export
Modified: trunk/src/core/Shell.cc
===================================================================
--- trunk/src/core/Shell.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/Shell.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -50,13 +50,10 @@
SetConsoleCommandShortcut(OutputHandler, info);
SetConsoleCommandShortcut(OutputHandler, debug);
- Shell* Shell::singletonRef_s = 0;
+ Shell* Shell::singletonPtr_s = 0;
Shell::Shell()
{
- assert(singletonRef_s == 0);
- singletonRef_s = this;
-
int level = Core::getSoftDebugLevel(OutputHandler::LD_Shell);
Core::setSoftDebugLevel(OutputHandler::LD_Shell, -1);
@@ -91,7 +88,6 @@
OutputHandler::getOutStream().setOutputBuffer(0);
if (this->inputBuffer_)
delete this->inputBuffer_;
- singletonRef_s = 0;
}
void Shell::setConfigValues()
Modified: trunk/src/core/Shell.h
===================================================================
--- trunk/src/core/Shell.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/Shell.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -59,14 +59,13 @@
virtual void exit() {}
};
- class _CoreExport Shell : virtual public OrxonoxClass, public OutputBufferListener
+ class _CoreExport Shell : public Singleton<Shell>, virtual public OrxonoxClass, public OutputBufferListener
{
+ friend class Singleton<Shell>;
public:
Shell();
virtual ~Shell();
- static Shell& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
-
static void clearShell();
static void history();
@@ -147,7 +146,7 @@
ConfigFileType commandHistoryConfigFileType_;
- static Shell* singletonRef_s;
+ static Shell* singletonPtr_s;
};
}
Modified: trunk/src/core/TclBind.cc
===================================================================
--- trunk/src/core/TclBind.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/TclBind.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -32,10 +32,12 @@
#include <string>
#include <cpptcl/cpptcl.h>
+#include "SpecialConfig.h"
#include "util/Debug.h"
#include "util/StringUtils.h"
#include "CommandExecutor.h"
#include "ConsoleCommand.h"
+#include "Core.h"
#include "TclThreadManager.h"
namespace orxonox
@@ -43,14 +45,12 @@
SetConsoleCommandShortcut(TclBind, tcl);
SetConsoleCommandShortcut(TclBind, bgerror);
- TclBind* TclBind::singletonRef_s = 0;
+ TclBind* TclBind::singletonPtr_s = 0;
TclBind::TclBind(const std::string& datapath)
{
- assert(singletonRef_s == 0);
- singletonRef_s = this;
this->interpreter_ = 0;
- this->bSetTclLibPath_ = false;
+ this->bSetTclDataPath_ = false;
this->setDataPath(datapath);
}
@@ -58,55 +58,82 @@
{
if (this->interpreter_)
delete this->interpreter_;
- singletonRef_s = 0;
}
void TclBind::setDataPath(const std::string& datapath)
{
// String has POSIX slashes
- this->tclLibPath_ = datapath + "tcl" + TCL_VERSION + '/';
- this->bSetTclLibPath_ = true;
+ this->tclDataPath_ = datapath + "tcl" + '/';
+ this->bSetTclDataPath_ = true;
- this->createTclInterpreter();
+ this->initializeTclInterpreter();
}
- void TclBind::createTclInterpreter()
+ void TclBind::initializeTclInterpreter()
{
- if (this->bSetTclLibPath_ && !this->interpreter_)
+ if (this->bSetTclDataPath_ && !this->interpreter_)
{
- this->interpreter_ = new Tcl::interpreter(this->tclLibPath_);
- this->interpreter_->def("orxonox::query", TclBind::tcl_query, Tcl::variadic());
- this->interpreter_->def("orxonox::crossquery", TclThreadManager::tcl_crossquery, Tcl::variadic());
+ this->interpreter_ = this->createTclInterpreter();
+
+ this->interpreter_->def("::orxonox::query", TclBind::tcl_query, Tcl::variadic());
+ this->interpreter_->def("::orxonox::crossquery", TclThreadManager::tcl_crossquery, Tcl::variadic());
this->interpreter_->def("execute", TclBind::tcl_execute, Tcl::variadic());
- this->interpreter_->def("orxonox::crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
+ this->interpreter_->def("::orxonox::crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
try
{
- this->interpreter_->eval("proc query args { orxonox::query [join $args] }");
- this->interpreter_->eval("proc crossquery {id args} { orxonox::crossquery 0 $id [join $args] }");
- this->interpreter_->eval("proc crossexecute {id args} { orxonox::crossquery 0 $id [join $args] }");
+ this->interpreter_->eval("proc query {args} { ::orxonox::query $args }");
+ this->interpreter_->eval("proc crossquery {id args} { ::orxonox::crossquery 0 $id $args }");
+ this->interpreter_->eval("proc crossexecute {id args} { ::orxonox::crossquery 0 $id $args }");
+ this->interpreter_->eval("proc running {} { return 1 }");
this->interpreter_->eval("set id 0");
- this->interpreter_->eval("rename exit tcl::exit; proc exit {} { execute exit }");
- this->interpreter_->eval("redef_puts");
+ this->interpreter_->eval("rename exit ::tcl::exit; proc exit {} { execute exit }");
}
catch (Tcl::tcl_error const &e)
{ COUT(1) << "Tcl error while creating Tcl-interpreter: " << e.what() << std::endl; }
catch (std::exception const &e)
{ COUT(1) << "Error while creating Tcl-interpreter: " << e.what() << std::endl; }
+ catch (...)
+ { COUT(1) << "Error while creating Tcl-interpreter." << std::endl; }
}
}
- void TclBind::createNewTclInterpreter()
+ Tcl::interpreter* TclBind::createTclInterpreter()
{
- if (this->interpreter_)
+ Tcl::interpreter* interpreter = new Tcl::interpreter();
+ std::string libpath = TclBind::getTclLibraryPath();
+
+ try
{
- delete this->interpreter_;
- this->interpreter_ = 0;
+ if (libpath != "")
+ interpreter->eval("set tcl_library \"" + libpath + "\"");
+
+ Tcl_Init(interpreter->get());
+
+ interpreter->eval("source \"" + TclBind::getInstance().tclDataPath_ + "/init.tcl\"");
}
+ catch (Tcl::tcl_error const &e)
+ { 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; }
+ catch (std::exception const &e)
+ { 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; }
+ catch (...)
+ { 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; }
- this->createTclInterpreter();
+ return interpreter;
}
+ std::string TclBind::getTclLibraryPath()
+ {
+#ifdef DEPENDENCY_PACKAGE_ENABLE
+ if (Core::isDevelopmentRun())
+ return (std::string(ORXONOX_DEP_LIB_PATH) + "/tcl");
+ else
+ return (Core::getRootPathString() + "lib/tcl");
+#else
+ return "";
+#endif
+ }
+
std::string TclBind::tcl_query(Tcl::object const &args)
{
COUT(4) << "Tcl_query: " << args.get() << std::endl;
@@ -141,7 +168,7 @@
{
try
{
- std::string output = TclBind::getInstance().interpreter_->eval(tclcode);
+ std::string output = TclBind::getInstance().interpreter_->eval("uplevel #0 " + tclcode);
if (output != "")
{
COUT(0) << "tcl> " << output << std::endl;
Modified: trunk/src/core/TclBind.h
===================================================================
--- trunk/src/core/TclBind.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/TclBind.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -33,24 +33,26 @@
#include <cassert>
#include <string>
+#include "util/Singleton.h"
namespace orxonox
{
- class _CoreExport TclBind
+ class _CoreExport TclBind : public Singleton<TclBind>
{
+ friend class Singleton<TclBind>;
public:
TclBind(const std::string& datapath);
~TclBind();
- static TclBind& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
-
static std::string tcl(const std::string& tclcode);
static void bgerror(std::string error);
void setDataPath(const std::string& datapath);
- std::string getTclLibPath() const { return this->tclLibPath_; }
- void createTclInterpreter();
- void createNewTclInterpreter();
+ const std::string& getTclDataPath() const { return this->tclDataPath_; }
+ static std::string getTclLibraryPath();
+
+ void initializeTclInterpreter();
+ static Tcl::interpreter* createTclInterpreter();
Tcl::interpreter* getTclInterpreter() const { return this->interpreter_; }
static std::string tcl_query(Tcl::object const &args);
@@ -62,10 +64,10 @@
TclBind(const TclBind& other);
Tcl::interpreter* interpreter_;
- std::string tclLibPath_;
- bool bSetTclLibPath_;
+ std::string tclDataPath_;
+ bool bSetTclDataPath_;
- static TclBind* singletonRef_s;
+ static TclBind* singletonPtr_s;
};
}
Modified: trunk/src/core/TclThreadManager.cc
===================================================================
--- trunk/src/core/TclThreadManager.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/TclThreadManager.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -53,6 +53,7 @@
SetConsoleCommand(TclThreadManager, destroy, false).argumentCompleter(0, autocompletion::tclthreads());
SetConsoleCommand(TclThreadManager, execute, false).argumentCompleter(0, autocompletion::tclthreads());
SetConsoleCommand(TclThreadManager, query, false).argumentCompleter(0, autocompletion::tclthreads());
+ SetConsoleCommand(TclThreadManager, source, false).argumentCompleter(0, autocompletion::tclthreads());
/**
@brief A struct containing all informations about a Tcl-interpreter
@@ -89,9 +90,6 @@
{
RegisterRootObject(TclThreadManager);
- assert(TclThreadManager::singletonPtr_s == 0);
- TclThreadManager::singletonPtr_s = this;
-
this->numInterpreterBundles_ = 0;
this->interpreterBundlesMutex_ = new boost::shared_mutex();
@@ -114,8 +112,6 @@
*/
TclThreadManager::~TclThreadManager()
{
- TclThreadManager::singletonPtr_s = 0;
-
delete this->interpreterBundlesMutex_;
// delete this->mainInterpreterMutex_; // <-- temporary disabled to avoid crash if a thread is still actively queriyng
delete this->messageQueue_;
@@ -239,55 +235,59 @@
{
TclInterpreterBundle* newbundle = new TclInterpreterBundle();
newbundle->id_ = id;
- newbundle->interpreter_ = new Tcl::interpreter(TclBind::getInstance().getTclLibPath());
+ newbundle->interpreter_ = TclBind::createTclInterpreter();
+ TclThreadManager::initialize(newbundle);
+
+ {
+ // Add the new bundle to the map
+ boost::unique_lock<boost::shared_mutex> lock(*TclThreadManager::getInstance().interpreterBundlesMutex_);
+ TclThreadManager::getInstance().interpreterBundles_[id] = newbundle;
+ }
+
+ return newbundle->interpreter_;
+ }
+
+ void TclThreadManager::initialize(TclInterpreterBundle* bundle)
+ {
+ std::string id_string = getConvertedValue<unsigned int, std::string>(bundle->id_);
+
// Initialize the new interpreter
try
{
- std::string id_string = getConvertedValue<unsigned int, std::string>(id);
-
// Define the functions which are implemented in C++
- newbundle->interpreter_->def("orxonox::execute", TclThreadManager::tcl_execute, Tcl::variadic());
- newbundle->interpreter_->def("orxonox::crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
- newbundle->interpreter_->def("orxonox::query", TclThreadManager::tcl_query, Tcl::variadic());
- newbundle->interpreter_->def("orxonox::crossquery", TclThreadManager::tcl_crossquery, Tcl::variadic());
- newbundle->interpreter_->def("orxonox::running", TclThreadManager::tcl_running);
+ bundle->interpreter_->def("::orxonox::execute", TclThreadManager::tcl_execute, Tcl::variadic());
+ bundle->interpreter_->def("::orxonox::crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
+ bundle->interpreter_->def("::orxonox::query", TclThreadManager::tcl_query, Tcl::variadic());
+ bundle->interpreter_->def("::orxonox::crossquery", TclThreadManager::tcl_crossquery, Tcl::variadic());
+ bundle->interpreter_->def("::orxonox::running", TclThreadManager::tcl_running);
// Create threadspecific shortcuts for the functions above
- newbundle->interpreter_->def("execute", TclThreadManager::tcl_execute, Tcl::variadic());
- newbundle->interpreter_->def("crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
- newbundle->interpreter_->eval("proc query args { orxonox::query " + id_string + " $args }");
- newbundle->interpreter_->eval("proc crossquery {id args} { orxonox::crossquery " + id_string + " $id $args }");
+ bundle->interpreter_->def("execute", TclThreadManager::tcl_execute, Tcl::variadic());
+ bundle->interpreter_->def("crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
+ bundle->interpreter_->eval("proc query {args} { ::orxonox::query " + id_string + " $args }");
+ bundle->interpreter_->eval("proc crossquery {id args} { ::orxonox::crossquery " + id_string + " $id $args }");
+ bundle->interpreter_->eval("proc running {} { return [::orxonox::running " + id_string + "] }");
// Define a variable containing the thread id
- newbundle->interpreter_->eval("set id " + id_string);
+ bundle->interpreter_->eval("set id " + id_string);
// Use our own exit function to avoid shutting down the whole program instead of just the interpreter
- newbundle->interpreter_->eval("rename exit tcl::exit");
- newbundle->interpreter_->eval("proc exit {} { execute TclThreadManager destroy " + id_string + " }");
+ bundle->interpreter_->eval("rename exit ::tcl::exit");
+ bundle->interpreter_->eval("proc exit {} { execute TclThreadManager destroy " + id_string + " }");
// Redefine some native functions
- newbundle->interpreter_->eval("redef_puts");
-
-// newbundle->interpreter_->eval("rename while tcl::while");
-// newbundle->interpreter_->eval("proc while {test command} { tcl::while {[uplevel 1 expr $test]} {uplevel 1 $command} }"); // (\"$test\" && [orxonox::running " + id + "]])
-// newbundle->interpreter_->eval("rename for tcl::for");
-// newbundle->interpreter_->eval("proc for {start test next command} { uplevel tcl::for \"$start\" \"$test\" \"$next\" \"$command\" }");
+ bundle->interpreter_->eval("rename while ::tcl::while");
+ bundle->interpreter_->eval("rename ::orxonox::while while");
+ bundle->interpreter_->eval("rename for ::tcl::for");
+ bundle->interpreter_->eval("rename ::orxonox::for for");
}
catch (const Tcl::tcl_error& e)
- { newbundle->interpreter_ = 0; COUT(1) << "Tcl error while creating Tcl-interpreter (" << id << "): " << e.what() << std::endl; }
+ { bundle->interpreter_ = 0; COUT(1) << "Tcl error while creating Tcl-interpreter (" << id_string << "): " << e.what() << std::endl; }
catch (const std::exception& e)
- { newbundle->interpreter_ = 0; COUT(1) << "Error while creating Tcl-interpreter (" << id << "): " << e.what() << std::endl; }
+ { bundle->interpreter_ = 0; COUT(1) << "Error while creating Tcl-interpreter (" << id_string << "): " << e.what() << std::endl; }
catch (...)
- { newbundle->interpreter_ = 0; COUT(1) << "An error occurred while creating a new Tcl-interpreter (" << id << ")" << std::endl; }
-
- {
- // Add the new bundle to the map
- boost::unique_lock<boost::shared_mutex> lock(*TclThreadManager::getInstance().interpreterBundlesMutex_);
- TclThreadManager::getInstance().interpreterBundles_[id] = newbundle;
- }
-
- return newbundle->interpreter_;
+ { bundle->interpreter_ = 0; COUT(1) << "An error occurred while creating a new Tcl-interpreter (" << id_string << ")" << std::endl; }
}
/**
@@ -297,6 +297,11 @@
{
// TODO
// Not yet implemented
+ TclInterpreterBundle* bundle = TclThreadManager::getInstance().getInterpreterBundle(id);
+ if (bundle)
+ {
+ bundle->bRunning_ = false;
+ }
}
/**
@@ -398,7 +403,7 @@
if ((source_bundle->id_ == target_bundle->id_) || source_bundle->queriers_.is_in(target_bundle->id_))
{
// This query would lead to a deadlock - return with an error
- this->error("Error: Circular query (" + this->dumpList(source_bundle->queriers_.getList()) + " " + getConvertedValue<unsigned int, std::string>(source_bundle->id_) \
+ TclThreadManager::error("Error: Circular query (" + this->dumpList(source_bundle->queriers_.getList()) + " " + getConvertedValue<unsigned int, std::string>(source_bundle->id_) \
+ " -> " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) \
+ "), couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) \
+ " from other interpreter with ID " + getConvertedValue<unsigned int, std::string>(source_bundle->id_) + ".");
@@ -434,9 +439,9 @@
if (target_bundle->id_ == 0 && bUseCommandExecutor)
{
// It's a query to the CommandExecutor
- this->debug("TclThread_query -> CE: " + command);
+ TclThreadManager::debug("TclThread_query -> CE: " + command);
if (!CommandExecutor::execute(command, false))
- this->error("Error: Can't execute command \"" + command + "\"!");
+ TclThreadManager::error("Error: Can't execute command \"" + command + "\"!");
if (CommandExecutor::getLastEvaluation().hasReturnvalue())
output = CommandExecutor::getLastEvaluation().getReturnvalue().getString();
@@ -444,9 +449,9 @@
else
{
// It's a query to a Tcl interpreter
- this->debug("TclThread_query: " + command);
+ TclThreadManager::debug("TclThread_query: " + command);
- output = this->eval(target_bundle, command);
+ output = TclThreadManager::eval(target_bundle, command, "query");
}
// Clear the queriers list of the target
@@ -463,7 +468,7 @@
{
// This happens if the main thread tries to query a busy interpreter
// To avoid a lock of the main thread, we simply don't proceed with the query in this case
- this->error("Error: Couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) + ", interpreter is busy right now.");
+ TclThreadManager::error("Error: Couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) + ", interpreter is busy right now.");
}
}
@@ -473,6 +478,14 @@
}
/**
+ @brief Creates a non-interactive Tcl-interpreter which executes a file.
+ */
+ void TclThreadManager::source(const std::string& file)
+ {
+ boost::thread(boost::bind(&sourceThread, file));
+ }
+
+ /**
@brief This function can be called from Tcl to ask if the thread is still suposed to be running.
@param id The id of the thread in question
*/
@@ -501,7 +514,7 @@
}
else
{
- this->error("Error: No Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(id) + " existing.");
+ TclThreadManager::error("Error: No Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(id) + " existing.");
return 0;
}
}
@@ -543,7 +556,7 @@
*/
void TclThreadManager::error(const std::string& error)
{
- this->messageQueue_->push_back("error " + error);
+ TclThreadManager::getInstance().messageQueue_->push_back("error " + error);
}
/**
@@ -551,7 +564,7 @@
*/
void TclThreadManager::debug(const std::string& error)
{
- this->messageQueue_->push_back("debug " + error);
+ TclThreadManager::getInstance().messageQueue_->push_back("debug " + error);
}
/**
@@ -560,7 +573,7 @@
Errors are reported through the @ref error function.
*/
- std::string TclThreadManager::eval(TclInterpreterBundle* bundle, const std::string& command)
+ std::string TclThreadManager::eval(TclInterpreterBundle* bundle, const std::string& command, const std::string& action)
{
Tcl_Interp* interpreter = bundle->interpreter_->get();
int cc = Tcl_Eval(interpreter, command.c_str());
@@ -569,7 +582,7 @@
if (cc != TCL_OK)
{
- this->error("Tcl error (execute, ID " + getConvertedValue<unsigned int, std::string>(bundle->id_) + "): " + static_cast<std::string>(result));
+ TclThreadManager::error("Tcl error (" + action + ", ID " + getConvertedValue<unsigned int, std::string>(bundle->id_) + "): " + static_cast<std::string>(result));
return "";
}
else
@@ -589,10 +602,71 @@
*/
void tclThread(TclInterpreterBundle* bundle, std::string command)
{
- TclThreadManager::getInstance().debug("TclThread_execute: " + command);
+ TclThreadManager::debug("TclThread_execute: " + command);
- TclThreadManager::getInstance().eval(bundle, command);
+ TclThreadManager::eval(bundle, command, "execute");
bundle->lock_->unlock();
}
+
+ /**
+ @brief The main function of a non-interactive source thread. Executes the file.
+ @param file The name of the file that should be executed by the non-interactive interpreter.
+ */
+ void sourceThread(std::string file)
+ {
+ TclThreadManager::debug("TclThread_source: " + file);
+
+ // Prepare the command-line arguments
+ const int argc = 2;
+ char* argv[argc];
+ argv[0] = "tclthread";
+ argv[1] = const_cast<char*>(file.c_str());
+
+ // Start the Tcl-command Tcl_Main with the Tcl_OrxonoxAppInit hook
+ Tcl_Main(argc, argv, Tcl_OrxonoxAppInit);
+
+// Tcl::object object(file);
+// int cc = Tcl_FSEvalFile(bundle->interpreter_->get(), object.get_object());
+// Tcl::details::result result(bundle->interpreter_->get());
+// if (cc != TCL_OK)
+// TclThreadManager::error("Tcl error (source, ID " + getConvertedValue<unsigned int, std::string>(bundle->id_) + "): " + static_cast<std::string>(result));
+//
+// // Unlock the mutex
+// bundle->lock_->unlock();
+ }
+
+ /**
+ @brief A tcl-init hook to inject the non-interactive Tcl-interpreter into the TclThreadManager.
+ */
+ int Tcl_OrxonoxAppInit(Tcl_Interp* interp)
+ {
+ // Create a new interpreter bundle
+ unsigned int id = TclThreadManager::create();
+ TclInterpreterBundle* bundle = TclThreadManager::getInstance().getInterpreterBundle(id);
+
+ // Replace the default interpreter in the bundle with the non-interactive one (passed as an argument to this function)
+ if (bundle->interpreter_)
+ delete bundle->interpreter_;
+ bundle->interpreter_ = new Tcl::interpreter(interp, true);
+
+ // Initialize the non-interactive interpreter (like in @ref TclBind::createTclInterpreter but exception safe)
+ std::string libpath = TclBind::getTclLibraryPath();
+ if (libpath != "")
+ TclThreadManager::eval(bundle, "set tcl_library \"" + libpath + "\"", "source");
+ int cc = Tcl_Init(interp);
+ TclThreadManager::eval(bundle, "source \"" + TclBind::getInstance().getTclDataPath() + "/init.tcl\"", "source");
+
+ // Initialize the non-interactive interpreter also with the thread-specific stuff
+ TclThreadManager::initialize(bundle);
+
+ // Lock the mutex (this will be locked until the thread finishes - no chance to interact with the interpreter)
+ bundle->lock_->lock();
+
+ // Return to Tcl_Main
+ if (!bundle->interpreter_)
+ return TCL_ERROR;
+ else
+ return cc;
+ }
}
Modified: trunk/src/core/TclThreadManager.h
===================================================================
--- trunk/src/core/TclThreadManager.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/TclThreadManager.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -32,32 +32,38 @@
#include "CorePrereqs.h"
#include <cassert>
+#include <list>
#include <map>
#include <string>
+#include "util/Singleton.h"
#include "OrxonoxClass.h"
+struct Tcl_Interp;
+
namespace orxonox
{
- class _CoreExport TclThreadManager : public OrxonoxClass
+ class _CoreExport TclThreadManager : public Singleton<TclThreadManager>, public OrxonoxClass
{
+ friend class Singleton<TclThreadManager>;
friend class TclBind;
friend _CoreExport void tclThread(TclInterpreterBundle* bundle, std::string command);
+ friend _CoreExport void sourceThread(std::string file);
+ friend _CoreExport int Tcl_OrxonoxAppInit(Tcl_Interp* interp);
public:
TclThreadManager(Tcl::interpreter* interpreter);
virtual ~TclThreadManager();
- static TclThreadManager& getInstance() { assert(TclThreadManager::singletonPtr_s); return *TclThreadManager::singletonPtr_s; }
-
static unsigned int create();
static Tcl::interpreter* createWithId(unsigned int id);
static void destroy(unsigned int id);
static void execute(unsigned int target_id, const std::string& command);
static std::string query(unsigned int target_id, const std::string& command);
+ static void source(const std::string& file);
- void error(const std::string& error);
- void debug(const std::string& error);
+ static void error(const std::string& error);
+ static void debug(const std::string& error);
void update(const Clock& time);
@@ -76,7 +82,8 @@
TclInterpreterBundle* getInterpreterBundle(unsigned int id);
std::string dumpList(const std::list<unsigned int>& list);
- std::string eval(TclInterpreterBundle* bundle, const std::string& command);
+ static void initialize(TclInterpreterBundle* bundle);
+ static std::string eval(TclInterpreterBundle* bundle, const std::string& command, const std::string& action);
static TclThreadManager* singletonPtr_s; ///< Singleton pointer
@@ -88,6 +95,8 @@
};
_CoreExport void tclThread(TclInterpreterBundle* bundle, std::string command);
+ _CoreExport void sourceThread(std::string file);
+ _CoreExport int Tcl_OrxonoxAppInit(Tcl_Interp* interp);
}
#endif /* _TclThreadManager_H__ */
Modified: trunk/src/core/input/InputManager.cc
===================================================================
--- trunk/src/core/input/InputManager.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/input/InputManager.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -63,7 +63,7 @@
// Abuse of this source file for the InputHandler
InputHandler InputHandler::EMPTY;
- InputManager* InputManager::singletonRef_s = 0;
+ InputManager* InputManager::singletonPtr_s = 0;
//! Defines the |= operator for easier use.
inline InputManager::State operator|=(InputManager::State& lval, InputManager::State rval)
@@ -92,9 +92,6 @@
{
RegisterRootObject(InputManager);
- assert(singletonRef_s == 0);
- singletonRef_s = this;
-
CCOUT(4) << "Constructing..." << std::endl;
this->setConfigValues();
@@ -137,8 +134,8 @@
this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "reload"), false);
}
- internalState_ = Nothing;
CCOUT(4) << "Construction complete." << std::endl;
+ internalState_ = Nothing;
}
void InputManager::setConfigValues()
@@ -296,7 +293,6 @@
this->destroyDevices();
CCOUT(4) << "Destruction complete." << std::endl;
- singletonRef_s = 0;
}
/**
Modified: trunk/src/core/input/InputManager.h
===================================================================
--- trunk/src/core/input/InputManager.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/core/input/InputManager.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -36,6 +36,7 @@
#include <string>
#include <vector>
+#include "util/Singleton.h"
#include "core/WindowEventListener.h"
#include "InputState.h"
@@ -61,8 +62,9 @@
- Keyboard construction is mandatory , mouse and joy sticks are not.
If the OIS::InputManager or the Keyboard fail, an exception is thrown.
*/
- class _CoreExport InputManager : public WindowEventListener
+ class _CoreExport InputManager : public Singleton<InputManager>, public WindowEventListener
{
+ friend class Singleton<InputManager>;
public:
//! Represents internal states of the InputManager.
enum State
@@ -167,9 +169,6 @@
OIS::InputManager* getOISInputManager()
{ return this->oisInputManager_; }
- //! Returns a reference to the singleton instance
- static InputManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
-
private: // functions
// don't mess with a Singleton
InputManager(const InputManager&);
@@ -210,7 +209,7 @@
std::set<InputState*> stateLeaveRequests_; //!< Requests to leave a running state
std::set<InputState*> stateDestroyRequests_; //!< Requests to destroy a state
- static InputManager* singletonRef_s; //!< Pointer reference to the singleton
+ static InputManager* singletonPtr_s; //!< Pointer reference to the singleton
};
}
Modified: trunk/src/cpptcl/changes_orxonox.diff
===================================================================
--- trunk/src/cpptcl/changes_orxonox.diff 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/cpptcl/changes_orxonox.diff 2009-07-30 12:10:44 UTC (rev 3370)
@@ -27,32 +27,3 @@
{
Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE);
return TCL_ERROR;
-@@ -858,6 +858,18 @@
- owner_ = true;
- }
-
-+interpreter::interpreter(string const &libpath)
-+{
-+ interp_ = Tcl_CreateInterp();
-+ owner_ = true;
-+
-+ try
-+ {
-+ this->eval("set tcl_library \"" + libpath + "\"");
-+ Tcl_Init(this->interp_);
-+ } catch (...) {}
-+}
-+
- interpreter::interpreter(Tcl_Interp *interp, bool owner)
- {
- interp_ = interp;
---- cpptcl.h Wed Jan 28 20:56:11 2009
-+++ cpptcl.h Sat Jan 24 12:52:54 2009
-@@ -467,6 +467,7 @@
- {
- public:
- interpreter();
-+ interpreter(std::string const &libpath);
- interpreter(Tcl_Interp *, bool owner = true);
- ~interpreter();
-
Modified: trunk/src/cpptcl/cpptcl.cc
===================================================================
--- trunk/src/cpptcl/cpptcl.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/cpptcl/cpptcl.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -858,18 +858,6 @@
owner_ = true;
}
-interpreter::interpreter(string const &libpath)
-{
- interp_ = Tcl_CreateInterp();
- owner_ = true;
-
- try
- {
- this->eval("set tcl_library \"" + libpath + "\"");
- Tcl_Init(this->interp_);
- } catch (...) {}
-}
-
interpreter::interpreter(Tcl_Interp *interp, bool owner)
{
interp_ = interp;
Modified: trunk/src/cpptcl/cpptcl.h
===================================================================
--- trunk/src/cpptcl/cpptcl.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/cpptcl/cpptcl.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -467,7 +467,6 @@
{
public:
interpreter();
- interpreter(std::string const &libpath);
interpreter(Tcl_Interp *, bool owner = true);
~interpreter();
Modified: trunk/src/orxonox/CMakeLists.txt
===================================================================
--- trunk/src/orxonox/CMakeLists.txt 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/CMakeLists.txt 2009-07-30 12:10:44 UTC (rev 3370)
@@ -19,14 +19,12 @@
SET_SOURCE_FILES(ORXONOX_SRC_FILES
CameraManager.cc
- GraphicsManager.cc
LevelManager.cc
Main.cc
PawnManager.cc
PlayerManager.cc
)
ADD_SUBDIRECTORY(gamestates)
-ADD_SUBDIRECTORY(gui)
ADD_SUBDIRECTORY(interfaces)
ADD_SUBDIRECTORY(objects)
ADD_SUBDIRECTORY(overlays)
@@ -42,7 +40,6 @@
FIND_HEADER_FILES
TOLUA_FILES
LevelManager.h
- gui/GUIManager.h
objects/pickup/BaseItem.h
objects/pickup/PickupInventory.h
objects/quest/QuestDescription.h
@@ -52,17 +49,16 @@
# When defined as WIN32 this removes the console window on Windows
${ORXONOX_WIN32}
LINK_LIBRARIES
+ ${Boost_FILESYSTEM_LIBRARY}
+ ${Boost_SYSTEM_LIBRARY} # Filesystem dependency
+ ${Boost_THREAD_LIBRARY}
+ ${Boost_DATE_TIME_LIBRARY} # Thread dependency
${OGRE_LIBRARY}
- ${CEGUI_LIBRARY}
- ${LUA_LIBRARIES}
- ${CEGUILUA_LIBRARY}
- ${Boost_SYSTEM_LIBRARY}
${OPENAL_LIBRARY}
${ALUT_LIBRARY}
${VORBISFILE_LIBRARY}
${VORBIS_LIBRARY}
${OGG_LIBRARY}
- ogreceguirenderer_orxonox
tinyxml++_orxonox
tolua++_orxonox
bullet_orxonox
Modified: trunk/src/orxonox/CameraManager.cc
===================================================================
--- trunk/src/orxonox/CameraManager.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/CameraManager.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -33,30 +33,24 @@
#include "util/StringUtils.h"
#include "core/GameMode.h"
+#include "core/GUIManager.h"
#include "core/ObjectList.h"
#include "tools/Shader.h"
#include "objects/worldentities/Camera.h"
#include "objects/Scene.h"
-#include "gui/GUIManager.h"
namespace orxonox
{
- CameraManager* CameraManager::singletonRef_s = 0;
+ CameraManager* CameraManager::singletonPtr_s = 0;
CameraManager::CameraManager(Ogre::Viewport* viewport)
: viewport_(viewport)
{
- assert(singletonRef_s == 0);
- singletonRef_s = this;
-
this->fallbackCamera_ = 0;
}
CameraManager::~CameraManager()
{
- assert(singletonRef_s != 0);
- singletonRef_s = 0;
-
if (this->fallbackCamera_)
this->fallbackCamera_->getSceneManager()->destroyCamera(this->fallbackCamera_);
}
Modified: trunk/src/orxonox/CameraManager.h
===================================================================
--- trunk/src/orxonox/CameraManager.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/CameraManager.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -40,11 +40,13 @@
#include <cassert>
#include <list>
#include "util/OgreForwardRefs.h"
+#include "util/Singleton.h"
namespace orxonox
{
- class _OrxonoxExport CameraManager
+ class _OrxonoxExport CameraManager : public Singleton<CameraManager>
{
+ friend class Singleton<CameraManager>;
public:
CameraManager(Ogre::Viewport* viewport);
~CameraManager();
@@ -56,8 +58,7 @@
void useCamera(Ogre::Camera* camera);
- static CameraManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
- static CameraManager* getInstancePtr() { return singletonRef_s; }
+ static CameraManager* getInstancePtr() { return singletonPtr_s; }
private:
CameraManager(const CameraManager&); // don't use
@@ -66,7 +67,7 @@
Ogre::Viewport* viewport_;
Ogre::Camera* fallbackCamera_;
- static CameraManager* singletonRef_s;
+ static CameraManager* singletonPtr_s;
};
}
Deleted: trunk/src/orxonox/GraphicsManager.cc
===================================================================
--- trunk/src/orxonox/GraphicsManager.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/GraphicsManager.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -1,426 +0,0 @@
-/*
- * ORXONOX - the hottest 3D action shooter ever to exist
- * > www.orxonox.net <
- *
- *
- * License notice:
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Author:
- * Reto Grieder
- * Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
- * Co-authors:
- * Felix Schulthess
- *
- */
-
-/**
- at file
- at brief
- Implementation of an partial interface to Ogre.
-*/
-
-#include "GraphicsManager.h"
-
-#include <fstream>
-#include <boost/filesystem.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include <OgreCompositorManager.h>
-#include <OgreConfigFile.h>
-#include <OgreFrameListener.h>
-#include <OgreRoot.h>
-#include <OgreLogManager.h>
-#include <OgreException.h>
-#include <OgreRenderWindow.h>
-#include <OgreRenderSystem.h>
-#include <OgreTextureManager.h>
-#include <OgreViewport.h>
-#include <OgreWindowEventUtilities.h>
-
-#include "SpecialConfig.h"
-#include "util/Exception.h"
-#include "util/StringUtils.h"
-#include "util/SubString.h"
-#include "core/Clock.h"
-#include "core/ConsoleCommand.h"
-#include "core/ConfigValueIncludes.h"
-#include "core/CoreIncludes.h"
-#include "core/Core.h"
-#include "core/Game.h"
-#include "core/GameMode.h"
-#include "core/WindowEventListener.h"
-#include "tools/ParticleInterface.h"
-
-// HACK!
-#include "overlays/map/Map.h"
-
-namespace orxonox
-{
- using boost::shared_ptr;
-
- class OgreWindowEventListener : public Ogre::WindowEventListener
- {
- public:
- void windowResized (Ogre::RenderWindow* rw)
- { orxonox::WindowEventListener::resizeWindow(rw->getWidth(), rw->getHeight()); }
- void windowFocusChange (Ogre::RenderWindow* rw)
- { orxonox::WindowEventListener::changeWindowFocus(); }
- void windowClosed (Ogre::RenderWindow* rw)
- { orxonox::Game::getInstance().stop(); }
- void windowMoved (Ogre::RenderWindow* rw)
- { orxonox::WindowEventListener::moveWindow(); }
- };
-
- GraphicsManager* GraphicsManager::singletonRef_s = 0;
-
- /**
- @brief
- Non-initialising constructor.
- */
- GraphicsManager::GraphicsManager()
- : ogreRoot_(0)
- , ogreLogger_(0)
- , renderWindow_(0)
- , viewport_(0)
- , ogreWindowEventListener_(new OgreWindowEventListener())
- {
- RegisterObject(GraphicsManager);
-
- assert(singletonRef_s == 0);
- singletonRef_s = this;
-
- this->setConfigValues();
-
- // Ogre setup procedure
- setupOgre();
-
- try
- {
- // load all the required plugins for Ogre
- loadOgrePlugins();
- // read resource declaration file
- this->declareResources();
- // Reads ogre config and creates the render window
- this->loadRenderer();
-
- // TODO: Spread this
- this->initialiseResources();
-
- // add console commands
- FunctorMember<GraphicsManager>* functor1 = createFunctor(&GraphicsManager::printScreen);
- functor1->setObject(this);
- ccPrintScreen_ = createConsoleCommand(functor1, "printScreen");
- CommandExecutor::addConsoleCommandShortcut(ccPrintScreen_);
- }
- catch (...)
- {
- // clean up
- delete this->ogreRoot_;
- delete this->ogreLogger_;
- delete this->ogreWindowEventListener_;
- throw;
- }
- }
-
- /**
- @brief
- Destroys all the Ogre related objects
- */
- GraphicsManager::~GraphicsManager()
- {
-/*
- delete this->ccPrintScreen_;
-*/
-
- // HACK! This fixes an exit crash
- Map::hackDestroyMap();
- // unload all compositors (this is only necessary because we don't yet destroy all resources!)
- Ogre::CompositorManager::getSingleton().removeAll();
-
- // Delete OGRE main control organ
- delete this->ogreRoot_;
-
- // delete the logManager (since we have created it in the first place).
- delete this->ogreLogger_;
-
- delete this->ogreWindowEventListener_;
-
- assert(singletonRef_s);
- singletonRef_s = 0;
- }
-
- void GraphicsManager::setConfigValues()
- {
- SetConfigValue(resourceFile_, "resources.cfg")
- .description("Location of the resources file in the data path.");
- SetConfigValue(ogreConfigFile_, "ogre.cfg")
- .description("Location of the Ogre config file");
- SetConfigValue(ogrePluginsFolder_, ORXONOX_OGRE_PLUGINS_FOLDER)
- .description("Folder where the Ogre plugins are located.");
- SetConfigValue(ogrePlugins_, ORXONOX_OGRE_PLUGINS)
- .description("Comma separated list of all plugins to load.");
- SetConfigValue(ogreLogFile_, "ogre.log")
- .description("Logfile for messages from Ogre. Use \"\" to suppress log file creation.");
- SetConfigValue(ogreLogLevelTrivial_ , 5)
- .description("Corresponding orxonox debug level for ogre Trivial");
- SetConfigValue(ogreLogLevelNormal_ , 4)
- .description("Corresponding orxonox debug level for ogre Normal");
- SetConfigValue(ogreLogLevelCritical_, 2)
- .description("Corresponding orxonox debug level for ogre Critical");
- SetConfigValue(detailLevelParticle_, 2)
- .description("O: off, 1: low, 2: normal, 3: high").callback(this, &GraphicsManager::detailLevelParticleChanged);
- }
-
- void GraphicsManager::detailLevelParticleChanged()
- {
- for (ObjectList<ParticleInterface>::iterator it = ObjectList<ParticleInterface>::begin(); it; ++it)
- it->detailLevelChanged(this->detailLevelParticle_);
- }
-
- void GraphicsManager::update(const Clock& time)
- {
- Ogre::FrameEvent evt;
- evt.timeSinceLastFrame = time.getDeltaTime();
- evt.timeSinceLastEvent = time.getDeltaTime(); // note: same time, but shouldn't matter anyway
-
- // don't forget to call _fireFrameStarted to OGRE to make sure
- // everything goes smoothly
- ogreRoot_->_fireFrameStarted(evt);
-
- // Pump messages in all registered RenderWindows
- // This calls the WindowEventListener objects.
- Ogre::WindowEventUtilities::messagePump();
- // make sure the window stays active even when not focused
- // (probably only necessary on windows)
- this->renderWindow_->setActive(true);
-
- // render
- ogreRoot_->_updateAllRenderTargets();
-
- // again, just to be sure OGRE works fine
- ogreRoot_->_fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
- }
-
- void GraphicsManager::setCamera(Ogre::Camera* camera)
- {
- this->viewport_->setCamera(camera);
- }
-
- /**
- @brief
- Creates the Ogre Root object and sets up the ogre log.
- */
- void GraphicsManager::setupOgre()
- {
- COUT(3) << "Setting up Ogre..." << std::endl;
-
- if (ogreConfigFile_ == "")
- {
- COUT(2) << "Warning: Ogre config file set to \"\". Defaulting to config.cfg" << std::endl;
- ModifyConfigValue(ogreConfigFile_, tset, "config.cfg");
- }
- if (ogreLogFile_ == "")
- {
- COUT(2) << "Warning: Ogre log file set to \"\". Defaulting to ogre.log" << std::endl;
- ModifyConfigValue(ogreLogFile_, tset, "ogre.log");
- }
-
- boost::filesystem::path ogreConfigFilepath(Core::getConfigPath() / this->ogreConfigFile_);
- boost::filesystem::path ogreLogFilepath(Core::getLogPath() / this->ogreLogFile_);
-
- // create a new logManager
- // Ogre::Root will detect that we've already created a Log
- std::auto_ptr<Ogre::LogManager> logger(new Ogre::LogManager());
- COUT(4) << "Ogre LogManager created" << std::endl;
-
- // create our own log that we can listen to
- Ogre::Log *myLog;
- myLog = logger->createLog(ogreLogFilepath.string(), true, false, false);
- COUT(4) << "Ogre Log created" << std::endl;
-
- myLog->setLogDetail(Ogre::LL_BOREME);
- myLog->addListener(this);
-
- COUT(4) << "Creating Ogre Root..." << std::endl;
-
- // check for config file existence because Ogre displays (caught) exceptions if not
- if (!boost::filesystem::exists(ogreConfigFilepath))
- {
- // create a zero sized file
- std::ofstream creator;
- creator.open(ogreConfigFilepath.string().c_str());
- creator.close();
- }
-
- // Leave plugins file empty. We're going to do that part manually later
- ogreRoot_ = new Ogre::Root("", ogreConfigFilepath.string(), ogreLogFilepath.string());
- // In case that new Root failed the logger gets destroyed because of the std::auto_ptr
- ogreLogger_ = logger.release();
-
- COUT(3) << "Ogre set up done." << std::endl;
- }
-
- void GraphicsManager::loadOgrePlugins()
- {
- // just to make sure the next statement doesn't segfault
- if (ogrePluginsFolder_ == "")
- ogrePluginsFolder_ = ".";
-
- boost::filesystem::path folder(ogrePluginsFolder_);
- // Do some SubString magic to get the comma separated list of plugins
- SubString plugins(ogrePlugins_, ",", " ", false, '\\', false, '"', false, '(', ')', false, '\0');
- // Use backslash paths on Windows! file_string() already does that though.
- for (unsigned int i = 0; i < plugins.size(); ++i)
- ogreRoot_->loadPlugin((folder / plugins[i]).file_string());
- }
-
- void GraphicsManager::declareResources()
- {
- CCOUT(4) << "Declaring Resources" << std::endl;
- //TODO: Specify layout of data file and maybe use xml-loader
- //TODO: Work with ressource groups (should be generated by a special loader)
-
- if (resourceFile_ == "")
- {
- COUT(2) << "Warning: Ogre resource file set to \"\". Defaulting to resources.cfg" << std::endl;
- ModifyConfigValue(resourceFile_, tset, "resources.cfg");
- }
-
- // Load resource paths from data file using configfile ressource type
- Ogre::ConfigFile cf;
- try
- {
- cf.load((Core::getMediaPath() / resourceFile_).string());
- }
- catch (...)
- {
- //COUT(1) << ex.getFullDescription() << std::endl;
- COUT(0) << "Have you forgotten to set the data path in orxnox.ini?" << std::endl;
- throw;
- }
-
- // Go through all sections & settings in the file
- Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
-
- std::string secName, typeName, archName;
- while (seci.hasMoreElements())
- {
- try
- {
- secName = seci.peekNextKey();
- Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
- Ogre::ConfigFile::SettingsMultiMap::iterator i;
- for (i = settings->begin(); i != settings->end(); ++i)
- {
- typeName = i->first; // for instance "FileSystem" or "Zip"
- archName = i->second; // name (and location) of archive
-
- Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
- (Core::getMediaPath() / archName).string(), typeName, secName);
- }
- }
- catch (Ogre::Exception& ex)
- {
- COUT(1) << ex.getFullDescription() << std::endl;
- }
- }
- }
-
- void GraphicsManager::loadRenderer()
- {
- CCOUT(4) << "Configuring Renderer" << std::endl;
-
- if (!ogreRoot_->restoreConfig())
- if (!ogreRoot_->showConfigDialog())
- ThrowException(InitialisationFailed, "OGRE graphics configuration dialogue failed.");
-
- CCOUT(4) << "Creating render window" << std::endl;
-
- this->renderWindow_ = ogreRoot_->initialise(true, "Orxonox");
- this->ogreWindowEventListener_->windowResized(renderWindow_);
-
- Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, ogreWindowEventListener_);
-
- Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(0);
-
- // create a full screen default viewport
- this->viewport_ = this->renderWindow_->addViewport(0, 0);
- }
-
- void GraphicsManager::initialiseResources()
- {
- CCOUT(4) << "Initialising resources" << std::endl;
- //TODO: Do NOT load all the groups, why are we doing that? And do we really do that? initialise != load...
- //try
- //{
- Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
- /*Ogre::StringVector str = Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
- for (unsigned int i = 0; i < str.size(); i++)
- {
- Ogre::ResourceGroupManager::getSingleton().loadResourceGroup(str[i]);
- }*/
- //}
- //catch (...)
- //{
- // CCOUT(2) << "Error: There was a serious error when initialising the resources." << std::endl;
- // throw;
- //}
- }
-
- /**
- @brief
- Method called by the LogListener interface from Ogre.
- We use it to capture Ogre log messages and handle it ourselves.
- @param message
- The message to be logged
- @param lml
- The message level the log is using
- @param maskDebug
- If we are printing to the console or not
- @param logName
- The name of this log (so you can have several listeners
- for different logs, and identify them)
- */
- void GraphicsManager::messageLogged(const std::string& message,
- Ogre::LogMessageLevel lml, bool maskDebug, const std::string& logName)
- {
- int orxonoxLevel;
- switch (lml)
- {
- case Ogre::LML_TRIVIAL:
- orxonoxLevel = this->ogreLogLevelTrivial_;
- break;
- case Ogre::LML_NORMAL:
- orxonoxLevel = this->ogreLogLevelNormal_;
- break;
- case Ogre::LML_CRITICAL:
- orxonoxLevel = this->ogreLogLevelCritical_;
- break;
- default:
- orxonoxLevel = 0;
- }
- OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
- << "Ogre: " << message << std::endl;
- }
-
- void GraphicsManager::printScreen()
- {
- assert(this->renderWindow_);
-
- this->renderWindow_->writeContentsToTimestampedFile(Core::getLogPathString() + "screenShot_", ".jpg");
- }
-}
Deleted: trunk/src/orxonox/GraphicsManager.h
===================================================================
--- trunk/src/orxonox/GraphicsManager.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/GraphicsManager.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -1,118 +0,0 @@
-/*
- * ORXONOX - the hottest 3D action shooter ever to exist
- * > www.orxonox.net <
- *
- *
- * License notice:
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Author:
- * Reto Grieder
- * Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
- * Co-authors:
- * Felix Schulthess
- *
- */
-
-/**
- at file
- at brief
- Declaration of GraphicsManager Singleton.
- */
-
-#ifndef _GraphicsManager_H__
-#define _GraphicsManager_H__
-
-#include "OrxonoxPrereqs.h"
-
-#include <cassert>
-#include <string>
-#include <OgreLog.h>
-#include "core/OrxonoxClass.h"
-
-namespace orxonox
-{
- /**
- @brief
- Graphics engine manager class
- */
- class _OrxonoxExport GraphicsManager : public OrxonoxClass, public Ogre::LogListener
- {
- public:
- GraphicsManager();
- ~GraphicsManager();
-
- void setConfigValues();
-
- void update(const Clock& time);
-
- void detailLevelParticleChanged();
- inline unsigned int getDetailLevelParticle() const
- { return this->detailLevelParticle_; }
-
- inline Ogre::Viewport* getViewport()
- { return this->viewport_; }
- inline Ogre::RenderWindow* getRenderWindow()
- { return this->renderWindow_; }
-
- void setCamera(Ogre::Camera* camera);
-
- inline static GraphicsManager& getInstance()
- { assert(singletonRef_s); return *singletonRef_s; }
-
- private:
- GraphicsManager(GraphicsManager&); // don't mess with singletons
-
- // OGRE initialisation
- void setupOgre();
- void loadOgrePlugins();
- void declareResources();
- void loadRenderer();
- void initialiseResources();
-
- // event from Ogre::LogListener
- void messageLogged(const std::string& message, Ogre::LogMessageLevel lml,
- bool maskDebug, const std::string& logName);
-
- // console commands
- void printScreen();
-
- private:
- Ogre::Root* ogreRoot_; //!< Ogre's root
- Ogre::LogManager* ogreLogger_;
- Ogre::RenderWindow* renderWindow_; //!< the one and only render window
- Ogre::Viewport* viewport_; //!< default full size viewport
- OgreWindowEventListener* ogreWindowEventListener_; //!< Pimpl to hide OgreWindowUtilities.h
-
- // config values
- unsigned int detailLevelParticle_; //!< Detail level of particle effects (0: off, 1: low, 2: normal, 3: high)
- std::string resourceFile_; //!< resources file name
- std::string ogreConfigFile_; //!< ogre config file name
- std::string ogrePluginsFolder_; //!< Folder where the Ogre plugins are located
- std::string ogrePlugins_; //!< Comma separated list of all plugins to load
- std::string ogreLogFile_; //!< log file name for Ogre log messages
- int ogreLogLevelTrivial_; //!< Corresponding Orxonx debug level for LL_TRIVIAL
- int ogreLogLevelNormal_; //!< Corresponding Orxonx debug level for LL_NORMAL
- int ogreLogLevelCritical_; //!< Corresponding Orxonx debug level for LL_CRITICAL
-
- // console commands
- ConsoleCommand* ccPrintScreen_;
-
- static GraphicsManager* singletonRef_s; //!< Pointer to the Singleton
- };
-}
-
-#endif /* _GraphicsManager_H__ */
Modified: trunk/src/orxonox/LevelManager.cc
===================================================================
--- trunk/src/orxonox/LevelManager.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/LevelManager.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -29,10 +29,13 @@
#include "LevelManager.h"
#include <map>
+#include <boost/filesystem.hpp>
#include "core/CommandLine.h"
#include "core/ConfigValueIncludes.h"
+#include "core/Core.h"
#include "core/CoreIncludes.h"
+#include "core/Loader.h"
#include "PlayerManager.h"
#include "objects/Level.h"
#include "objects/infos/HumanPlayer.h"
@@ -41,13 +44,10 @@
{
SetCommandLineArgument(level, "").shortcut("l").information("Default level file (overrides LevelManager::defaultLevelName_ configValue)");
- LevelManager* LevelManager::singletonRef_s = 0;
+ LevelManager* LevelManager::singletonPtr_s = 0;
LevelManager::LevelManager()
{
- assert(singletonRef_s == 0);
- singletonRef_s = this;
-
RegisterRootObject(LevelManager);
this->setConfigValues();
@@ -60,8 +60,6 @@
LevelManager::~LevelManager()
{
- assert(singletonRef_s != 0);
- singletonRef_s = 0;
}
void LevelManager::setConfigValues()
@@ -119,8 +117,35 @@
ModifyConfigValue(defaultLevelName_, set, levelName);
}
- const std::string& LevelManager::getDefaultLevel()
+ const std::string& LevelManager::getDefaultLevel() const
{
return defaultLevelName_;
}
+
+ std::string LevelManager::getAvailableLevelListItem(unsigned int index) const
+ {
+ if (index >= availableLevels_.size())
+ return std::string();
+ else
+ return availableLevels_[index];
+ }
+
+ void LevelManager::compileAvailableLevelList()
+ {
+ availableLevels_.clear();
+
+ boost::filesystem::directory_iterator file(Core::getMediaPathString() + "levels");
+ boost::filesystem::directory_iterator end;
+
+ while (file != end)
+ {
+ if (!boost::filesystem::is_directory(*file) && file->string()[file->string().length()-1] != '~')
+ {
+ std::string filename = file->path().leaf();
+ if (filename.length() > 4)
+ availableLevels_.push_back(filename.substr(0,filename.length()-4));
+ }
+ ++file;
+ }
+ }
}
Modified: trunk/src/orxonox/LevelManager.h
===================================================================
--- trunk/src/orxonox/LevelManager.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/LevelManager.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -34,6 +34,8 @@
#include <cassert>
#include <list>
#include <string>
+
+#include "util/Singleton.h"
#include "core/OrxonoxClass.h"
// tolua_begin
@@ -41,8 +43,9 @@
{
class _OrxonoxExport LevelManager
// tolua_end
- : public OrxonoxClass
+ : public Singleton<LevelManager>, public OrxonoxClass
{ // tolua_export
+ friend class Singleton<LevelManager>;
public:
LevelManager();
virtual ~LevelManager();
@@ -54,10 +57,12 @@
Level* getActiveLevel();
void setDefaultLevel(const std::string& levelName); //tolua_export
- const std::string& getDefaultLevel(); //tolua_export
+ const std::string& getDefaultLevel() const; //tolua_export
+ void compileAvailableLevelList(); //tolua_export
+ std::string getAvailableLevelListItem(unsigned int index) const; //tolua_export
- static LevelManager* getInstancePtr() { return singletonRef_s; }
- static LevelManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; } // tolua_export
+ static LevelManager* getInstancePtr() { return singletonPtr_s; }
+ static LevelManager& getInstance() { return Singleton<LevelManager>::getInstance(); } // tolua_export
private:
LevelManager(const LevelManager&);
@@ -65,11 +70,12 @@
void activateNextLevel();
std::list<Level*> levels_s;
+ std::vector<std::string> availableLevels_;
// config values
std::string defaultLevelName_;
- static LevelManager* singletonRef_s;
+ static LevelManager* singletonPtr_s;
}; // tolua_export
} // tolua_export
Modified: trunk/src/orxonox/Main.cc
===================================================================
--- trunk/src/orxonox/Main.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/Main.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -45,8 +45,16 @@
#include "util/Debug.h"
#include "util/Exception.h"
+#include "core/CommandLine.h"
#include "core/Game.h"
+SetCommandLineSwitch(console).information("Start in console mode (text IO only)");
+// Shortcuts for easy direct loading
+SetCommandLineSwitch(server).information("Start in server mode");
+SetCommandLineSwitch(client).information("Start in client mode");
+SetCommandLineSwitch(dedicated).information("Start in dedicated server mode");
+SetCommandLineSwitch(standalone).information("Start in standalone mode");
+
/*
@brief
Main method. Game starts here (except for static initialisations).
@@ -85,6 +93,20 @@
);
game->requestState("root");
+
+ // Some development hacks (not really, but in the future, this calls won't make sense anymore)
+ if (CommandLine::getValue("standalone").getBool())
+ Game::getInstance().requestStates("graphics, standalone, level");
+ else if (CommandLine::getValue("server").getBool())
+ Game::getInstance().requestStates("graphics, server, level");
+ else if (CommandLine::getValue("client").getBool())
+ Game::getInstance().requestStates("graphics, client, level");
+ else if (CommandLine::getValue("dedicated").getBool())
+ Game::getInstance().requestStates("dedicated, level");
+ else if (CommandLine::getValue("console").getBool())
+ Game::getInstance().requestStates("ioConsole");
+ else
+ Game::getInstance().requestStates("graphics, mainMenu");
}
catch (const std::exception& ex)
{
Modified: trunk/src/orxonox/OrxonoxPrecompiledHeaders.h
===================================================================
--- trunk/src/orxonox/OrxonoxPrecompiledHeaders.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/OrxonoxPrecompiledHeaders.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -89,9 +89,8 @@
#include "core/BaseObject.h"
//#include "core/ConfigValueIncludes.h" // 19
//#include "core/ConsoleCommand.h" // 15
-#include "core/Core.h"
+//#include "core/Core.h" // ?, but not many times
#include "core/CoreIncludes.h"
-#include "core/GameMode.h"
#include "core/XMLPort.h"
#include "network/synchronisable/Synchronisable.h"
Modified: trunk/src/orxonox/OrxonoxPrereqs.h
===================================================================
--- trunk/src/orxonox/OrxonoxPrereqs.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/OrxonoxPrereqs.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -73,10 +73,6 @@
};
}
- class GraphicsManager;
- class OgreWindowEventListener;
- class Settings;
-
class RadarViewable;
class Radar;
class RadarListener;
@@ -276,9 +272,6 @@
class Scoreboard;
class Map;
- //gui
- class GUIManager;
-
//sound
class SoundBase;
class SoundManager;
@@ -292,17 +285,6 @@
class DynamicRenderable;
}
-namespace CEGUI
-{
- class DefaultLogger;
- class Logger;
- class LuaScriptModule;
-
- class OgreCEGUIRenderer;
- class OgreCEGUIResourceProvider;
- class OgreCEGUITexture;
-}
-
// Bullet Physics Engine
class btTransform;
class btVector3;
@@ -329,7 +311,4 @@
typedef unsigned int ALuint;
typedef int ALint;
-// Lua
-struct lua_State;
-
#endif /* _OrxonoxPrereqs_H__ */
Modified: trunk/src/orxonox/PawnManager.cc
===================================================================
--- trunk/src/orxonox/PawnManager.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/PawnManager.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -33,25 +33,20 @@
namespace orxonox
{
- PawnManager* PawnManager::singletonRef_s = 0;
+ PawnManager* PawnManager::singletonPtr_s = 0;
PawnManager::PawnManager()
{
RegisterRootObject(PawnManager);
-
- assert(PawnManager::singletonRef_s == 0);
- PawnManager::singletonRef_s = this;
}
PawnManager::~PawnManager()
{
- assert(PawnManager::singletonRef_s != 0);
- PawnManager::singletonRef_s = 0;
}
void PawnManager::touch()
{
- if (!PawnManager::singletonRef_s)
+ if (!PawnManager::singletonPtr_s)
new PawnManager();
}
Modified: trunk/src/orxonox/PawnManager.h
===================================================================
--- trunk/src/orxonox/PawnManager.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/PawnManager.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -30,12 +30,15 @@
#define _PawnManager_H__
#include "OrxonoxPrereqs.h"
+
+#include "util/Singleton.h"
#include "interfaces/Tickable.h"
namespace orxonox
{
- class _OrxonoxExport PawnManager : public Tickable
+ class _OrxonoxExport PawnManager : protected Singleton<PawnManager>, public Tickable
{
+ friend class Singleton<PawnManager>;
public:
static void touch();
@@ -45,7 +48,7 @@
PawnManager();
virtual ~PawnManager();
- static PawnManager* singletonRef_s;
+ static PawnManager* singletonPtr_s;
};
}
Modified: trunk/src/orxonox/PlayerManager.cc
===================================================================
--- trunk/src/orxonox/PlayerManager.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/PlayerManager.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -36,22 +36,17 @@
namespace orxonox
{
- PlayerManager* PlayerManager::singletonRef_s = 0;
+ PlayerManager* PlayerManager::singletonPtr_s = 0;
PlayerManager::PlayerManager()
{
RegisterRootObject(PlayerManager);
- assert(singletonRef_s == 0);
- singletonRef_s = this;
-
this->getConnectedClients();
}
PlayerManager::~PlayerManager()
{
- assert(singletonRef_s);
- singletonRef_s = 0;
}
void PlayerManager::clientConnected(unsigned int clientID)
Modified: trunk/src/orxonox/PlayerManager.h
===================================================================
--- trunk/src/orxonox/PlayerManager.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/PlayerManager.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -33,19 +33,18 @@
#include <cassert>
#include <map>
+#include "util/Singleton.h"
#include "network/ClientConnectionListener.h"
namespace orxonox
{
- class _OrxonoxExport PlayerManager : public ClientConnectionListener
+ class _OrxonoxExport PlayerManager : public Singleton<PlayerManager>, public ClientConnectionListener
{
+ friend class Singleton<PlayerManager>;
public:
PlayerManager();
virtual ~PlayerManager();
- inline static PlayerManager& getInstance()
- { assert(singletonRef_s); return *singletonRef_s; }
-
PlayerInfo* getClient(unsigned int clientID) const;
inline const std::map<unsigned int, PlayerInfo*>& getClients() const
{ return this->clients_; }
@@ -56,7 +55,7 @@
std::map<unsigned int, PlayerInfo*> clients_;
- static PlayerManager* singletonRef_s;
+ static PlayerManager* singletonPtr_s;
};
}
Modified: trunk/src/orxonox/gamestates/GSClient.cc
===================================================================
--- trunk/src/orxonox/gamestates/GSClient.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSClient.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -41,8 +41,8 @@
SetCommandLineArgument(ip, "127.0.0.1").information("Sever IP as strin in the form #.#.#.#");
- GSClient::GSClient(const GameStateConstrParams& params)
- : GameState(params)
+ GSClient::GSClient(const GameStateInfo& info)
+ : GameState(info)
, client_(0)
{
}
Modified: trunk/src/orxonox/gamestates/GSClient.h
===================================================================
--- trunk/src/orxonox/gamestates/GSClient.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSClient.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -39,7 +39,7 @@
class _OrxonoxExport GSClient : public GameState
{
public:
- GSClient(const GameStateConstrParams& params);
+ GSClient(const GameStateInfo& info);
~GSClient();
void activate();
Modified: trunk/src/orxonox/gamestates/GSDedicated.cc
===================================================================
--- trunk/src/orxonox/gamestates/GSDedicated.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSDedicated.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -54,8 +54,8 @@
termios* GSDedicated::originalTerminalSettings_;
- GSDedicated::GSDedicated(const GameStateConstrParams& params)
- : GameState(params)
+ GSDedicated::GSDedicated(const GameStateInfo& info)
+ : GameState(info)
, server_(0)
, closeThread_(false)
, cleanLine_(true)
Modified: trunk/src/orxonox/gamestates/GSDedicated.h
===================================================================
--- trunk/src/orxonox/gamestates/GSDedicated.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSDedicated.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -47,7 +47,7 @@
class _OrxonoxExport GSDedicated : public GameState
{
public:
- GSDedicated(const GameStateConstrParams& params);
+ GSDedicated(const GameStateInfo& info);
~GSDedicated();
void activate();
Modified: trunk/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- trunk/src/orxonox/gamestates/GSGraphics.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSGraphics.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -34,45 +34,46 @@
#include "GSGraphics.h"
-#include <boost/filesystem.hpp>
-#include <OgreRenderWindow.h>
-
#include "util/Convert.h"
#include "core/Clock.h"
#include "core/CommandExecutor.h"
#include "core/ConsoleCommand.h"
#include "core/Core.h"
#include "core/Game.h"
-#include "core/GameMode.h"
+#include "core/GUIManager.h"
#include "core/input/InputManager.h"
#include "core/input/KeyBinder.h"
#include "core/input/InputState.h"
#include "core/Loader.h"
#include "core/XMLFile.h"
#include "overlays/console/InGameConsole.h"
-#include "gui/GUIManager.h"
#include "sound/SoundManager.h"
-#include "GraphicsManager.h"
+// HACK:
+#include "overlays/map/Map.h"
+
namespace orxonox
{
- DeclareGameState(GSGraphics, "graphics", true, true);
+ DeclareGameState(GSGraphics, "graphics", false, true);
- GSGraphics::GSGraphics(const GameStateConstrParams& params)
- : GameState(params)
- , inputManager_(0)
+ GSGraphics::GSGraphics(const GameStateInfo& info)
+ : GameState(info)
, console_(0)
- , guiManager_(0)
- , graphicsManager_(0)
, soundManager_(0)
, masterKeyBinder_(0)
, masterInputState_(0)
, debugOverlay_(0)
{
+ // load master key bindings
+ masterInputState_ = InputManager::getInstance().createInputState("master", true);
+ masterKeyBinder_ = new KeyBinder();
+ masterInputState_->setKeyHandler(masterKeyBinder_);
}
GSGraphics::~GSGraphics()
{
+ InputManager::getInstance().destroyState("master");
+ delete this->masterKeyBinder_;
}
/**
@@ -92,29 +93,12 @@
*/
void GSGraphics::activate()
{
- GameMode::setShowsGraphics(true);
-
- // Load OGRE including the render window
- this->graphicsManager_ = new GraphicsManager();
-
// load debug overlay
COUT(3) << "Loading Debug Overlay..." << std::endl;
- this->debugOverlay_ = new XMLFile((Core::getMediaPath() / "overlay" / "debug.oxo").string());
+ this->debugOverlay_ = new XMLFile(Core::getMediaPathString() + "overlay/debug.oxo");
Loader::open(debugOverlay_);
- // The render window width and height are used to set up the mouse movement.
- size_t windowHnd = 0;
- Ogre::RenderWindow* renderWindow = GraphicsManager::getInstance().getRenderWindow();
- renderWindow->getCustomAttribute("WINDOW", &windowHnd);
-
- // Calls the InputManager which sets up the input devices.
- inputManager_ = new InputManager(windowHnd);
-
- // load master key bindings
- masterInputState_ = InputManager::getInstance().createInputState("master", true);
- masterKeyBinder_ = new KeyBinder();
masterKeyBinder_->loadBindings("masterKeybindings.ini");
- masterInputState_->setKeyHandler(masterKeyBinder_);
// Load the SoundManager
soundManager_ = new SoundManager();
@@ -123,10 +107,6 @@
console_ = new InGameConsole();
console_->initialise();
- // load the CEGUI interface
- guiManager_ = new GUIManager();
- guiManager_->initialise(renderWindow);
-
// add console command to toggle GUI
FunctorMember<GSGraphics>* functor = createFunctor(&GSGraphics::toggleGUI);
functor->setObject(this);
@@ -153,11 +133,6 @@
}
*/
- masterInputState_->setHandler(0);
- InputManager::getInstance().destroyState("master");
- delete this->masterKeyBinder_;
-
- delete this->guiManager_;
delete this->console_;
Loader::unload(this->debugOverlay_);
@@ -165,12 +140,8 @@
delete this->soundManager_;
- delete this->inputManager_;
- this->inputManager_ = 0;
-
- delete graphicsManager_;
-
- GameMode::setShowsGraphics(false);
+ // HACK: (destroys a resource smart pointer)
+ Map::hackDestroyMap();
}
/**
@@ -202,19 +173,6 @@
Game::getInstance().requestState("mainMenu");
}
- uint64_t timeBeforeTick = time.getRealMicroseconds();
-
- this->inputManager_->update(time);
this->console_->update(time);
-
- uint64_t timeAfterTick = time.getRealMicroseconds();
-
- // Also add our tick time
- Game::getInstance().addTickTime(timeAfterTick - timeBeforeTick);
-
- // Process gui events
- this->guiManager_->update(time);
- // Render
- this->graphicsManager_->update(time);
}
}
Modified: trunk/src/orxonox/gamestates/GSGraphics.h
===================================================================
--- trunk/src/orxonox/gamestates/GSGraphics.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSGraphics.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -49,7 +49,7 @@
class _OrxonoxExport GSGraphics : public GameState
{
public:
- GSGraphics(const GameStateConstrParams& params);
+ GSGraphics(const GameStateInfo& info);
~GSGraphics();
void activate();
@@ -60,10 +60,7 @@
private:
// managed singletons
- InputManager* inputManager_; //!< Reference to input management
InGameConsole* console_;
- GUIManager* guiManager_; //!< Interface to GUI
- GraphicsManager* graphicsManager_; //!< Interface to Ogre
SoundManager* soundManager_; //!< Keeps track of SoundBase objects
KeyBinder* masterKeyBinder_; //!< Key binder for master key bindings
Modified: trunk/src/orxonox/gamestates/GSIOConsole.cc
===================================================================
--- trunk/src/orxonox/gamestates/GSIOConsole.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSIOConsole.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -37,8 +37,8 @@
{
DeclareGameState(GSIOConsole, "ioConsole", false, false);
- GSIOConsole::GSIOConsole(const GameStateConstrParams& params)
- : GameState(params)
+ GSIOConsole::GSIOConsole(const GameStateInfo& info)
+ : GameState(info)
{
}
Modified: trunk/src/orxonox/gamestates/GSIOConsole.h
===================================================================
--- trunk/src/orxonox/gamestates/GSIOConsole.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSIOConsole.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -37,7 +37,7 @@
class _OrxonoxExport GSIOConsole : public GameState
{
public:
- GSIOConsole(const GameStateConstrParams& params);
+ GSIOConsole(const GameStateInfo& info);
~GSIOConsole();
void activate();
Modified: trunk/src/orxonox/gamestates/GSLevel.cc
===================================================================
--- trunk/src/orxonox/gamestates/GSLevel.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSLevel.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -39,6 +39,8 @@
#include "core/Game.h"
#include "core/GameMode.h"
#include "core/Core.h"
+#include "core/GraphicsManager.h"
+#include "core/GUIManager.h"
#include "core/Loader.h"
#include "core/XMLFile.h"
@@ -46,21 +48,19 @@
#include "objects/Radar.h"
#include "objects/quest/QuestManager.h"
#include "overlays/notifications/NotificationManager.h"
-#include "gui/GUIManager.h"
#include "CameraManager.h"
-#include "GraphicsManager.h"
#include "LevelManager.h"
#include "PlayerManager.h"
namespace orxonox
{
- DeclareGameState(GSLevel, "level", false, true);
+ DeclareGameState(GSLevel, "level", false, false);
SetConsoleCommand(GSLevel, showIngameGUI, true);
XMLFile* GSLevel::startFile_s = NULL;
- GSLevel::GSLevel(const GameStateConstrParams& params)
- : GameState(params)
+ GSLevel::GSLevel(const GameStateInfo& info)
+ : GameState(info)
, keyBinder_(0)
, gameInputState_(0)
, guiMouseOnlyInputState_(0)
Modified: trunk/src/orxonox/gamestates/GSLevel.h
===================================================================
--- trunk/src/orxonox/gamestates/GSLevel.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSLevel.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -40,7 +40,7 @@
class _OrxonoxExport GSLevel : public GameState, public OrxonoxClass
{
public:
- GSLevel(const GameStateConstrParams& params);
+ GSLevel(const GameStateInfo& info);
~GSLevel();
void setConfigValues();
Modified: trunk/src/orxonox/gamestates/GSMainMenu.cc
===================================================================
--- trunk/src/orxonox/gamestates/GSMainMenu.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSMainMenu.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -35,27 +35,19 @@
#include "core/Game.h"
#include "core/Clock.h"
#include "core/ConsoleCommand.h"
+#include "core/GraphicsManager.h"
+#include "core/GUIManager.h"
#include "objects/Scene.h"
-#include "gui/GUIManager.h"
#include "sound/SoundMainMenu.h"
-#include "GraphicsManager.h"
namespace orxonox
{
DeclareGameState(GSMainMenu, "mainMenu", false, true);
- GSMainMenu::GSMainMenu(const GameStateConstrParams& params)
- : GameState(params)
+ GSMainMenu::GSMainMenu(const GameStateInfo& info)
+ : GameState(info)
, inputState_(0)
{
- }
-
- GSMainMenu::~GSMainMenu()
- {
- }
-
- void GSMainMenu::activate()
- {
inputState_ = InputManager::getInstance().createInputState("mainMenu");
inputState_->setHandler(GUIManager::getInstancePtr());
inputState_->setJoyStickHandler(&InputHandler::EMPTY);
@@ -64,9 +56,20 @@
this->scene_ = new Scene(0);
// and a Camera
this->camera_ = this->scene_->getSceneManager()->createCamera("mainMenu/Camera");
+ }
+ GSMainMenu::~GSMainMenu()
+ {
+ InputManager::getInstance().destroyState("mainMenu");
+
+ this->scene_->getSceneManager()->destroyCamera(this->camera_);
+ delete this->scene_;
+ }
+
+ void GSMainMenu::activate()
+ {
// show main menu
- GUIManager::getInstance().showGUI("mainmenu_3");
+ GUIManager::getInstance().showGUI("mainmenu_4");
GUIManager::getInstance().setCamera(this->camera_);
GraphicsManager::getInstance().setCamera(this->camera_);
@@ -106,12 +109,9 @@
delete this->ambient_;
InputManager::getInstance().leaveState("mainMenu");
- InputManager::getInstance().destroyState("mainMenu");
GUIManager::getInstance().setCamera(0);
GraphicsManager::getInstance().setCamera(0);
- this->scene_->getSceneManager()->destroyCamera(this->camera_);
- delete this->scene_;
/*
if (this->ccStartGame_)
Modified: trunk/src/orxonox/gamestates/GSMainMenu.h
===================================================================
--- trunk/src/orxonox/gamestates/GSMainMenu.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSMainMenu.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -39,7 +39,7 @@
class _OrxonoxExport GSMainMenu : public GameState
{
public:
- GSMainMenu(const GameStateConstrParams& params);
+ GSMainMenu(const GameStateInfo& info);
~GSMainMenu();
void activate();
Modified: trunk/src/orxonox/gamestates/GSRoot.cc
===================================================================
--- trunk/src/orxonox/gamestates/GSRoot.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSRoot.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -29,11 +29,13 @@
#include "GSRoot.h"
#include "core/Clock.h"
-#include "core/CommandLine.h"
#include "core/ConsoleCommand.h"
#include "core/Game.h"
#include "core/GameMode.h"
+#include "core/LuaBind.h"
#include "network/NetworkFunction.h"
+#include "ToluaBindCore.h"
+#include "ToluaBindOrxonox.h"
#include "tools/Timer.h"
#include "interfaces/TimeFactorListener.h"
#include "interfaces/Tickable.h"
@@ -41,22 +43,20 @@
namespace orxonox
{
- DeclareGameState(GSRoot, "root", true, false);
- SetCommandLineSwitch(console).information("Start in console mode (text IO only)");
- // Shortcuts for easy direct loading
- SetCommandLineSwitch(server).information("Start in server mode");
- SetCommandLineSwitch(client).information("Start in client mode");
- SetCommandLineSwitch(dedicated).information("Start in dedicated server mode");
- SetCommandLineSwitch(standalone).information("Start in standalone mode");
+ DeclareGameState(GSRoot, "root", false, false);
- GSRoot::GSRoot(const GameStateConstrParams& params)
- : GameState(params)
+ GSRoot::GSRoot(const GameStateInfo& info)
+ : GameState(info)
, timeFactor_(1.0f)
, bPaused_(false)
, timeFactorPauseBackup_(1.0f)
{
this->ccSetTimeFactor_ = 0;
this->ccPause_ = 0;
+
+ // Tell LuaBind about all tolua interfaces
+ LuaBind::getInstance().addToluaInterface(&tolua_Core_open, "Core");
+ LuaBind::getInstance().addToluaInterface(&tolua_Orxonox_open, "Orxonox");
}
GSRoot::~GSRoot()
@@ -87,36 +87,6 @@
// create the global LevelManager
this->levelManager_ = new LevelManager();
-
- // Load level directly?
- bool loadLevel = false;
- if (CommandLine::getValue("standalone").getBool())
- {
- Game::getInstance().requestStates("graphics, standalone, level");
- loadLevel = true;
- }
- if (CommandLine::getValue("server").getBool())
- {
- Game::getInstance().requestStates("graphics, server, level");
- loadLevel = true;
- }
- if (CommandLine::getValue("client").getBool())
- {
- Game::getInstance().requestStates("graphics, client, level");
- loadLevel = true;
- }
- if (CommandLine::getValue("dedicated").getBool())
- {
- Game::getInstance().requestStates("dedicated, level");
- loadLevel = true;
- }
-
- // Determine where to start otherwise
- if (!loadLevel && !CommandLine::getValue("console").getBool())
- {
- // Also load graphics
- Game::getInstance().requestState("graphics");
- }
}
void GSRoot::deactivate()
@@ -147,8 +117,6 @@
Game::getInstance().requestState("ioConsole");
}
- uint64_t timeBeforeTick = time.getRealMicroseconds();
-
for (ObjectList<TimerBase>::iterator it = ObjectList<TimerBase>::begin(); it; ++it)
it->tick(time);
@@ -163,16 +131,14 @@
for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; ++it)
it->tick(leveldt * this->timeFactor_);
/*** HACK *** HACK ***/
-
- uint64_t timeAfterTick = time.getRealMicroseconds();
-
- // Also add our tick time
- Game::getInstance().addTickTime(timeAfterTick - timeBeforeTick);
}
/**
@brief
Changes the speed of Orxonox
+ @remark
+ This function is a hack when placed here!
+ Timefactor should be related to the scene (level or so), not the game
*/
void GSRoot::setTimeFactor(float factor)
{
Modified: trunk/src/orxonox/gamestates/GSRoot.h
===================================================================
--- trunk/src/orxonox/gamestates/GSRoot.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSRoot.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -37,7 +37,7 @@
class _OrxonoxExport GSRoot : public GameState
{
public:
- GSRoot(const GameStateConstrParams& params);
+ GSRoot(const GameStateInfo& info);
~GSRoot();
void activate();
Modified: trunk/src/orxonox/gamestates/GSServer.cc
===================================================================
--- trunk/src/orxonox/gamestates/GSServer.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSServer.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -40,8 +40,8 @@
SetCommandLineArgument(port, 55556).shortcut("p").information("Network communication port to be used 0-65535 (default: 55556)");
- GSServer::GSServer(const GameStateConstrParams& params)
- : GameState(params)
+ GSServer::GSServer(const GameStateInfo& info)
+ : GameState(info)
, server_(0)
{
}
Modified: trunk/src/orxonox/gamestates/GSServer.h
===================================================================
--- trunk/src/orxonox/gamestates/GSServer.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSServer.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -39,7 +39,7 @@
class _OrxonoxExport GSServer : public GameState
{
public:
- GSServer(const GameStateConstrParams& params);
+ GSServer(const GameStateInfo& info);
~GSServer();
void activate();
Modified: trunk/src/orxonox/gamestates/GSStandalone.cc
===================================================================
--- trunk/src/orxonox/gamestates/GSStandalone.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSStandalone.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -35,8 +35,8 @@
{
DeclareGameState(GSStandalone, "standalone", false, true);
- GSStandalone::GSStandalone(const GameStateConstrParams& params)
- : GameState(params)
+ GSStandalone::GSStandalone(const GameStateInfo& info)
+ : GameState(info)
{
}
Modified: trunk/src/orxonox/gamestates/GSStandalone.h
===================================================================
--- trunk/src/orxonox/gamestates/GSStandalone.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/gamestates/GSStandalone.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -37,7 +37,7 @@
class _OrxonoxExport GSStandalone : public GameState
{
public:
- GSStandalone(const GameStateConstrParams& params);
+ GSStandalone(const GameStateInfo& info);
~GSStandalone();
void activate();
Modified: trunk/src/orxonox/objects/pickup/BaseItem.h
===================================================================
--- trunk/src/orxonox/objects/pickup/BaseItem.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/objects/pickup/BaseItem.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -50,10 +50,7 @@
@author
Daniel 'Huty' Haggenmueller
*/
- class _OrxonoxExport BaseItem
-// tolua_end
- : public BaseObject
-// tolua_begin
+ class _OrxonoxExport BaseItem : public BaseObject
{
// tolua_end
public:
Modified: trunk/src/orxonox/objects/pickup/PickupInventory.cc
===================================================================
--- trunk/src/orxonox/objects/pickup/PickupInventory.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/objects/pickup/PickupInventory.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -36,8 +36,8 @@
#include <elements/CEGUITabControl.h>
#include "core/ConsoleCommand.h"
+#include "core/GUIManager.h"
#include "core/input/InputManager.h"
-#include "gui/GUIManager.h"
#include "objects/controllers/HumanController.h"
#include "objects/worldentities/pawns/Pawn.h"
Modified: trunk/src/orxonox/objects/pickup/PickupInventory.h
===================================================================
--- trunk/src/orxonox/objects/pickup/PickupInventory.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/objects/pickup/PickupInventory.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -42,12 +42,10 @@
// tolua_begin
namespace orxonox
{
-// tolua_end
/**
@brief Static class for the inventory GUI window.
@author Daniel 'Huty' Haggenmueller
*/
-// tolua_begin
class _OrxonoxExport PickupInventory
{
// tolua_end
Modified: trunk/src/orxonox/objects/pickup/PickupSpawner.cc
===================================================================
--- trunk/src/orxonox/objects/pickup/PickupSpawner.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/objects/pickup/PickupSpawner.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -36,9 +36,9 @@
#include "BaseItem.h"
#include "core/CoreIncludes.h"
+#include "core/GUIManager.h" // HACK; see below
#include "core/Template.h"
#include "core/XMLPort.h"
-#include "gui/GUIManager.h" // HACK; see below
#include "objects/worldentities/pawns/Pawn.h"
#include "PickupInventory.h" // HACK; Only for hack, remove later
Modified: trunk/src/orxonox/objects/quest/QuestDescription.h
===================================================================
--- trunk/src/orxonox/objects/quest/QuestDescription.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/objects/quest/QuestDescription.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -53,10 +53,9 @@
@author
Damian 'Mozork' Frick
*/
- class _OrxonoxExport QuestDescription
+ class _OrxonoxExport QuestDescription : public BaseObject
+ {
// tolua_end
- : public BaseObject
- { // tolua_export
public:
QuestDescription(BaseObject* creator);
virtual ~QuestDescription();
Modified: trunk/src/orxonox/objects/quest/QuestListener.cc
===================================================================
--- trunk/src/orxonox/objects/quest/QuestListener.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/objects/quest/QuestListener.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -80,7 +80,7 @@
/**
@brief
- Makes all QuestListener in the list aware that a certain status change has occured and executes them if the status change affects them.
+ Makes all QuestListener in the list aware that a certain status change has occurred and executes them if the status change affects them.
@param listeners
The list of QuestListeners that have to be made aware of the status change.
@param status
@@ -181,7 +181,7 @@
}
else
{
- COUT(1) << "An unforseen, never to happen, Error has occured. This is impossible!" << std::endl;
+ COUT(1) << "An unforseen, never to happen, Error has occurred. This is impossible!" << std::endl;
return "";
}
}
Modified: trunk/src/orxonox/objects/quest/QuestManager.cc
===================================================================
--- trunk/src/orxonox/objects/quest/QuestManager.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/objects/quest/QuestManager.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -35,7 +35,6 @@
#include "util/Exception.h"
#include "core/CoreIncludes.h"
-#include "gui/GUIManager.h"
#include "objects/infos/PlayerInfo.h"
#include "objects/infos/PlayerInfo.h"
@@ -47,7 +46,7 @@
namespace orxonox
{
//! Pointer to the current (and single) instance of this class.
- /*static*/ QuestManager* QuestManager::singletonRef_s = NULL;
+ /*static*/ QuestManager* QuestManager::singletonPtr_s = NULL;
/**
@brief
@@ -58,9 +57,6 @@
QuestManager::QuestManager()
{
RegisterRootObject(QuestManager);
-
- assert(singletonRef_s == 0);
- singletonRef_s = this;
}
/**
@@ -74,18 +70,6 @@
/**
@brief
- Returns a reference to the current (and single) instance of the QuestManager, and creates one if there isn't one to begin with.
- @return
- Returns a reference to the single instance of the Quest Manager.
- */
- /*static*/ QuestManager & QuestManager::getInstance()
- {
- assert(singletonRef_s);
- return *singletonRef_s;
- }
-
- /**
- @brief
Registers a Quest with the QuestManager to make it globally accessable.
Uses it's id to make sure to be able to be identify and retrieve it later.
@param quest
@@ -224,7 +208,10 @@
*/
QuestContainer* QuestManager::getQuestTree(std::string & name)
{
- GUIOverlay* gui = GUIManager::getInstance().getOverlay(name);
+ GUIOverlay* gui = NULL;
+ for (ObjectList<GUIOverlay>::iterator it = ObjectList<GUIOverlay>::begin(); it != ObjectList<GUIOverlay>::end(); ++it)
+ if (it->getGUIName() == name)
+ gui = *it;
PlayerInfo* player;
if(gui == NULL)
@@ -320,7 +307,7 @@
else
{
container->status = "";
- COUT(1) << "An error occured. A Quest of un-specified status wanted to be displayed." << std::endl;
+ COUT(1) << "An error occurred. A Quest of un-specified status wanted to be displayed." << std::endl;
}
std::list<Quest*> quests = quest->getSubQuestList();
Modified: trunk/src/orxonox/objects/quest/QuestManager.h
===================================================================
--- trunk/src/orxonox/objects/quest/QuestManager.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/objects/quest/QuestManager.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -39,6 +39,8 @@
#include <list>
#include <map>
#include <string>
+
+#include "util/Singleton.h"
#include "core/OrxonoxClass.h"
// tolua_begin
@@ -70,17 +72,16 @@
@author
Damian 'Mozork' Frick
*/
- class _OrxonoxExport QuestManager
-// tolua_end
- : public OrxonoxClass
-// tolua_begin
+ class _OrxonoxExport QuestManager : public Singleton<QuestManager>, public orxonox::OrxonoxClass
{
// tolua_end
+ friend class Singleton<QuestManager>;
public:
QuestManager();
virtual ~QuestManager();
- static QuestManager& getInstance(); // tolua_export //!< Returns a reference to the single instance of the Quest Manager.
+ //! Returns a reference to the single instance of the Quest Manager.
+ static QuestManager& getInstance() { return Singleton<QuestManager>::getInstance(); } // tolua_export
bool registerQuest(Quest* quest); //!< Registers a Quest in the QuestManager.
bool registerHint(QuestHint* quest); //!< Registers a QuestHint in the QuestManager.
@@ -91,7 +92,7 @@
QuestContainer* getQuestTree(std::string & name); // tolua_export
private:
- static QuestManager* singletonRef_s;
+ static QuestManager* singletonPtr_s;
std::map<std::string, Quest*> questMap_; //!< All Quests registered by their id's.
std::map<std::string, QuestHint*> hintMap_; //!< All QuestHints registered by their id's.
Modified: trunk/src/orxonox/overlays/GUIOverlay.cc
===================================================================
--- trunk/src/orxonox/overlays/GUIOverlay.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/overlays/GUIOverlay.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -33,8 +33,8 @@
#include "core/input/InputManager.h"
#include "core/CoreIncludes.h"
+#include "core/GUIManager.h"
#include "core/XMLPort.h"
-#include "gui/GUIManager.h"
namespace orxonox
{
@@ -54,8 +54,6 @@
SUPER(GUIOverlay, XMLPort, xmlElement, mode);
XMLPortParam(GUIOverlay, "guiname", setGUIName, getGUIName, xmlElement, mode);
-
- GUIManager::getInstance().registerOverlay(this->guiName_, this);
}
void GUIOverlay::changedVisibility()
Modified: trunk/src/orxonox/overlays/console/InGameConsole.cc
===================================================================
--- trunk/src/orxonox/overlays/console/InGameConsole.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/overlays/console/InGameConsole.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -59,7 +59,7 @@
SetConsoleCommand(InGameConsole, openConsole, true);
SetConsoleCommand(InGameConsole, closeConsole, true);
- InGameConsole* InGameConsole::singletonRef_s = 0;
+ InGameConsole* InGameConsole::singletonPtr_s = 0;
/**
@brief Constructor: Creates and initializes the InGameConsole.
@@ -75,9 +75,6 @@
{
RegisterObject(InGameConsole);
- assert(singletonRef_s == 0);
- singletonRef_s = this;
-
this->bActive_ = false;
this->cursor_ = 0.0f;
this->cursorSymbol_ = '|';
@@ -130,8 +127,6 @@
if (this->consoleOverlay_)
Ogre::OverlayManager::getSingleton().destroy(consoleOverlay_);
-
- singletonRef_s = 0;
}
/**
Modified: trunk/src/orxonox/overlays/console/InGameConsole.h
===================================================================
--- trunk/src/orxonox/overlays/console/InGameConsole.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/overlays/console/InGameConsole.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -33,14 +33,17 @@
#include "OrxonoxPrereqs.h"
#include <string>
+
#include "util/OgreForwardRefs.h"
+#include "util/Singleton.h"
#include "core/Shell.h"
#include "core/WindowEventListener.h"
namespace orxonox
{
- class _OrxonoxExport InGameConsole : public ShellListener, public WindowEventListener
+ class _OrxonoxExport InGameConsole : public Singleton<InGameConsole>, public ShellListener, public WindowEventListener
{
+ friend class Singleton<InGameConsole>;
public: // functions
InGameConsole();
~InGameConsole();
@@ -51,9 +54,6 @@
void update(const Clock& time);
- static InGameConsole& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
- static InGameConsole* getInstancePtr() { return singletonRef_s; }
-
static void openConsole();
static void closeConsole();
@@ -111,7 +111,7 @@
char cursorSymbol_;
bool bHidesAllInput_;
- static InGameConsole* singletonRef_s;
+ static InGameConsole* singletonPtr_s;
};
}
Modified: trunk/src/orxonox/overlays/notifications/NotificationManager.cc
===================================================================
--- trunk/src/orxonox/overlays/notifications/NotificationManager.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/overlays/notifications/NotificationManager.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -45,7 +45,7 @@
const std::string NotificationManager::ALL = "all";
const std::string NotificationManager::NONE = "none";
- NotificationManager* NotificationManager::singletonRef_s = NULL;
+ NotificationManager* NotificationManager::singletonPtr_s = NULL;
/**
@brief
@@ -55,9 +55,6 @@
{
RegisterRootObject(NotificationManager);
- assert(singletonRef_s == 0);
- singletonRef_s = this;
-
this->highestIndex_ = 0;
}
@@ -71,18 +68,6 @@
/**
@brief
- Returns the current (and single) instance of the NotificationManager. Creates one, if there isn't one to begin with.
- @return
- Returns a reference to the single instance of the NotificationManager.
- */
- /*static*/ NotificationManager & NotificationManager::getInstance()
- {
- assert(singletonRef_s);
- return *singletonRef_s;
- }
-
- /**
- @brief
Registers a Notification within the NotificationManager and makes sure that the Notification is displayed in all the NotificationQueues associated with its sender.
@param notification
The Notification to be registered.
Modified: trunk/src/orxonox/overlays/notifications/NotificationManager.h
===================================================================
--- trunk/src/orxonox/overlays/notifications/NotificationManager.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/overlays/notifications/NotificationManager.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -39,6 +39,8 @@
#include <ctime>
#include <map>
#include <string>
+
+#include "util/Singleton.h"
#include "core/OrxonoxClass.h"
namespace orxonox
@@ -51,8 +53,9 @@
@author
Damian 'Mozork' Frick
*/
- class _OrxonoxExport NotificationManager : public OrxonoxClass
+ class _OrxonoxExport NotificationManager : public Singleton<NotificationManager>, public OrxonoxClass
{
+ friend class Singleton<NotificationManager>;
public:
NotificationManager();
virtual ~NotificationManager();
@@ -60,8 +63,6 @@
static const std::string ALL;
static const std::string NONE;
- static NotificationManager & getInstance(); //! Returns a reference to the single instance of the NotificationManager.
-
bool registerNotification(Notification* notification); //!< Registers a Notification within the NotificationManager.
bool registerQueue(NotificationQueue* queue); //!< Registers a NotificationQueue within the NotificationManager.
@@ -87,7 +88,7 @@
{ return this->getNotifications(queue, map, std::time(0)-timeDelay, std::time(0)); }
private:
- static NotificationManager* singletonRef_s;
+ static NotificationManager* singletonPtr_s;
int highestIndex_; //!< This variable holds the highest index (resp. key) in notificationLists_s, to secure that no key appears twice.
Modified: trunk/src/orxonox/sound/SoundBase.cc
===================================================================
--- trunk/src/orxonox/sound/SoundBase.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/sound/SoundBase.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -64,19 +64,19 @@
void SoundBase::update() {
if(this->entity_ != NULL && alIsSource(this->source_)) {
- Vector3 pos = this->entity_->getPosition();
+ const Vector3& pos = this->entity_->getPosition();
alSource3f(this->source_, AL_POSITION, pos.x, pos.y, pos.z);
ALenum error = alGetError();
if(error == AL_INVALID_VALUE)
COUT(2) << "Sound: OpenAL: Invalid sound position" << std::endl;
- Vector3 vel = this->entity_->getVelocity();
+ const Vector3& vel = this->entity_->getVelocity();
alSource3f(this->source_, AL_VELOCITY, vel.x, vel.y, vel.z);
error = alGetError();
if(error == AL_INVALID_VALUE)
COUT(2) << "Sound: OpenAL: Invalid sound velocity" << std::endl;
- Quaternion orient = this->entity_->getOrientation();
+ const Quaternion& orient = this->entity_->getOrientation();
Vector3 at = orient.zAxis();
alSource3f(this->source_, AL_DIRECTION, at.x, at.y, at.z);
error = alGetError();
@@ -189,7 +189,7 @@
if(ov_open(f, &vf, NULL, 0) < 0)
{
- COUT(2) << "Sound: libvorbisfile: File seems not to be an Ogg Vorbis bitstream" << std::endl;
+ COUT(2) << "Sound: libvorbisfile: File does not seem to be an Ogg Vorbis bitstream" << std::endl;
ov_clear(&vf);
return AL_NONE;
}
Modified: trunk/src/orxonox/sound/SoundManager.cc
===================================================================
--- trunk/src/orxonox/sound/SoundManager.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/sound/SoundManager.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -37,16 +37,13 @@
namespace orxonox
{
- SoundManager* SoundManager::singletonRef_s = NULL;
+ SoundManager* SoundManager::singletonPtr_s = NULL;
/**
* Default constructor
*/
SoundManager::SoundManager()
{
- assert(singletonRef_s == NULL);
- singletonRef_s = this;
-
this->device_ = NULL;
this->soundavailable_ = true;
if(!alutInitWithoutContext(NULL,NULL))
@@ -92,9 +89,6 @@
SoundManager::~SoundManager()
{
- assert(singletonRef_s != NULL);
- singletonRef_s = NULL;
-
alcDestroyContext(this->context_);
alcCloseDevice(this->device_);
alutExit();
@@ -147,7 +141,7 @@
COUT(2) << "Sound: OpenAL: Invalid listener position" << std::endl;
// update listener orientation
- Quaternion orient = camera->getOrientation();
+ const Quaternion& orient = camera->getOrientation();
Vector3 up = orient.xAxis(); // just a wild guess
Vector3 at = orient.zAxis();
Modified: trunk/src/orxonox/sound/SoundManager.h
===================================================================
--- trunk/src/orxonox/sound/SoundManager.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/sound/SoundManager.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -31,6 +31,7 @@
#include <cassert>
#include <list>
+#include "util/Singleton.h"
#include "interfaces/Tickable.h"
namespace orxonox
@@ -41,8 +42,9 @@
* function every tick. It is a singleton.
*
*/
- class _OrxonoxExport SoundManager : public Tickable
+ class _OrxonoxExport SoundManager : public Singleton<SoundManager>, public Tickable
{
+ friend class Singleton<SoundManager>;
public:
SoundManager();
~SoundManager();
@@ -51,15 +53,13 @@
void tick(float dt);
bool isSoundAvailable();
- static SoundManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
-
private:
ALCdevice* device_;
ALCcontext* context_;
std::list<SoundBase*> soundlist_;
bool soundavailable_;
- static SoundManager* singletonRef_s;
+ static SoundManager* singletonPtr_s;
}; // class SoundManager
} // namespace orxonox
Modified: trunk/src/orxonox/tools/ParticleInterface.cc
===================================================================
--- trunk/src/orxonox/tools/ParticleInterface.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/tools/ParticleInterface.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -42,8 +42,8 @@
#include "util/Convert.h"
#include "util/Math.h"
#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
#include "core/GameMode.h"
-#include "GraphicsManager.h"
namespace orxonox
{
@@ -90,6 +90,12 @@
}
}
+ void ParticleInterface::setConfigValues()
+ {
+ SetConfigValue(globalDetailLevel_, 2)
+ .description("O: off, 1: low, 2: normal, 3: high").callback(this, &ParticleInterface::detailLevelChanged);
+ }
+
Ogre::ParticleEmitter* ParticleInterface::createNewEmitter()
{
if (this->particleSystem_ && this->particleSystem_->getNumEmitters() > 0)
@@ -179,12 +185,12 @@
{
this->detaillevel_ = level;
if (GameMode::showsGraphics())
- this->detailLevelChanged(GraphicsManager::getInstance().getDetailLevelParticle());
+ this->detailLevelChanged();
}
- void ParticleInterface::detailLevelChanged(unsigned int newlevel)
+ void ParticleInterface::detailLevelChanged()
{
- if (newlevel >= static_cast<unsigned int>(this->detaillevel_))
+ if (this->globalDetailLevel_ >= this->detaillevel_)
this->bAllowedByLOD_ = true;
else
this->bAllowedByLOD_ = false;
Modified: trunk/src/orxonox/tools/ParticleInterface.h
===================================================================
--- trunk/src/orxonox/tools/ParticleInterface.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/tools/ParticleInterface.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -46,6 +46,7 @@
public:
ParticleInterface(Ogre::SceneManager* scenemanager, const std::string& templateName, LODParticle::Value detaillevel);
virtual ~ParticleInterface();
+ void setConfigValues();
inline Ogre::ParticleSystem* getParticleSystem()
{ return this->particleSystem_; }
@@ -76,7 +77,6 @@
inline bool isVisible() const
{ return this->bVisible_; }
- void detailLevelChanged(unsigned int newlevel);
void setDetailLevel(unsigned int level);
inline void storeThisAsCurrentParticleInterface()
@@ -89,15 +89,19 @@
private:
void updateVisibility();
+ void detailLevelChanged();
Ogre::ParticleSystem* particleSystem_;
Ogre::SceneManager* scenemanager_;
bool bVisible_;
bool bEnabled_;
bool bAllowedByLOD_;
- unsigned int detaillevel_; //!< Detail level of this particle effect (0: off, 1: low, 2: normal, 3: high)
+ unsigned int detaillevel_; //!< Detail level of this particle effect (0: off, 1: low, 2: normal, 3: high)
float speedFactor_;
+ // config values
+ unsigned int globalDetailLevel_; //!< Global maximum detail level of particle effects (0: off, 1: low, 2: normal, 3: high)
+
static ParticleInterface* currentParticleInterface_s;
static unsigned int counter_s;
};
Modified: trunk/src/orxonox/tools/Shader.cc
===================================================================
--- trunk/src/orxonox/tools/Shader.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/orxonox/tools/Shader.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -40,7 +40,7 @@
#include "core/CoreIncludes.h"
#include "core/GameMode.h"
-#include "GraphicsManager.h"
+#include "core/GraphicsManager.h"
namespace orxonox
{
Modified: trunk/src/util/ScopeGuard.h
===================================================================
--- trunk/src/util/ScopeGuard.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/util/ScopeGuard.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -123,10 +123,10 @@
fun_();
}
- protected:
ScopeGuardImpl0(F fun) : fun_(fun)
{}
+ protected:
F fun_;
};
@@ -170,10 +170,10 @@
fun_(p1_);
}
- protected:
ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1)
{}
+ protected:
F fun_;
const P1 p1_;
};
@@ -218,10 +218,10 @@
fun_(p1_, p2_);
}
- protected:
ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2)
{}
+ protected:
F fun_;
const P1 p1_;
const P2 p2_;
@@ -267,10 +267,10 @@
fun_(p1_, p2_, p3_);
}
- protected:
ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3)
{}
+ protected:
F fun_;
const P1 p1_;
const P2 p2_;
@@ -318,11 +318,11 @@
fun_( p1_, p2_, p3_, p4_ );
}
- protected:
ScopeGuardImpl4( F fun, P1 p1, P2 p2, P3 p3, P4 p4 ) :
fun_( fun ), p1_( p1 ), p2_( p2 ), p3_( p3 ), p4_( p4 )
{}
+ protected:
F fun_;
const P1 p1_;
const P2 p2_;
@@ -371,11 +371,11 @@
fun_( p1_, p2_, p3_, p4_, p5_ );
}
- protected:
ScopeGuardImpl5( F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 ) :
fun_( fun ), p1_( p1 ), p2_( p2 ), p3_( p3 ), p4_( p4 ), p5_( p5 )
{}
+ protected:
F fun_;
const P1 p1_;
const P2 p2_;
@@ -425,10 +425,10 @@
(obj_.*memFun_)();
}
- protected:
ObjScopeGuardImpl0(Obj& obj, MemFun memFun) : obj_(obj), memFun_(memFun)
{}
+ protected:
Obj& obj_;
MemFun memFun_;
};
@@ -487,10 +487,10 @@
(obj_.*memFun_)(p1_);
}
- protected:
ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) : obj_(obj), memFun_(memFun), p1_(p1)
{}
+ protected:
Obj& obj_;
MemFun memFun_;
const P1 p1_;
@@ -550,10 +550,10 @@
(obj_.*memFun_)(p1_, p2_);
}
- protected:
ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2)
{}
+ protected:
Obj& obj_;
MemFun memFun_;
const P1 p1_;
@@ -615,11 +615,11 @@
( obj_.*memFun_ )( p1_, p2_, p3_ );
}
- protected:
ObjScopeGuardImpl3( Obj & obj, MemFun memFun, P1 p1, P2 p2, P3 p3 ) :
obj_( obj ), memFun_( memFun ), p1_( p1 ), p2_( p2 ), p3_( p3 )
{}
+ protected:
Obj& obj_;
MemFun memFun_;
const P1 p1_;
Modified: trunk/src/util/SignalHandler.cc
===================================================================
--- trunk/src/util/SignalHandler.cc 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/util/SignalHandler.cc 2009-07-30 12:10:44 UTC (rev 3370)
@@ -40,7 +40,7 @@
namespace orxonox
{
- SignalHandler* SignalHandler::singletonRef_s = NULL;
+ SignalHandler* SignalHandler::singletonPtr_s = NULL;
}
#ifdef ORXONOX_PLATFORM_LINUX
@@ -121,7 +121,7 @@
break;
}
// if the signalhandler has already been destroyed then don't do anything
- if( SignalHandler::singletonRef_s == 0 )
+ if( SignalHandler::singletonPtr_s == 0 )
{
COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "can't write backtrace because SignalHandler already destroyed" << std::endl;
exit(EXIT_FAILURE);
Modified: trunk/src/util/SignalHandler.h
===================================================================
--- trunk/src/util/SignalHandler.h 2009-07-30 12:04:22 UTC (rev 3369)
+++ trunk/src/util/SignalHandler.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -39,6 +39,7 @@
#include <cassert>
#include <list>
#include <string>
+#include "Singleton.h"
namespace orxonox
{
@@ -66,12 +67,12 @@
typedef std::list<SignalRec> SignalRecList;
typedef std::list<SignalCallbackRec> SignalCallbackList;
- class SignalHandler
+ class SignalHandler : public Singleton<SignalHandler>
{
+ friend class Singleton<SignalHandler>;
public:
- SignalHandler() { assert(SignalHandler::singletonRef_s == 0); SignalHandler::singletonRef_s = this; }
- ~SignalHandler() { assert(SignalHandler::singletonRef_s != 0); SignalHandler::singletonRef_s = NULL; }
- inline static SignalHandler& getInstance() { assert(SignalHandler::singletonRef_s); return *SignalHandler::singletonRef_s; }
+ SignalHandler() { }
+ ~SignalHandler() { }
void registerCallback( SignalCallback cb, void * someData );
@@ -86,7 +87,7 @@
SignalCallbackList callbackList;
- static SignalHandler* singletonRef_s;
+ static SignalHandler* singletonPtr_s;
std::string appName;
std::string filename;
@@ -97,18 +98,18 @@
namespace orxonox
{
- class _UtilExport SignalHandler
+ class _UtilExport SignalHandler : public Singleton<SignalHandler>
{
+ friend class Singleton<SignalHandler>;
public:
- SignalHandler() { assert(SignalHandler::singletonRef_s == 0); SignalHandler::singletonRef_s = this; }
- ~SignalHandler() { assert(SignalHandler::singletonRef_s != 0); SignalHandler::singletonRef_s = 0; }
- inline static SignalHandler& getInstance() { assert(SignalHandler::singletonRef_s); return *SignalHandler::singletonRef_s; }
+ SignalHandler() { }
+ ~SignalHandler() { }
void doCatch( const std::string & appName, const std::string & filename ) {}
void dontCatch() {}
void registerCallback( SignalCallback cb, void * someData ) {}
private:
- static SignalHandler* singletonRef_s;
+ static SignalHandler* singletonPtr_s;
};
}
Copied: trunk/src/util/Singleton.h (from rev 3367, branches/resource/src/util/Singleton.h)
===================================================================
--- trunk/src/util/Singleton.h (rev 0)
+++ trunk/src/util/Singleton.h 2009-07-30 12:10:44 UTC (rev 3370)
@@ -0,0 +1,77 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Reto Grieder
+ * Co-authors:
+ * ...
+ *
+ */
+
+#ifndef __Util_Singleton_H__
+#define __Util_Singleton_H__
+
+#include "UtilPrereqs.h"
+#include <cassert>
+
+namespace orxonox
+{
+ /**
+ @brief
+ Base for singleton classes.
+
+ Usage:
+ Inherit publicly from Singleton<MyClass> and provide access to
+ MyClass::singletonPtr_s.
+ This can easily be done with a friend declaration.
+ */
+ template <class T>
+ class Singleton
+ {
+ public:
+ //! Returns a reference to the singleton instance
+ static T& getInstance()
+ {
+ assert(T::singletonPtr_s != 0);
+ return *T::singletonPtr_s;
+ }
+
+ protected:
+ //! Constructor sets the singleton instance pointer
+ Singleton()
+ {
+ assert(T::singletonPtr_s == 0);
+ T::singletonPtr_s = static_cast<T*>(this);
+ }
+
+ //! Constructor resets the singleton instance pointer
+ ~Singleton()
+ {
+ assert(T::singletonPtr_s != 0);
+ T::singletonPtr_s = 0;
+ }
+
+ private:
+ Singleton(const Singleton& rhs); //!< Don't use (undefined)
+ };
+}
+
+#endif /* __Util_Singleton_H__ */
More information about the Orxonox-commit
mailing list