Changeset 2896 for code/trunk/src/core
- Timestamp:
- Apr 6, 2009, 1:59:00 AM (16 years ago)
- Location:
- code/trunk
- Files:
-
- 2 deleted
- 32 edited
- 4 copied
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
/code/branches/gui merged: 2796,2798-2801,2805,2807-2808,2811,2814-2817,2834,2840-2850,2853-2854,2859,2862-2863,2869,2875,2887,2892
- Property svn:mergeinfo changed
-
code/trunk/src/core/CMakeLists.txt
r2710 r2896 24 24 Core.cc 25 25 Event.cc 26 Game.cc 27 GameMode.cc 26 28 GameState.cc 27 29 Language.cc … … 29 31 ObjectListBase.cc 30 32 OrxonoxClass.cc 31 RootGameState.cc32 33 33 34 # command -
code/trunk/src/core/Clock.h
r2171 r2896 45 45 class _CoreExport Clock 46 46 { 47 friend class RootGameState;48 49 47 public: 50 48 Clock(); 51 49 ~Clock(); 50 51 void capture(); 52 52 53 53 unsigned long long getMicroseconds() const { return tickTime_; } … … 63 63 private: 64 64 Clock(const Clock& instance); 65 void capture();66 65 67 66 Ogre::Timer* timer_; -
code/trunk/src/core/ConfigFileManager.cc
r2759 r2896 190 190 this->bUpdated_ = true; 191 191 192 return this->entries_.insert(this->entries_.end(), (ConfigFileEntry*)(new ConfigFileEntryValue(name, fallback, bString)));192 return this->entries_.insert(this->entries_.end(), static_cast<ConfigFileEntry*>(new ConfigFileEntryValue(name, fallback, bString))); 193 193 } 194 194 … … 207 207 208 208 if (index == 0) 209 return this->entries_.insert(this->entries_.end(), (ConfigFileEntry*)(new ConfigFileEntryVectorValue(name, index, fallback, bString)));210 else 211 return this->entries_.insert(++this->getEntryIterator(name, index - 1, "", bString), (ConfigFileEntry*)(new ConfigFileEntryVectorValue(name, index, fallback, bString)));209 return this->entries_.insert(this->entries_.end(), static_cast<ConfigFileEntry*>(new ConfigFileEntryVectorValue(name, index, fallback, bString))); 210 else 211 return this->entries_.insert(++this->getEntryIterator(name, index - 1, "", bString), static_cast<ConfigFileEntry*>(new ConfigFileEntryVectorValue(name, index, fallback, bString))); 212 212 } 213 213 -
code/trunk/src/core/Core.cc
r2759 r2896 22 22 * Author: 23 23 * Fabian 'x3n' Landau 24 * Reto Grieder 24 25 * Co-authors: 25 * Reto Grieder26 * ... 26 27 * 27 28 */ … … 41 42 42 43 #ifdef ORXONOX_PLATFORM_WINDOWS 44 # ifndef WIN32_LEAN_AND_MEAN 45 # define WIN32_LEAN_AND_MEAN 46 # endif 43 47 # include <windows.h> 44 48 #elif defined(ORXONOX_PLATFORM_APPLE) … … 51 55 52 56 #include "SpecialConfig.h" 57 #include "util/Debug.h" 53 58 #include "util/Exception.h" 59 #include "util/SignalHandler.h" 60 #include "Clock.h" 61 #include "CommandExecutor.h" 62 #include "CommandLine.h" 63 #include "ConfigFileManager.h" 64 #include "ConfigValueIncludes.h" 65 #include "CoreIncludes.h" 66 #include "Factory.h" 67 #include "Identifier.h" 54 68 #include "Language.h" 55 #include "CoreIncludes.h"56 #include "ConfigValueIncludes.h"57 69 #include "LuaBind.h" 58 #include "CommandLine.h" 70 #include "Shell.h" 71 #include "TclBind.h" 72 #include "TclThreadManager.h" 59 73 60 74 namespace orxonox … … 67 81 static boost::filesystem::path logPath_g; //!< Path to the log file folder 68 82 69 bool Core::bShowsGraphics_s = false;70 bool Core::bHasServer_s = false;71 bool Core::bIsClient_s = false;72 bool Core::bIsStandalone_s = false;73 bool Core::bIsMaster_s = false;74 75 bool Core::isDevBuild_s = false;76 83 Core* Core::singletonRef_s = 0; 77 84 78 85 SetCommandLineArgument(mediaPath, "").information("PATH"); 79 SetCommandLineArgument(directory, "").information("DIR"); 80 81 /** 82 @brief Constructor: Registers the object and sets the config-values. 83 @param A reference to a global variable, used to avoid an infinite recursion in getSoftDebugLevel() 84 */ 86 SetCommandLineArgument(writingPathSuffix, "").information("DIR"); 87 SetCommandLineArgument(settingsFile, "orxonox.ini"); 88 SetCommandLineArgument(limitToCPU, 0).information("0: off | #cpu"); 89 85 90 Core::Core() 86 91 { … … 89 94 assert(Core::singletonRef_s == 0); 90 95 Core::singletonRef_s = this; 91 92 this->bInitializeRandomNumberGenerator_ = false; 93 this->setConfigValues(); 96 } 97 98 void Core::initialise(int argc, char** argv) 99 { 100 // Parse command line arguments fist 101 try 102 { 103 CommandLine::parseAll(argc, argv); 104 } 105 catch (ArgumentException& ex) 106 { 107 COUT(1) << ex.what() << std::endl; 108 COUT(0) << "Usage:" << std::endl << "orxonox " << CommandLine::getUsageInformation() << std::endl; 109 } 110 111 // limit the main thread to the first core so that QueryPerformanceCounter doesn't jump 112 // do this after ogre has initialised. Somehow Ogre changes the settings again (not through 113 // the timer though). 114 int limitToCPU = CommandLine::getValue("limitToCPU"); 115 if (limitToCPU > 0) 116 setThreadAffinity((unsigned int)limitToCPU); 117 118 // Determine and set the location of the executable 119 setExecutablePath(); 120 121 // Determine whether we have an installed or a binary dir run 122 // The latter occurs when simply running from the build directory 123 checkDevBuild(); 124 125 // Make sure the directories we write in exist or else make them 126 createDirectories(); 127 128 // create a signal handler (only active for linux) 129 // This call is placed as soon as possible, but after the directories are set 130 this->signalHandler_ = new SignalHandler(); 131 this->signalHandler_->doCatch(executablePath_g.string(), Core::getLogPathString() + "orxonox_crash.log"); 94 132 95 133 // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used 96 134 OutputHandler::getOutStream().setLogPath(Core::getLogPathString()); 97 135 136 // Manage ini files and set the default settings file (usually orxonox.ini) 137 this->configFileManager_ = new ConfigFileManager(); 138 this->configFileManager_->setFilename(ConfigFileType::Settings, 139 CommandLine::getValue("settingsFile").getString()); 140 141 this->languageInstance_ = new Language(); 142 143 // Do this soon after the ConfigFileManager has been created to open up the 144 // possibility to configure everything below here 145 this->setConfigValues(); 146 98 147 // Possible media path override by the command line 99 148 if (!CommandLine::getArgument("mediaPath")->hasDefaultValue()) … … 102 151 Core::tsetMediaPath(CommandLine::getValue("mediaPath")); 103 152 } 153 154 // Create the lua interface 155 this->luaBind_ = new LuaBind(); 156 157 // initialise Tcl 158 this->tclBind_ = new TclBind(Core::getMediaPathString()); 159 this->tclThreadManager_ = new TclThreadManager(tclBind_->getTclInterpreter()); 160 161 // create a shell 162 this->shell_ = new Shell(); 163 164 // creates the class hierarchy for all classes with factories 165 Factory::createClassHierarchy(); 166 167 this->loaded_ = true; 104 168 } 105 169 … … 109 173 Core::~Core() 110 174 { 175 this->loaded_ = false; 176 177 delete this->shell_; 178 delete this->tclThreadManager_; 179 delete this->tclBind_; 180 delete this->luaBind_; 181 delete this->languageInstance_; 182 delete this->configFileManager_; 183 delete this->signalHandler_; 184 185 // Destroy command line arguments 186 CommandLine::destroyAllArguments(); 187 // Also delete external console command that don't belong to an Identifier 188 CommandExecutor::destroyExternalCommands(); 189 111 190 assert(Core::singletonRef_s); 112 191 Core::singletonRef_s = 0; … … 292 371 } 293 372 294 /** 295 @brief 296 Performs the rather lower level operations just after 297 int main() has been called. 298 @remarks 299 This gets called AFTER pre-main stuff like AddFactory, 300 SetConsoleCommand, etc. 301 */ 302 /*static*/ void Core::postMainInitialisation() 303 { 304 // set location of the executable 305 Core::setExecutablePath(); 306 307 // Determine whether we have an installed or a binary dir run 308 // The latter occurs when simply running from the build directory 309 Core::checkDevBuild(); 310 311 // Make sure the directories we write in exist or else make them 312 Core::createDirectories(); 373 374 /** 375 @note 376 The code of this function has been copied and adjusted from OGRE, an open source graphics engine. 377 (Object-oriented Graphics Rendering Engine) 378 For the latest info, see http://www.ogre3d.org/ 379 380 Copyright (c) 2000-2008 Torus Knot Software Ltd 381 382 OGRE is licensed under the LGPL. For more info, see OGRE license. 383 */ 384 void Core::setThreadAffinity(int limitToCPU) 385 { 386 if (limitToCPU <= 0) 387 return; 388 389 #ifdef ORXONOX_PLATFORM_WINDOWS 390 unsigned int coreNr = limitToCPU - 1; 391 // Get the current process core mask 392 DWORD procMask; 393 DWORD sysMask; 394 # if _MSC_VER >= 1400 && defined (_M_X64) 395 GetProcessAffinityMask(GetCurrentProcess(), (PDWORD_PTR)&procMask, (PDWORD_PTR)&sysMask); 396 # else 397 GetProcessAffinityMask(GetCurrentProcess(), &procMask, &sysMask); 398 # endif 399 400 // If procMask is 0, consider there is only one core available 401 // (using 0 as procMask will cause an infinite loop below) 402 if (procMask == 0) 403 procMask = 1; 404 405 // if the core specified with coreNr is not available, take the lowest one 406 if (!(procMask & (1 << coreNr))) 407 coreNr = 0; 408 409 // Find the lowest core that this process uses and coreNr suggests 410 DWORD threadMask = 1; 411 while ((threadMask & procMask) == 0 || (threadMask < (1u << coreNr))) 412 threadMask <<= 1; 413 414 // Set affinity to the first core 415 SetThreadAffinityMask(GetCurrentThread(), threadMask); 416 #endif 313 417 } 314 418 … … 317 421 Compares the executable path with the working directory 318 422 */ 319 /*static*/void Core::setExecutablePath()423 void Core::setExecutablePath() 320 424 { 321 425 #ifdef ORXONOX_PLATFORM_WINDOWS … … 369 473 don't write the logs and config files to ~/.orxonox 370 474 */ 371 /*static*/void Core::checkDevBuild()475 void Core::checkDevBuild() 372 476 { 373 477 if (boost::filesystem::exists(executablePath_g / "orxonox_dev_build.keep_me")) 374 478 { 375 479 COUT(1) << "Running from the build tree." << std::endl; 376 Core::isDevBuild_ s= true;480 Core::isDevBuild_ = true; 377 481 mediaPath_g = ORXONOX_MEDIA_DEV_PATH; 378 482 configPath_g = ORXONOX_CONFIG_DEV_PATH; … … 385 489 boost::filesystem::path relativeExecutablePath(ORXONOX_RUNTIME_INSTALL_PATH); 386 490 rootPath_g = executablePath_g; 387 while (!boost::filesystem::equivalent(rootPath_g / relativeExecutablePath, executablePath_g) ||rootPath_g.empty())491 while (!boost::filesystem::equivalent(rootPath_g / relativeExecutablePath, executablePath_g) && !rootPath_g.empty()) 388 492 rootPath_g = rootPath_g.branch_path(); 389 493 if (rootPath_g.empty()) … … 416 520 417 521 // Option to put all the config and log files in a separate folder 418 if (!CommandLine::getArgument(" directory")->hasDefaultValue())419 { 420 std::string directory(CommandLine::getValue(" directory").getString());522 if (!CommandLine::getArgument("writingPathSuffix")->hasDefaultValue()) 523 { 524 std::string directory(CommandLine::getValue("writingPathSuffix").getString()); 421 525 configPath_g = configPath_g / directory; 422 526 logPath_g = logPath_g / directory; … … 429 533 if necessary. Otherwise me might have problems opening those files. 430 534 */ 431 /*static*/void Core::createDirectories()535 void Core::createDirectories() 432 536 { 433 537 std::vector<std::pair<boost::filesystem::path, std::string> > directories; … … 451 555 } 452 556 } 557 558 void Core::update(const Clock& time) 559 { 560 this->tclThreadManager_->update(time); 561 } 453 562 } -
code/trunk/src/core/Core.h
r2759 r2896 22 22 * Author: 23 23 * Fabian 'x3n' Landau 24 * Reto Grieder 24 25 * Co-authors: 25 * Reto Grieder26 * ... 26 27 * 27 28 */ … … 44 45 #include "util/OutputHandler.h" 45 46 46 // Only allow main to access postMainInitialisation, so we need a forward declaration47 int main(int, char**);48 47 // boost::filesystem header has quite a large tail, use forward declaration 49 48 namespace boost { namespace filesystem … … 59 58 class _CoreExport Core : public OrxonoxClass 60 59 { 61 friend int ::main(int, char**); // sets isDevBuild_s62 63 60 public: 64 61 Core(); 65 62 ~Core(); 63 64 void initialise(int argc, char** argv); 66 65 void setConfigValues(); 66 67 void update(const Clock& time); 67 68 68 69 static Core& getInstance() { assert(Core::singletonRef_s); return *Core::singletonRef_s; } … … 72 73 static const std::string& getLanguage(); 73 74 static void resetLanguage(); 74 75 static bool isDevBuild() { return Core::isDevBuild_s; }76 75 77 76 static void tsetMediaPath(const std::string& path) … … 84 83 static std::string getLogPathString(); 85 84 86 // fast access global variables.87 static bool showsGraphics() { return bShowsGraphics_s; }88 static bool hasServer() { return bHasServer_s; }89 static bool isClient() { return bIsClient_s; }90 static bool isStandalone() { return bIsStandalone_s; }91 static bool isMaster() { return bIsMaster_s; }92 static void setShowsGraphics(bool val) { bShowsGraphics_s = val; updateIsMaster(); }93 static void setHasServer (bool val) { bHasServer_s = val; updateIsMaster(); }94 static void setIsClient (bool val) { bIsClient_s = val; updateIsMaster(); }95 static void setIsStandalone (bool val) { bIsStandalone_s = val; updateIsMaster(); }96 static void updateIsMaster () { bIsMaster_s = (bHasServer_s || bIsStandalone_s); }97 98 85 private: 99 86 Core(const Core&); 87 88 void checkDevBuild(); 89 void setExecutablePath(); 90 void createDirectories(); 91 void setThreadAffinity(int limitToCPU); 92 100 93 void resetLanguageIntern(); 101 94 void initializeRandomNumberGenerator(); … … 105 98 void _tsetMediaPath(const std::string& path); 106 99 107 static void postMainInitialisation(); 108 static void checkDevBuild(); 109 static void setExecutablePath(); 110 static void createDirectories(); 100 // Singletons 101 ConfigFileManager* configFileManager_; 102 Language* languageInstance_; 103 LuaBind* luaBind_; 104 Shell* shell_; 105 SignalHandler* signalHandler_; 106 TclBind* tclBind_; 107 TclThreadManager* tclThreadManager_; 111 108 112 109 int softDebugLevel_; //!< The debug level … … 117 114 bool bInitializeRandomNumberGenerator_; //!< If true, srand(time(0)) is called 118 115 std::string mediaPathString_; //!< Path to the data/media file folder as string 119 120 static bool bShowsGraphics_s; //!< global variable that tells whether to show graphics 121 static bool bHasServer_s; //!< global variable that tells whether this is a server 122 static bool bIsClient_s; 123 static bool bIsStandalone_s; 124 static bool bIsMaster_s; 125 126 static bool isDevBuild_s; //!< True for builds in the build directory (not installed) 116 bool isDevBuild_; //!< True for builds in the build directory (not installed) 117 bool loaded_; //!< Only true if constructor was interrupted 127 118 128 119 static Core* singletonRef_s; -
code/trunk/src/core/CorePrereqs.h
r2710 r2896 166 166 167 167 // game states 168 class GameStateBase; 169 template <class ParentType> 168 class Game; 170 169 class GameState; 171 class RootGameState;170 struct GameStateTreeNode; 172 171 173 172 // input -
code/trunk/src/core/GameState.cc
r1764 r2896 30 30 @file 31 31 @brief 32 Implementation of GameState Baseclass.32 Implementation of GameState class. 33 33 */ 34 34 35 35 #include "GameState.h" 36 #include <cassert> 36 37 #include "util/Debug.h" 37 38 #include "util/Exception.h" 39 #include "Clock.h" 38 40 39 41 namespace orxonox … … 43 45 Constructor only initialises variables and sets the name permanently. 44 46 */ 45 GameState Base::GameStateBase(const std::string& name)47 GameState::GameState(const std::string& name) 46 48 : name_(name) 47 //, parent_(0) 48 , activeChild_(0) 49 //, bPausegetParent()(false) 49 , parent_(0) 50 50 { 51 Operations temp = {false, false, false, false, false}; 52 this->operation_ = temp; 51 this->activity_.activating = false; 52 this->activity_.active = false; 53 this->activity_.deactivating = false; 54 this->activity_.suspended = false; 55 this->activity_.topState = false; 56 this->activity_.updating = false; 53 57 } 54 58 … … 57 61 Destructor only checks that we don't delete an active state. 58 62 */ 59 GameState Base::~GameStateBase()63 GameState::~GameState() 60 64 { 61 OrxAssert(this-> operation_.active == false, "Deleting an active GameState is a very bad idea..");65 OrxAssert(this->activity_.active == false, "Deleting an active GameState is a very bad idea.."); 62 66 } 63 67 … … 69 73 The state to be added. 70 74 */ 71 void GameState Base::addChild(GameStateBase* state)75 void GameState::addChild(GameState* state) 72 76 { 73 if (!state) 74 return; 75 // check if the state/tree to be added has states in it that already exist in this tree. 76 for (std::map<std::string, GameStateBase*>::const_iterator it = state->allChildren_.begin(); 77 it != state->allChildren_.end(); ++it) 77 assert(state != NULL); 78 79 std::map<std::string, GameState*>::const_iterator it = this->children_.find(state->getName()); 80 if (it == this->children_.end()) 78 81 { 79 if (this->getState(it->second->getName())) 80 { 81 ThrowException(GameState, "Cannot add a GameState to the hierarchy twice."); 82 return; 83 } 82 this->children_[state->getName()] = state; 83 // mark us as parent 84 state->setParent(this); 84 85 } 85 if (this->getState(state->name_))86 else 86 87 { 87 ThrowException(GameState, "Cannot add a GameState to the hierarchy twice."); 88 return; 88 ThrowException(GameState, "Cannot add two children with the same name"); 89 89 } 90 // Make sure we don't add a tree that already has an active state.91 if (state->getCurrentState())92 {93 ThrowException(GameState, "Cannot merge a tree that is already active.");94 return;95 }96 97 // merge the child's children into this tree98 for (std::map<std::string, GameStateBase*>::const_iterator it = state->allChildren_.begin();99 it != state->allChildren_.end(); ++it)100 this->grandchildAdded(state, it->second);101 // merge 'state' into this tree102 this->grandchildAdded(state, state);103 104 // mark us as parent105 state->setParent(this);106 90 } 107 91 … … 113 97 GameState by instance pointer 114 98 */ 115 void GameState Base::removeChild(GameStateBase* state)99 void GameState::removeChild(GameState* state) 116 100 { 117 std::map<GameStateBase*, GameStateBase*>::iterator it = this->grandchildrenToChildren_.find(state); 118 if (it != this->grandchildrenToChildren_.end()) 119 { 120 if (state->isInSubtree(getCurrentState())) 121 { 122 ThrowException(GameState, "Cannot remove an active game state child '" 123 + state->getName() + "' from '" + name_ + "'."); 124 //COUT(2) << "Warning: Cannot remove an active game state child '" << state->getName() 125 // << "' from '" << name_ << "'." << std::endl; 126 } 127 else 128 { 129 for (std::map<GameStateBase*, GameStateBase*>::const_iterator it = state->grandchildrenToChildren_.begin(); 130 it != state->grandchildrenToChildren_.end(); ++it) 131 this->grandchildRemoved(it->first); 132 this->grandchildRemoved(state); 133 } 134 } 101 assert(state != NULL); 102 103 std::map<std::string, GameState*>::iterator it = this->children_.find(state->getName()); 104 if (it != this->children_.end()) 105 this->children_.erase(it); 135 106 else 136 107 { 137 108 ThrowException(GameState, "Game state '" + name_ + "' doesn't have a child named '" 138 109 + state->getName() + "'."); 139 //COUT(2) << "Warning: Game state '" << name_ << "' doesn't have a child named '"140 // << state->getName() << "'. Removal skipped." << std::endl;141 110 } 142 111 } 143 112 144 /** 145 @brief 146 Removes a child by name. This splits the tree in two parts, 147 each of them functional on its own. 148 @param state 149 GameState by name 150 */ 151 152 void GameStateBase::removeChild(const std::string& name) 113 void GameState::activateInternal() 153 114 { 154 GameStateBase* state = getState(name); 155 if (state) 156 { 157 removeChild(state); 158 } 159 else 160 { 161 ThrowException(GameState, "GameState '" + name + "' doesn't exist."); 162 //COUT(2) << "Warning: GameState '" << name << "' doesn't exist." << std::endl; 163 } 115 this->activity_.activating = true; 116 this->activate(); 117 this->activity_.activating = false; 118 this->activity_.active = true; 164 119 } 165 120 166 /** 167 @brief 168 Tells a state that one of its children has added a child. This is necessary 169 to fill the internal maps correctly. 170 @param child 171 The child who notices this state. 172 @param grandchild 173 The child that has been added. 174 */ 175 inline void GameStateBase::grandchildAdded(GameStateBase* child, GameStateBase* grandchild) 121 void GameState::deactivateInternal() 176 122 { 177 // fill the two maps correctly. 178 this->allChildren_[grandchild->getName()] = grandchild; 179 this->grandchildrenToChildren_[grandchild] = child; 180 if (this->getParent()) 181 this->getParent()->grandchildAdded(this, grandchild); 123 this->activity_.active = false; 124 this->activity_.deactivating = true; 125 this->activate(); 126 this->activity_.deactivating = false; 127 this->activity_.suspended = false; 128 this->activity_.updating = false; 182 129 } 183 130 184 /** 185 @brief 186 Tells a state that one of its children has removed a child. This is necessary 187 to fill the internal maps correctly. 188 @param child 189 The child who notices this state. 190 @param grandchild 191 The child that has been removed. 192 */ 193 inline void GameStateBase::grandchildRemoved(GameStateBase* grandchild) 131 void GameState::updateInternal(const Clock& time) 194 132 { 195 // adjust the two maps correctly. 196 this->allChildren_.erase(grandchild->getName()); 197 this->grandchildrenToChildren_.erase(grandchild); 198 if (this->getParent()) 199 this->getParent()->grandchildRemoved(grandchild); 200 } 201 202 /** 203 @brief 204 Checks whether a specific game states exists in the hierarchy. 205 @remarks 206 Remember that the every node has a map with all its child nodes. 207 */ 208 GameStateBase* GameStateBase::getState(const std::string& name) 209 { 210 if (this->getParent()) 211 return this->getParent()->getState(name); 212 else 213 { 214 // The map only contains children, so check ourself first 215 if (name == this->name_) 216 return this; 217 // Search in the map. If there is no entry, we can be sure the state doesn't exist. 218 std::map<std::string, GameStateBase*>::const_iterator it = this->allChildren_.find(name); 219 return (it!= this->allChildren_.end() ? it->second : 0); 220 } 221 } 222 223 /** 224 @brief 225 Returns the root node of the tree. 226 */ 227 GameStateBase* GameStateBase::getRoot() 228 { 229 if (this->getParent()) 230 return this->getParent()->getRoot(); 231 else 232 return this; 233 } 234 235 /** 236 @brief 237 Returns the current active state. 238 @remarks 239 Remember that the current active state is the one that does not 240 have active children itself. Many states can be active at once. 241 */ 242 GameStateBase* GameStateBase::getCurrentState() 243 { 244 if (this->operation_.active) 245 { 246 if (this->activeChild_) 247 return this->activeChild_->getCurrentState(); 248 else 249 return this; 250 } 251 else 252 { 253 if (this->getParent()) 254 return this->getParent()->getCurrentState(); 255 else 256 return 0; 257 } 258 } 259 260 /** 261 @brief 262 Determines whether 'state' is in this subtree, including this node. 263 */ 264 bool GameStateBase::isInSubtree(GameStateBase* state) const 265 { 266 return (grandchildrenToChildren_.find(state) != grandchildrenToChildren_.end() 267 || state == this); 268 } 269 270 /** 271 @brief 272 Makes a state transition according to the state tree. You can choose any state 273 in the tree to do the call. The function finds the current state on its own. 274 @param state 275 The state to be entered, has to exist in the tree. 276 */ 277 void GameStateBase::requestState(const std::string& name) 278 { 279 assert(getRoot()); 280 getRoot()->requestState(name); 281 } 282 283 /** 284 @brief 285 Internal method that actually makes the state transition. Since it is internal, 286 the method can assume certain things to be granted (like 'this' is always active). 287 */ 288 void GameStateBase::makeTransition(GameStateBase* source, GameStateBase* destination) 289 { 290 if (source == this->getParent()) 291 { 292 // call is from the parent 293 this->activate(); 294 } 295 else if (source == 0) 296 { 297 // call was just started by root 298 // don't do anyting yet 299 } 300 else 301 { 302 // call is from a child 303 this->activeChild_ = 0; 304 } 305 306 if (destination == this) 307 return; 308 309 // Check for 'destination' in the children map first 310 std::map<GameStateBase*, GameStateBase*>::const_iterator it 311 = this->grandchildrenToChildren_.find(destination); 312 if (it != this->grandchildrenToChildren_.end()) 313 { 314 // child state. Don't use 'state', might be a grandchild! 315 this->activeChild_ = it->second; 316 it->second->makeTransition(this, destination); 317 } 318 else 319 { 320 // parent. We can be sure of this. 321 assert(this->getParent() != 0); 322 323 this->deactivate(); 324 this->getParent()->makeTransition(this, destination); 325 } 326 } 327 328 /** 329 @brief 330 Activates the state. Only sets bActive_ to true and notifies the parent. 331 */ 332 void GameStateBase::activate() 333 { 334 this->operation_.active = true; 335 this->operation_.entering = true; 336 this->enter(); 337 this->operation_.entering = false; 338 } 339 340 /** 341 Activates the state. Only sets bActive_ to false and notifies the parent. 342 */ 343 void GameStateBase::deactivate() 344 { 345 this->operation_.leaving = true; 346 this->leave(); 347 this->operation_.leaving = false; 348 this->operation_.active = false; 349 } 350 351 /** 352 @brief 353 Update method that calls ticked() with enclosed bRunning_ = true 354 If there was a state transition request within ticked() then this 355 method will transition in the end. 356 @param dt Delta time 357 @note 358 This method is not virtual! You cannot override it therefore. 359 */ 360 void GameStateBase::tick(const Clock& time) 361 { 362 this->operation_.running = true; 363 this->ticked(time); 364 this->operation_.running = false; 133 this->activity_.updating = true; 134 this->update(time); 135 this->activity_.updating = false; 365 136 } 366 137 } -
code/trunk/src/core/GameState.h
r1755 r2896 39 39 40 40 #include <string> 41 #include <vector>42 41 #include <map> 43 #include <cassert> 44 #include "Clock.h" 42 #include "CorePrereqs.h" 45 43 46 44 namespace orxonox … … 60 58 Then Bar stores Foo in map by its name. The other one then maps Foo to Foofoo. 61 59 */ 62 class _CoreExport GameState Base60 class _CoreExport GameState 63 61 { 64 friend class RootGameState; 65 template <class ParentType> 66 friend class GameState; 62 friend class Game; 67 63 68 64 public: … … 71 67 Gives information about what the GameState is currently doing 72 68 */ 73 struct Operations69 struct State 74 70 { 75 unsigned active : 1; 76 unsigned entering : 1; 77 unsigned leaving : 1; 78 unsigned running : 1; 79 unsigned suspended : 1; 71 unsigned active : 1; 72 unsigned activating : 1; 73 unsigned deactivating : 1; 74 unsigned updating : 1; 75 unsigned suspended : 1; 76 unsigned topState : 1; 80 77 }; 81 78 82 79 public: 83 virtual ~GameStateBase(); 80 GameState(const std::string& name); 81 virtual ~GameState(); 84 82 85 83 const std::string& getName() const { return name_; } 86 const Operations getOperation() const { return this->operation_; }87 bool isInSubtree(GameStateBase* state) const;84 State getActivity() const { return this->activity_; } 85 GameState* getParent() const { return this->parent_; } 88 86 89 GameStateBase* getState(const std::string& name); 90 GameStateBase* getRoot(); 91 //! Returns the currently active game state 92 virtual GameStateBase* getCurrentState(); 93 94 virtual void requestState(const std::string& name); 95 96 void addChild(GameStateBase* state); 97 void removeChild(GameStateBase* state); 98 void removeChild(const std::string& name); 87 void addChild(GameState* state); 88 void removeChild(GameState* state); 99 89 100 90 protected: 101 virtual void enter() = 0; 102 virtual void leave() = 0; 103 virtual void ticked(const Clock& time) = 0; 104 105 GameStateBase* getActiveChild() { return this->activeChild_; } 106 107 void tickChild(const Clock& time) { if (this->getActiveChild()) this->getActiveChild()->tick(time); } 108 109 virtual GameStateBase* getParent() const = 0; 110 virtual void setParent(GameStateBase* state) = 0; 91 virtual void activate() = 0; 92 virtual void deactivate() = 0; 93 virtual void update(const Clock& time) = 0; 111 94 112 95 private: 113 // Making the constructor private ensures that game states 114 // are always derivates of GameState<T>. Note the friend declaration above. 115 GameStateBase(const std::string& name); 116 117 //! Performs a transition to 'destination' 118 virtual void makeTransition(GameStateBase* source, GameStateBase* destination); 119 120 void grandchildAdded(GameStateBase* child, GameStateBase* grandchild); 121 void grandchildRemoved(GameStateBase* grandchild); 122 123 void tick(const Clock& time); 124 void activate(); 125 void deactivate(); 96 void setParent(GameState* state) { this->parent_ = state; } 97 void setActivity(State activity); 98 void activateInternal(); 99 void deactivateInternal(); 100 void updateInternal(const Clock& time); 126 101 127 102 const std::string name_; 128 Operations operation_; 129 GameStateBase* activeChild_; 130 //bool bPauseParent_; 131 std::map<std::string, GameStateBase*> allChildren_; 132 std::map<GameStateBase*, GameStateBase*> grandchildrenToChildren_; 133 }; 134 135 136 template <class ParentType> 137 class GameState : public GameStateBase 138 { 139 public: 140 GameState(const std::string& name) 141 : GameStateBase(name) 142 , parent_(0) 143 { } 144 virtual ~GameState() { } 145 146 ParentType* getParent() const 147 { return parent_; } 148 149 protected: 150 void setParent(GameStateBase* state) 151 { 152 assert(dynamic_cast<ParentType*>(state) != 0); 153 this->parent_ = dynamic_cast<ParentType*>(state); 154 } 155 156 private: 157 ParentType* parent_; 103 State activity_; 104 GameState* parent_; 105 std::map<std::string, GameState*> children_; 158 106 }; 159 107 } -
code/trunk/src/core/Iterator.h
r2784 r2896 181 181 this->list_->unregisterIterator(this); 182 182 183 this->element_ = (other.element_) ? (ObjectListBaseElement*)other.element_: 0;183 this->element_ = (other.element_) ? static_cast<ObjectListBaseElement*>(other.element_) : 0; 184 184 this->list_ = ClassIdentifier<O>::getIdentifier()->getObjects(); 185 185 this->list_->registerIterator(this); -
code/trunk/src/core/LuaBind.cc
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/core/LuaBind.h
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/core/ObjectListBase.h
r2784 r2896 71 71 { 72 72 public: 73 ObjectListElement(T* object) : ObjectListBaseElement( (OrxonoxClass*)object), object_(object) {}73 ObjectListElement(T* object) : ObjectListBaseElement(static_cast<OrxonoxClass*>(object)), object_(object) {} 74 74 T* object_; //!< The object 75 75 }; -
code/trunk/src/core/TclThreadManager.cc
r1792 r2896 35 35 #include <OgreTimer.h> 36 36 37 #include "Clock.h" 37 38 #include "CoreIncludes.h" 38 39 #include "ConsoleCommand.h" … … 598 599 } 599 600 600 void TclThreadManager:: tick(float dt)601 void TclThreadManager::update(const Clock& time) 601 602 { 602 603 { … … 633 634 boost::try_mutex::scoped_lock interpreter_lock(this->orxonoxInterpreterBundle_.interpreterMutex_); 634 635 #endif 635 unsigned long maxtime = (unsigned long)( dt* 1000000 * TCLTHREADMANAGER_MAX_CPU_USAGE);636 unsigned long maxtime = (unsigned long)(time.getDeltaTime() * 1000000 * TCLTHREADMANAGER_MAX_CPU_USAGE); 636 637 Ogre::Timer timer; 637 638 while (!this->queueIsEmpty()) -
code/trunk/src/core/TclThreadManager.h
r2710 r2896 90 90 void debug(const std::string& error); 91 91 92 v irtual void tick(float dt);92 void update(const Clock& time); 93 93 94 94 std::list<unsigned int> getThreadList() const; -
code/trunk/src/core/Template.cc
- Property svn:mergeinfo changed
/code/branches/gui/src/core/Template.cc (added) merged: 2815
r2893 r2896 65 65 if (element) 66 66 { 67 TiXmlElement* tixmlelement = dynamic_cast<TiXmlElement*>(element->GetTiXmlPointer());67 TiXmlElement* tixmlelement = static_cast<TiXmlElement*>(element->GetTiXmlPointer()); 68 68 if (tixmlelement) 69 69 this->setXMLElement(*tixmlelement); … … 138 138 COUT(4) << object->getLoaderIndentation() << " aplying Template \"" << this->getName() << "\"..." << std::endl; 139 139 140 Element temp = ((TiXmlElement*)&this->getXMLElement());140 Element temp = &const_cast<TiXmlElement&>(this->getXMLElement()); 141 141 142 142 if (this->bLoadDefaults_) - Property svn:mergeinfo changed
-
code/trunk/src/core/Template.h
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/core/XMLFile.h
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/core/XMLIncludes.h
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/core/XMLPort.h
r2710 r2896 556 556 try 557 557 { 558 COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "fabricating " << child->Value() << "..." << std::endl;558 COUT(4) << object->getLoaderIndentation() << "fabricating " << child->Value() << "..." << std::endl; 559 559 560 560 BaseObject* newObject = identifier->fabricate((BaseObject*)object); 561 561 assert(newObject); 562 newObject->setLoaderIndentation( ((BaseObject*)object)->getLoaderIndentation() + " ");562 newObject->setLoaderIndentation(object->getLoaderIndentation() + " "); 563 563 564 564 O* castedObject = dynamic_cast<O*>(newObject); … … 568 568 { 569 569 newObject->XMLPort(*child, XMLPort::LoadObject); 570 COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl;570 COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl; 571 571 } 572 572 else 573 573 { 574 COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl;574 COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl; 575 575 } 576 576 577 COUT(5) << ((BaseObject*)object)->getLoaderIndentation();577 COUT(5) << object->getLoaderIndentation(); 578 578 (*this->loadexecutor_)(object, castedObject); 579 579 … … 581 581 newObject->XMLPort(*child, XMLPort::LoadObject); 582 582 583 COUT(5) << ((BaseObject*)object)->getLoaderIndentation() << "...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl;583 COUT(5) << object->getLoaderIndentation() << "...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl; 584 584 } 585 585 catch (AbortLoadingException& ex) … … 601 601 else 602 602 { 603 COUT(2) << ((BaseObject*)object)->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not loadable." << std::endl;603 COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not loadable." << std::endl; 604 604 } 605 605 } 606 606 else 607 607 { 608 COUT(2) << ((BaseObject*)object)->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a '" << Class(O)->getName() << "'." << std::endl;608 COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a '" << Class(O)->getName() << "'." << std::endl; 609 609 } 610 610 } … … 626 626 { 627 627 COUT(1) << std::endl; 628 COUT(1) << "An error occurred in XMLPort.h while loading a '" << Class(O)->getName() << "' in '" << this->sectionname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << ((BaseObject*)object)->getName() << ") in " << object->getFilename() << ":" << std::endl;628 COUT(1) << "An error occurred in XMLPort.h while loading a '" << Class(O)->getName() << "' in '" << this->sectionname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << object->getName() << ") in " << object->getFilename() << ":" << std::endl; 629 629 COUT(1) << ex.what() << std::endl; 630 630 } -
code/trunk/src/core/input/CalibratorCallback.h
r1755 r2896 52 52 void keyHeld (const KeyEvent& evt) { } 53 53 54 void tickInput(float dt) { }54 void updateInput(float dt) { } 55 55 }; 56 56 } -
code/trunk/src/core/input/ExtendedInputState.cc
r2773 r2896 402 402 } 403 403 404 void ExtendedInputState:: tickInput(float dt)404 void ExtendedInputState::updateInput(float dt) 405 405 { 406 406 for (unsigned int i = 0; i < allHandlers_.size(); ++i) 407 407 { 408 allHandlers_[i]-> tickInput(dt);409 } 410 } 411 412 void ExtendedInputState:: tickInput(float dt, unsigned int device)408 allHandlers_[i]->updateInput(dt); 409 } 410 } 411 412 void ExtendedInputState::updateInput(float dt, unsigned int device) 413 413 { 414 414 switch (device) … … 416 416 case Keyboard: 417 417 for (unsigned int i = 0; i < keyHandlers_.size(); ++i) 418 keyHandlers_[i]-> tickKey(dt);418 keyHandlers_[i]->updateKey(dt); 419 419 break; 420 420 421 421 case Mouse: 422 422 for (unsigned int i = 0; i < mouseHandlers_.size(); ++i) 423 mouseHandlers_[i]-> tickMouse(dt);423 mouseHandlers_[i]->updateMouse(dt); 424 424 break; 425 425 426 426 default: // joy sticks 427 427 for (unsigned int i = 0; i < joyStickHandlers_[device - 2].size(); ++i) 428 joyStickHandlers_[device - 2][i]-> tickJoyStick(dt, device - 2);428 joyStickHandlers_[device - 2][i]->updateJoyStick(dt, device - 2); 429 429 break; 430 430 } -
code/trunk/src/core/input/ExtendedInputState.h
r1887 r2896 68 68 ~ExtendedInputState() { } 69 69 70 void tickInput(float dt);71 void tickInput(float dt, unsigned int device);70 void updateInput(float dt); 71 void updateInput(float dt, unsigned int device); 72 72 73 73 void keyPressed (const KeyEvent& evt); -
code/trunk/src/core/input/InputBuffer.cc
r2662 r2896 224 224 225 225 /** 226 @brief This tick() function is called by the InputManager if the InputBuffer is active.226 @brief This update() function is called by the InputManager if the InputBuffer is active. 227 227 @param dt Delta time 228 228 */ 229 void InputBuffer:: tickInput(float dt)229 void InputBuffer::updateInput(float dt) 230 230 { 231 231 timeSinceKeyPressed_ += dt; -
code/trunk/src/core/input/InputBuffer.h
r2662 r2896 127 127 for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ) 128 128 { 129 InputBufferListenerTuple<T>* refListener = dynamic_cast<InputBufferListenerTuple<T>*>(*it);129 InputBufferListenerTuple<T>* refListener = static_cast<InputBufferListenerTuple<T>*>(*it); 130 130 if (refListener && refListener->listener_ == listener) 131 131 this->listeners_.erase(it++); … … 171 171 void processKey (const KeyEvent &e); 172 172 173 void tickInput(float dt);174 void tickKey(float dt) { }173 void updateInput(float dt); 174 void updateKey(float dt) { } 175 175 176 176 std::string buffer_; -
code/trunk/src/core/input/InputInterfaces.h
r2662 r2896 474 474 public: 475 475 virtual ~InputHandler() { } 476 virtual void tickInput(float dt) = 0;476 virtual void updateInput(float dt) = 0; 477 477 }; 478 478 … … 488 488 virtual void keyReleased(const KeyEvent& evt) = 0; 489 489 virtual void keyHeld (const KeyEvent& evt) = 0; 490 virtual void tickKey (float dt) = 0;490 virtual void updateKey (float dt) = 0; 491 491 }; 492 492 … … 504 504 virtual void mouseMoved (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0; 505 505 virtual void mouseScrolled (int abs, int rel) = 0; 506 virtual void tickMouse (float dt) = 0;506 virtual void updateMouse (float dt) = 0; 507 507 }; 508 508 … … 520 520 virtual void joyStickButtonHeld (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0; 521 521 virtual void joyStickAxisMoved (unsigned int joyStickID, unsigned int axis, float value) = 0; 522 virtual void tickJoyStick (float dt, unsigned int joyStick) = 0;522 virtual void updateJoyStick (float dt, unsigned int joyStick) = 0; 523 523 }; 524 524 … … 531 531 virtual ~EmptyHandler() { } 532 532 533 void tickInput(float dt) { }534 void tickJoyStick(float dt, unsigned int joyStick) { }535 void tickMouse(float dt) { }536 void tickKey(float dt) { }533 void updateInput(float dt) { } 534 void updateJoyStick(float dt, unsigned int joyStick) { } 535 void updateMouse(float dt) { } 536 void updateKey(float dt) { } 537 537 538 538 void keyPressed (const KeyEvent& evt) { } -
code/trunk/src/core/input/InputManager.cc
r2662 r2896 43 43 44 44 #include "util/Exception.h" 45 #include "core/Clock.h" 45 46 #include "core/CoreIncludes.h" 46 47 #include "core/ConfigValueIncludes.h" … … 108 109 , internalState_(Uninitialised) 109 110 , stateEmpty_(0) 110 , stateMaster_(0)111 111 , keyDetector_(0) 112 112 , calibratorCallbackBuffer_(0) … … 173 173 //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE"))); 174 174 //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND"))); 175 #if defined O IS_LINUX_PLATFORM175 #if defined ORXONOX_PLATFORM_LINUX 176 176 paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true"))); 177 177 paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true")); … … 218 218 219 219 // Lowest priority empty InputState 220 stateEmpty_ = createInputState<SimpleInputState>("empty", -1);220 stateEmpty_ = createInputState<SimpleInputState>("empty", false, false, InputStatePriority::Empty); 221 221 stateEmpty_->setHandler(&EMPTY_HANDLER); 222 222 activeStates_[stateEmpty_->getPriority()] = stateEmpty_; 223 223 224 // Always active master InputState225 stateMaster_ = new ExtendedInputState();226 stateMaster_->setName("master");227 stateMaster_->setNumOfJoySticks(joySticksSize_);228 229 224 // KeyDetector to evaluate a pressed key's name 230 SimpleInputState* detector = createInputState<SimpleInputState>("detector", 101);225 SimpleInputState* detector = createInputState<SimpleInputState>("detector", false, false, InputStatePriority::Detector); 231 226 keyDetector_ = new KeyDetector(); 232 227 detector->setHandler(keyDetector_); 233 228 234 229 // Joy stick calibration helper callback 235 SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", 100);230 SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", false, false, InputStatePriority::Calibrator); 236 231 calibrator->setHandler(&EMPTY_HANDLER); 237 232 calibratorCallbackBuffer_ = new InputBuffer(); … … 424 419 425 420 // state management 426 activeStatesT op_.resize(devicesNum_);421 activeStatesTriggered_.resize(devicesNum_); 427 422 428 423 // inform all states 429 for (std::map< int, InputState*>::const_iterator it = inputStatesByPriority_.begin();430 it != inputStatesBy Priority_.end(); ++it)424 for (std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.begin(); 425 it != inputStatesByName_.end(); ++it) 431 426 { 432 427 it->second->setNumOfJoySticks(joySticksSize_); 433 428 } 434 // inform master state435 if (stateMaster_)436 this->stateMaster_->setNumOfJoySticks(joySticksSize_);437 429 438 430 // inform all JoyStick Device Number Listeners … … 454 446 } 455 447 } 456 448 457 449 void InputManager::_startCalibration() 458 450 { … … 549 541 // destroy the empty InputState 550 542 _destroyState(this->stateEmpty_); 551 // destroy the master input state. This might trigger a memory leak552 // because the user has forgotten to destroy the KeyBinder or any Handler!553 delete stateMaster_;554 543 555 544 // destroy all user InputStates 556 while (inputStatesBy Priority_.size() > 0)557 _destroyState((*inputStatesBy Priority_.rbegin()).second);545 while (inputStatesByName_.size() > 0) 546 _destroyState((*inputStatesByName_.rbegin()).second); 558 547 559 548 // destroy the devices … … 639 628 _updateActiveStates(); 640 629 } 641 inputStatesByPriority_.erase(state->getPriority());642 630 inputStatesByName_.erase(state->getName()); 643 631 delete state; … … 670 658 @brief 671 659 Public interface. Only reloads immediately if the call stack doesn't 672 include the tick() method.660 include the update() method. 673 661 @param joyStickSupport 674 662 Whether or not to initialise joy sticks as well. … … 742 730 @brief 743 731 Updates the states and the InputState situation. 744 @param dt745 Delta time746 */ 747 void InputManager:: tick(float dt)732 @param time 733 Clock holding the current time. 734 */ 735 void InputManager::update(const Clock& time) 748 736 { 749 737 if (internalState_ == Uninitialised) … … 759 747 if (!stateLeaveRequests_.empty()) 760 748 { 761 for (std::set<InputState*>:: reverse_iterator rit = stateLeaveRequests_.rbegin();762 rit != stateLeaveRequests_.rend(); ++rit)763 { 764 (* rit)->onLeave();749 for (std::set<InputState*>::iterator it = stateLeaveRequests_.begin(); 750 it != stateLeaveRequests_.end(); ++it) 751 { 752 (*it)->onLeave(); 765 753 // just to be sure that the state actually is registered 766 assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end()); 767 768 activeStates_.erase((*rit)->getPriority()); 754 assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end()); 755 756 activeStates_.erase((*it)->getPriority()); 757 if ((*it)->getPriority() < InputStatePriority::HighPriority) 758 (*it)->setPriority(0); 769 759 _updateActiveStates(); 770 760 } … … 775 765 if (!stateEnterRequests_.empty()) 776 766 { 777 for (std::set<InputState*>:: reverse_iterator rit = stateEnterRequests_.rbegin();778 rit != stateEnterRequests_.rend(); ++rit)767 for (std::set<InputState*>::const_iterator it = stateEnterRequests_.begin(); 768 it != stateEnterRequests_.end(); ++it) 779 769 { 780 770 // just to be sure that the state actually is registered 781 assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end()); 782 783 activeStates_[(*rit)->getPriority()] = (*rit); 771 assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end()); 772 773 if ((*it)->getPriority() == 0) 774 { 775 // Get smallest possible priority between 1 and maxStateStackSize_s 776 #if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator 777 for(std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); 778 rit != activeStates_.rend(); ++rit) 779 #else 780 for(std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin(); 781 rit != activeStates_.rend(); ++rit) 782 #endif 783 { 784 if (rit->first < InputStatePriority::HighPriority) 785 { 786 (*it)->setPriority(rit->first + 1); 787 break; 788 } 789 } 790 // In case no normal handler was on the stack 791 if ((*it)->getPriority() == 0) 792 (*it)->setPriority(1); 793 } 794 activeStates_[(*it)->getPriority()] = (*it); 784 795 _updateActiveStates(); 785 (* rit)->onEnter();796 (*it)->onEnter(); 786 797 } 787 798 stateEnterRequests_.clear(); … … 791 802 if (!stateDestroyRequests_.empty()) 792 803 { 793 for (std::set<InputState*>:: reverse_iterator rit = stateDestroyRequests_.rbegin();794 rit != stateDestroyRequests_.rend(); ++rit)795 { 796 _destroyState((* rit));804 for (std::set<InputState*>::iterator it = stateDestroyRequests_.begin(); 805 it != stateDestroyRequests_.end(); ++it) 806 { 807 _destroyState((*it)); 797 808 } 798 809 stateDestroyRequests_.clear(); … … 812 823 _updateActiveStates(); 813 824 814 // mark that we capture and distributeinput825 // mark that we now start capturing and distributing input 815 826 internalState_ |= Ticking; 816 827 … … 829 840 { 830 841 KeyEvent kEvt(keysDown_[iKey], keyboardModifiers_); 831 activeStatesTop_[Keyboard]->keyHeld(kEvt); 832 stateMaster_->keyHeld(kEvt); 842 843 for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState) 844 activeStatesTriggered_[Keyboard][iState]->keyHeld(kEvt); 833 845 } 834 846 … … 836 848 for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++) 837 849 { 838 activeStatesTop_[Mouse]->mouseButtonHeld(mouseButtonsDown_[iButton]);839 stateMaster_->mouseButtonHeld(mouseButtonsDown_[iButton]);850 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState) 851 activeStatesTriggered_[Mouse][iState]->mouseButtonHeld(mouseButtonsDown_[iButton]); 840 852 } 841 853 … … 844 856 for (unsigned int iButton = 0; iButton < joyStickButtonsDown_[iJoyStick].size(); iButton++) 845 857 { 846 activeStatesTop_[JoyStick0 + iJoyStick] 847 ->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]); 848 stateMaster_->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]); 858 for (unsigned int iState = 0; iState < activeStatesTriggered_[JoyStick0 + iJoyStick].size(); ++iState) 859 activeStatesTriggered_[JoyStick0 + iJoyStick][iState]->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]); 849 860 } 850 861 851 // tickthe handlers for each active handler862 // update the handlers for each active handler 852 863 for (unsigned int i = 0; i < devicesNum_; ++i) 853 864 { 854 activeStatesTop_[i]->tickInput(dt, i); 855 if (stateMaster_->isInputDeviceEnabled(i)) 856 stateMaster_->tickInput(dt, i); 857 } 858 859 // tick the handler with a general tick afterwards 865 for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState) 866 activeStatesTriggered_[i][iState]->updateInput(time.getDeltaTime(), i); 867 } 868 869 // update the handler with a general tick afterwards 860 870 for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i) 861 activeStatesTicked_[i]->tickInput(dt); 862 stateMaster_->tickInput(dt); 871 activeStatesTicked_[i]->updateInput(time.getDeltaTime()); 863 872 } 864 873 … … 869 878 @brief 870 879 Updates the currently active states (according to activeStates_) for each device. 871 Also, a list of all active states (no duplicates!) is compiled for the general tick.880 Also, a list of all active states (no duplicates!) is compiled for the general update(). 872 881 */ 873 882 void InputManager::_updateActiveStates() 874 883 { 875 for (std::map<int, InputState*>::const_iterator it = activeStates_.begin(); it != activeStates_.end(); ++it) 876 for (unsigned int i = 0; i < devicesNum_; ++i) 877 if (it->second->isInputDeviceEnabled(i)) 878 activeStatesTop_[i] = it->second; 884 for (unsigned int i = 0; i < devicesNum_; ++i) 885 { 886 bool occupied = false; 887 activeStatesTriggered_[i].clear(); 888 #if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator 889 for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit) 890 { 891 #else 892 for (std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit) 893 { 894 #endif 895 if (rit->second->isInputDeviceEnabled(i) && (!occupied || rit->second->bAlwaysGetsInput_)) 896 { 897 activeStatesTriggered_[i].push_back(rit->second); 898 if (!rit->second->bTransparent_) 899 occupied = true; 900 } 901 } 902 } 879 903 880 904 // update tickables (every state will only appear once) … … 882 906 std::set<InputState*> tempSet; 883 907 for (unsigned int i = 0; i < devicesNum_; ++i) 884 tempSet.insert(activeStatesTop_[i]); 885 886 // copy the content of the set back to the actual vector 908 for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState) 909 tempSet.insert(activeStatesTriggered_[i][iState]); 910 911 // copy the content of the std::set back to the actual vector 887 912 activeStatesTicked_.clear(); 888 913 for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it) … … 942 967 943 968 KeyEvent kEvt(e, keyboardModifiers_); 944 activeStatesTop_[Keyboard]->keyPressed(kEvt);945 stateMaster_->keyPressed(kEvt);969 for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState) 970 activeStatesTriggered_[Keyboard][iState]->keyPressed(kEvt); 946 971 947 972 return true; … … 975 1000 976 1001 KeyEvent kEvt(e, keyboardModifiers_); 977 activeStatesTop_[Keyboard]->keyReleased(kEvt);978 stateMaster_->keyReleased(kEvt);1002 for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState) 1003 activeStatesTriggered_[Keyboard][iState]->keyReleased(kEvt); 979 1004 980 1005 return true; … … 998 1023 IntVector2 rel(e.state.X.rel, e.state.Y.rel); 999 1024 IntVector2 clippingSize(e.state.width, e.state.height); 1000 activeStatesTop_[Mouse]->mouseMoved(abs, rel, clippingSize);1001 stateMaster_->mouseMoved(abs, rel, clippingSize);1025 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState) 1026 activeStatesTriggered_[Mouse][iState]->mouseMoved(abs, rel, clippingSize); 1002 1027 } 1003 1028 … … 1005 1030 if (e.state.Z.rel != 0) 1006 1031 { 1007 activeStatesTop_[Mouse]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);1008 stateMaster_->mouseScrolled(e.state.Z.abs, e.state.Z.rel);1032 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState) 1033 activeStatesTriggered_[Mouse][iState]->mouseScrolled(e.state.Z.abs, e.state.Z.rel); 1009 1034 } 1010 1035 … … 1029 1054 mouseButtonsDown_.push_back((MouseButtonCode::ByEnum)id); 1030 1055 1031 activeStatesTop_[Mouse]->mouseButtonPressed((MouseButtonCode::ByEnum)id);1032 stateMaster_->mouseButtonPressed((MouseButtonCode::ByEnum)id);1056 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState) 1057 activeStatesTriggered_[Mouse][iState]->mouseButtonPressed((MouseButtonCode::ByEnum)id); 1033 1058 1034 1059 return true; … … 1055 1080 } 1056 1081 1057 activeStatesTop_[Mouse]->mouseButtonReleased((MouseButtonCode::ByEnum)id);1058 stateMaster_->mouseButtonReleased((MouseButtonCode::ByEnum)id);1082 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState) 1083 activeStatesTriggered_[Mouse][iState]->mouseButtonReleased((MouseButtonCode::ByEnum)id); 1059 1084 1060 1085 return true; … … 1092 1117 buttonsDown.push_back((JoyStickButtonCode::ByEnum)button); 1093 1118 1094 activeStatesTop_[2 + iJoyStick]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);1095 stateMaster_->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);1119 for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState) 1120 activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button); 1096 1121 1097 1122 return true; … … 1113 1138 } 1114 1139 1115 activeStatesTop_[2 + iJoyStick]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);1116 stateMaster_->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);1140 for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState) 1141 activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button); 1117 1142 1118 1143 return true; … … 1141 1166 fValue *= joyStickCalibrations_[iJoyStick].negativeCoeff[axis]; 1142 1167 1143 activeStatesTop_[2 + iJoyStick]->joyStickAxisMoved(iJoyStick, axis, fValue);1144 stateMaster_->joyStickAxisMoved(iJoyStick, axis, fValue);1168 for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState) 1169 activeStatesTriggered_[2 + iJoyStick][iState]->joyStickAxisMoved(iJoyStick, axis, fValue); 1145 1170 } 1146 1171 } … … 1245 1270 Unique name of the handler. 1246 1271 @param priority 1247 Unique integer number. Higher means more prioritised. 1272 Determines which InputState gets the input. Higher is better. 1273 Use 0 to handle it implicitely by the order of activation. 1274 Otherwise numbers larger than maxStateStackSize_s have to be used! 1248 1275 @return 1249 1276 True if added, false if name or priority already existed. 1250 1277 */ 1251 bool InputManager::_configureInputState(InputState* state, const std::string& name, int priority)1278 bool InputManager::_configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority) 1252 1279 { 1253 1280 if (name == "") … … 1257 1284 if (inputStatesByName_.find(name) == inputStatesByName_.end()) 1258 1285 { 1259 if (inputStatesByPriority_.find(priority) 1260 == inputStatesByPriority_.end()) 1261 { 1262 inputStatesByName_[name] = state; 1263 inputStatesByPriority_[priority] = state; 1264 state->setNumOfJoySticks(numberOfJoySticks()); 1265 state->setName(name); 1286 if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty) 1287 { 1288 // Make sure we don't add two high priority states with the same priority 1289 for (std::map<std::string, InputState*>::const_iterator it = this->inputStatesByName_.begin(); 1290 it != this->inputStatesByName_.end(); ++it) 1291 { 1292 if (it->second->getPriority() == priority) 1293 { 1294 COUT(2) << "Warning: Could not add an InputState with the same priority '" 1295 << priority << "' != 0." << std::endl; 1296 return false; 1297 } 1298 } 1299 } 1300 inputStatesByName_[name] = state; 1301 state->setNumOfJoySticks(numberOfJoySticks()); 1302 state->setName(name); 1303 state->bAlwaysGetsInput_ = bAlwaysGetsInput; 1304 state->bTransparent_ = bTransparent; 1305 if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty) 1266 1306 state->setPriority(priority); 1267 return true; 1268 } 1269 else 1270 { 1271 COUT(2) << "Warning: Could not add an InputState with the same priority '" 1272 << priority << "'." << std::endl; 1273 return false; 1274 } 1307 return true; 1275 1308 } 1276 1309 else … … 1290 1323 @remarks 1291 1324 You can't remove the internal states "empty", "calibrator" and "detector". 1292 The removal process is being postponed if InputManager:: tick() is currently running.1325 The removal process is being postponed if InputManager::update() is currently running. 1293 1326 */ 1294 1327 bool InputManager::requestDestroyState(const std::string& name) … … 1371 1404 { 1372 1405 // not scheduled for destruction 1373 // setprevents a state being added multiple times1406 // prevents a state being added multiple times 1374 1407 stateEnterRequests_.insert(it->second); 1375 1408 return true; … … 1390 1423 bool InputManager::requestLeaveState(const std::string& name) 1391 1424 { 1425 if (name == "empty") 1426 { 1427 COUT(2) << "InputManager: Leaving the empty state is not allowed!" << std::endl; 1428 return false; 1429 } 1392 1430 // get pointer from the map with all stored handlers 1393 1431 std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name); -
code/trunk/src/core/input/InputManager.h
r2662 r2896 43 43 #include <stack> 44 44 #include "util/Math.h" 45 #include "util/OrxEnum.h" 45 46 #include "core/OrxonoxClass.h" 46 47 #include "InputInterfaces.h" … … 74 75 float positiveCoeff[24]; 75 76 float negativeCoeff[24]; 77 }; 78 79 struct InputStatePriority : OrxEnum<InputStatePriority> 80 { 81 OrxEnumConstructors(InputStatePriority); 82 83 static const int Empty = -1; 84 static const int Dynamic = 0; 85 86 static const int HighPriority = 1000; 87 static const int Console = HighPriority + 0; 88 static const int Calibrator = HighPriority + 1; 89 static const int Detector = HighPriority + 2; 76 90 }; 77 91 … … 116 130 117 131 template <class T> 118 T* createInputState(const std::string& name, int priority);132 T* createInputState(const std::string& name, bool bAlwaysGetsInput = false, bool bTransparent = false, InputStatePriority priority = InputStatePriority::Dynamic); 119 133 120 134 InputState* getState (const std::string& name); 121 135 InputState* getCurrentState(); 122 ExtendedInputState* getMasterInputState() { return this->stateMaster_; }123 136 bool requestDestroyState (const std::string& name); 124 137 bool requestEnterState (const std::string& name); 125 138 bool requestLeaveState (const std::string& name); 126 139 127 void tick(float dt);140 void update(const Clock& time); 128 141 129 142 static InputManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; } … … 165 178 166 179 void _updateActiveStates(); 167 bool _configureInputState(InputState* state, const std::string& name, int priority);180 bool _configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority); 168 181 169 182 // input events … … 197 210 // some internally handled states and handlers 198 211 SimpleInputState* stateEmpty_; 199 ExtendedInputState* stateMaster_; //!< Always active master input state200 212 KeyDetector* keyDetector_; //!< KeyDetector instance 201 213 InputBuffer* calibratorCallbackBuffer_; 202 214 203 215 std::map<std::string, InputState*> inputStatesByName_; 204 std::map<int, InputState*> inputStatesByPriority_;205 216 206 217 std::set<InputState*> stateEnterRequests_; //!< Request to enter a new state … … 209 220 210 221 std::map<int, InputState*> activeStates_; 211 std::vector< InputState*> activeStatesTop_; //!< Current input states for joy stick events.212 std::vector<InputState*> activeStatesTicked_; //!< Current input states for joy stick events.222 std::vector<std::vector<InputState*> > activeStatesTriggered_; 223 std::vector<InputState*> activeStatesTicked_; 213 224 214 225 // joystick calibration … … 249 260 */ 250 261 template <class T> 251 T* InputManager::createInputState(const std::string& name, intpriority)262 T* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority) 252 263 { 253 264 T* state = new T; 254 if (_configureInputState(state, name, priority))265 if (_configureInputState(state, name, bAlwaysGetsInput, bTransparent, priority)) 255 266 return state; 256 267 else -
code/trunk/src/core/input/InputState.h
r1887 r2896 71 71 virtual void unRegisterOnLeave() { executorOnLeave_ = 0; } 72 72 73 virtual void tickInput(float dt, unsigned int device) = 0;74 virtual void tickInput(float dt) = 0;73 virtual void updateInput(float dt, unsigned int device) = 0; 74 virtual void updateInput(float dt) = 0; 75 75 76 76 virtual void keyPressed (const KeyEvent& evt) = 0; … … 90 90 91 91 protected: 92 InputState() : bHandlersChanged_(false), priority_(0), executorOnEnter_(0), executorOnLeave_(0) { } 92 InputState() 93 : bHandlersChanged_(false) 94 , priority_(0) 95 , bAlwaysGetsInput_(false) 96 , bTransparent_(false) 97 , executorOnEnter_(0) 98 , executorOnLeave_(0) 99 { } 93 100 virtual ~InputState() { } 94 101 … … 114 121 int priority_; 115 122 std::vector<bool> bInputDeviceEnabled_; 123 bool bAlwaysGetsInput_; 124 bool bTransparent_; 116 125 117 126 Executor* executorOnEnter_; -
code/trunk/src/core/input/KeyBinder.cc
r2713 r2896 42 42 #include "core/CoreIncludes.h" 43 43 #include "core/ConfigFileManager.h" 44 #include "core/Core.h"45 44 #include "InputCommands.h" 46 45 #include "InputManager.h" … … 309 308 } 310 309 311 void KeyBinder:: tickMouse(float dt)310 void KeyBinder::updateMouse(float dt) 312 311 { 313 312 if (bDeriveMouseInput_) … … 349 348 // Why dividing relative value by dt? The reason lies in the simple fact, that when you 350 349 // press a button that has relative movement, that value has to be multiplied by dt to be 351 // frame rate independent. This can easily (and only) be done in tickInput(float).350 // frame rate independent. This can easily (and only) be done in updateInput(float). 352 351 // Hence we need to divide by dt here for the mouse to compensate, because the relative 353 352 // move movements have nothing to do with dt. … … 362 361 } 363 362 364 void KeyBinder:: tickJoyStick(float dt, unsigned int joyStick)363 void KeyBinder::updateJoyStick(float dt, unsigned int joyStick) 365 364 { 366 365 for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++) -
code/trunk/src/core/input/KeyBinder.h
r2710 r2896 68 68 69 69 protected: // functions 70 void tickInput(float dt);71 void tickKey(float dt) { }72 void tickMouse(float dt);73 void tickJoyStick(float dt, unsigned int joyStick);70 void updateInput(float dt); 71 void updateKey(float dt) { } 72 void updateMouse(float dt); 73 void updateJoyStick(float dt, unsigned int joyStick); 74 74 // internal 75 75 void tickHalfAxis(HalfAxis& halfAxis); … … 134 134 @brief 135 135 Commands that have additional parameters (axes) are executed at the end of 136 the tick() so that all values can be buffered for single execution.136 update() so that all values can be buffered for single execution. 137 137 */ 138 138 std::vector<BufferedParamCommand*> paramCommandBuffer_; … … 200 200 { joyStickButtons_[joyStickID][id].execute(KeybindMode::OnHold); } 201 201 202 inline void KeyBinder:: tickInput(float dt)202 inline void KeyBinder::updateInput(float dt) 203 203 { 204 204 // execute all buffered bindings (additional parameter) -
code/trunk/src/core/input/SimpleInputState.h
r1887 r2896 59 59 ~SimpleInputState() { } 60 60 61 void tickInput(float dt);62 void tickInput(float dt, unsigned int device);61 void updateInput(float dt); 62 void updateInput(float dt, unsigned int device); 63 63 64 64 void keyPressed (const KeyEvent& evt); … … 87 87 }; 88 88 89 inline void SimpleInputState:: tickInput(float dt)89 inline void SimpleInputState::updateInput(float dt) 90 90 { 91 91 for (unsigned int i = 0; i < allHandlers_.size(); ++i) 92 92 { 93 allHandlers_[i]-> tickInput(dt);93 allHandlers_[i]->updateInput(dt); 94 94 } 95 95 } 96 96 97 inline void SimpleInputState:: tickInput(float dt, unsigned int device)97 inline void SimpleInputState::updateInput(float dt, unsigned int device) 98 98 { 99 99 switch (device) … … 101 101 case InputDevice::Keyboard: 102 102 if (keyHandler_) 103 keyHandler_-> tickKey(dt);103 keyHandler_->updateKey(dt); 104 104 break; 105 105 106 106 case InputDevice::Mouse: 107 107 if (mouseHandler_) 108 mouseHandler_-> tickMouse(dt);108 mouseHandler_->updateMouse(dt); 109 109 break; 110 110 111 111 default: // joy sticks 112 112 if (joyStickHandler_[device - 2]) 113 joyStickHandler_[device - 2]-> tickJoyStick(dt, device - 2);113 joyStickHandler_[device - 2]->updateJoyStick(dt, device - 2); 114 114 break; 115 115 }
Note: See TracChangeset
for help on using the changeset viewer.