Changeset 3280 for code/trunk/src/core
- Timestamp:
- Jul 12, 2009, 11:58:01 PM (16 years ago)
- Location:
- code/trunk
- Files:
-
- 38 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
/code/branches/core4 (added) merged: 3235-3237,3245-3250,3253-3254,3260-3261,3265,3270
- Property svn:mergeinfo changed
-
code/trunk/src/core/ArgumentCompletionFunctions.cc
r3196 r3280 34 34 35 35 #include "util/Convert.h" 36 #include "util/String .h"36 #include "util/StringUtils.h" 37 37 #include "Identifier.h" 38 38 #include "ConfigValueContainer.h" … … 143 143 144 144 for (std::list<unsigned int>::const_iterator it = threadnumbers.begin(); it != threadnumbers.end(); ++it) 145 threads.push_back(ArgumentCompletionListElement( getConvertedValue<unsigned int,std::string>(*it)));145 threads.push_back(ArgumentCompletionListElement(multi_cast<std::string>(*it))); 146 146 147 147 return threads; -
code/trunk/src/core/BaseObject.cc
r3196 r3280 36 36 #include <tinyxml/tinyxml.h> 37 37 38 #include "util/String .h"38 #include "util/StringUtils.h" 39 39 #include "CoreIncludes.h" 40 40 #include "Event.h" -
code/trunk/src/core/CMakeLists.txt
r3196 r3280 68 68 TOLUA_FILES 69 69 CommandExecutor.h 70 Game.h71 70 LuaBind.h 72 71 DEFINE_SYMBOL -
code/trunk/src/core/CommandEvaluation.cc
r3196 r3280 30 30 31 31 #include "util/Debug.h" 32 #include "util/String .h"32 #include "util/StringUtils.h" 33 33 #include "ConsoleCommand.h" 34 34 #include "Identifier.h" … … 39 39 { 40 40 this->initialize(""); 41 this->state_ = C S_Uninitialized;41 this->state_ = CommandState::Uninitialized; 42 42 } 43 43 … … 64 64 65 65 this->errorMessage_ = ""; 66 this->state_ = C S_Empty;66 this->state_ = CommandState::Empty; 67 67 } 68 68 … … 104 104 switch (this->state_) 105 105 { 106 case C S_Uninitialized:107 break; 108 case C S_Empty:109 break; 110 case C S_ShortcutOrIdentifier:106 case CommandState::Uninitialized: 107 break; 108 case CommandState::Empty: 109 break; 110 case CommandState::ShortcutOrIdentifier: 111 111 if (this->function_) 112 112 { … … 119 119 return (this->command_ = this->functionclass_->getName() + " "); 120 120 break; 121 case C S_Function:121 case CommandState::Function: 122 122 if (this->function_) 123 123 { … … 128 128 } 129 129 break; 130 case C S_ParamPreparation:131 case C S_Params:130 case CommandState::ParamPreparation: 131 case CommandState::Params: 132 132 { 133 133 if (this->argument_ == "" && this->possibleArgument_ == "") … … 149 149 break; 150 150 } 151 case C S_Finished:152 break; 153 case C S_Error:151 case CommandState::Finished: 152 break; 153 case CommandState::Error: 154 154 break; 155 155 } … … 163 163 switch (this->state_) 164 164 { 165 case C S_Uninitialized:166 break; 167 case C S_Empty:168 case C S_ShortcutOrIdentifier:165 case CommandState::Uninitialized: 166 break; 167 case CommandState::Empty: 168 case CommandState::ShortcutOrIdentifier: 169 169 if (this->listOfPossibleFunctions_.size() == 0) 170 170 return CommandEvaluation::dump(this->listOfPossibleIdentifiers_); … … 174 174 return (CommandEvaluation::dump(this->listOfPossibleFunctions_) + "\n" + CommandEvaluation::dump(this->listOfPossibleIdentifiers_)); 175 175 break; 176 case C S_Function:176 case CommandState::Function: 177 177 return CommandEvaluation::dump(this->listOfPossibleFunctions_); 178 178 break; 179 case C S_ParamPreparation:180 case C S_Params:179 case CommandState::ParamPreparation: 180 case CommandState::Params: 181 181 if (this->listOfPossibleArguments_.size() > 0) 182 182 return CommandEvaluation::dump(this->listOfPossibleArguments_); 183 183 else 184 184 return CommandEvaluation::dump(this->function_); 185 case C S_Finished:185 case CommandState::Finished: 186 186 if (this->function_) 187 187 return CommandEvaluation::dump(this->function_); 188 188 break; 189 case C S_Error:189 case CommandState::Error: 190 190 return this->errorMessage_; 191 191 break; … … 200 200 201 201 for (unsigned int i = 0; i < MAX_FUNCTOR_ARGUMENTS; i++) 202 this->param_[i] = MT_ null;202 this->param_[i] = MT_Type::Null; 203 203 204 204 if (!this->isValid()) … … 230 230 return this->param_[index]; 231 231 232 return MT_ null;232 return MT_Type::Null; 233 233 } 234 234 … … 238 238 return this->function_->hasReturnvalue(); 239 239 240 return MT_ null;240 return MT_Type::Null; 241 241 } 242 242 -
code/trunk/src/core/CommandEvaluation.h
r1747 r3280 41 41 namespace orxonox 42 42 { 43 enumCommandState43 namespace CommandState 44 44 { 45 CS_Uninitialized, 46 CS_Empty, 47 CS_ShortcutOrIdentifier, 48 CS_Function, 49 CS_ParamPreparation, 50 CS_Params, 51 CS_Finished, 52 CS_Error 53 }; 45 enum Value 46 { 47 Uninitialized, 48 Empty, 49 ShortcutOrIdentifier, 50 Function, 51 ParamPreparation, 52 Params, 53 Finished, 54 Error 55 }; 56 } 54 57 55 58 class _CoreExport CommandEvaluation … … 112 115 113 116 std::string errorMessage_; 114 CommandState state_;117 CommandState::Value state_; 115 118 116 119 bool bEvaluatedParams_; -
code/trunk/src/core/CommandExecutor.cc
r3196 r3280 30 30 31 31 #include "util/Debug.h" 32 #include "util/String .h"32 #include "util/StringUtils.h" 33 33 #include "ConsoleCommand.h" 34 34 #include "Identifier.h" … … 141 141 void CommandExecutor::parseIfNeeded(const std::string& command) 142 142 { 143 if (CommandExecutor::getEvaluation().state_ == C S_Uninitialized)143 if (CommandExecutor::getEvaluation().state_ == CommandState::Uninitialized) 144 144 { 145 145 CommandExecutor::parse(command); … … 169 169 switch (CommandExecutor::getEvaluation().state_) 170 170 { 171 case C S_Uninitialized:171 case CommandState::Uninitialized: 172 172 { 173 173 // Impossible 174 174 break; 175 175 } 176 case C S_Empty:176 case CommandState::Empty: 177 177 { 178 178 if (CommandExecutor::argumentsGiven() == 0) … … 184 184 else 185 185 { 186 CommandExecutor::getEvaluation().state_ = C S_ShortcutOrIdentifier;186 CommandExecutor::getEvaluation().state_ = CommandState::ShortcutOrIdentifier; 187 187 // Move on to next case 188 188 } 189 189 } 190 case C S_ShortcutOrIdentifier:190 case CommandState::ShortcutOrIdentifier: 191 191 { 192 192 if (CommandExecutor::argumentsGiven() > 1) … … 199 199 { 200 200 // It's a shortcut 201 CommandExecutor::getEvaluation().state_ = C S_ParamPreparation;201 CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation; 202 202 CommandExecutor::getEvaluation().functionclass_ = 0; 203 203 // Move on to next case … … 206 206 { 207 207 // It's a functionname 208 CommandExecutor::getEvaluation().state_ = C S_Function;208 CommandExecutor::getEvaluation().state_ = CommandState::Function; 209 209 CommandExecutor::getEvaluation().function_ = 0; 210 210 // Move on to next case … … 213 213 { 214 214 // The first argument is bad 215 CommandExecutor::getEvaluation().state_ = C S_Error;215 CommandExecutor::getEvaluation().state_ = CommandState::Error; 216 216 AddLanguageEntry("commandexecutorunknownfirstargument", "is not a shortcut nor a classname"); 217 217 CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(0) + " " + GetLocalisation("commandexecutorunknownfirstargument") + "."; … … 238 238 CommandExecutor::getEvaluation().bCommandChanged_ = true; 239 239 } 240 CommandExecutor::getEvaluation().state_ = C S_ParamPreparation;240 CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation; 241 241 CommandExecutor::getEvaluation().functionclass_ = 0; 242 242 CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().function_->getName(); … … 258 258 CommandExecutor::getEvaluation().bCommandChanged_ = true; 259 259 } 260 CommandExecutor::getEvaluation().state_ = C S_Function;260 CommandExecutor::getEvaluation().state_ = CommandState::Function; 261 261 CommandExecutor::getEvaluation().function_ = 0; 262 262 CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " "; … … 266 266 { 267 267 // No possibilities 268 CommandExecutor::getEvaluation().state_ = C S_Error;268 CommandExecutor::getEvaluation().state_ = CommandState::Error; 269 269 AddLanguageEntry("commandexecutorunknownfirstargumentstart", "There is no command or classname starting with"); 270 270 CommandExecutor::getEvaluation().errorMessage_ = "Error: " + GetLocalisation("commandexecutorunknownfirstargumentstart") + " " + CommandExecutor::getArgument(0) + "."; … … 285 285 } 286 286 } 287 case C S_Function:287 case CommandState::Function: 288 288 { 289 289 if (CommandExecutor::getEvaluation().functionclass_) … … 298 298 { 299 299 // It's a function 300 CommandExecutor::getEvaluation().state_ = C S_ParamPreparation;300 CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation; 301 301 // Move on to next case 302 302 } … … 304 304 { 305 305 // The second argument is bad 306 CommandExecutor::getEvaluation().state_ = C S_Error;306 CommandExecutor::getEvaluation().state_ = CommandState::Error; 307 307 AddLanguageEntry("commandexecutorunknownsecondargument", "is not a function of"); 308 308 CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(1) + " " + GetLocalisation("commandexecutorunknownsecondargument") + " " + CommandExecutor::getEvaluation().functionclass_->getName() + "."; … … 326 326 CommandExecutor::getEvaluation().bCommandChanged_ = true; 327 327 } 328 CommandExecutor::getEvaluation().state_ = C S_ParamPreparation;328 CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation; 329 329 CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " " + CommandExecutor::getEvaluation().function_->getName(); 330 330 if (CommandExecutor::getEvaluation().function_->getParamCount() > 0) … … 338 338 { 339 339 // No possibilities 340 CommandExecutor::getEvaluation().state_ = C S_Error;340 CommandExecutor::getEvaluation().state_ = CommandState::Error; 341 341 AddLanguageEntry("commandexecutorunknownsecondargumentstart", "has no function starting with"); 342 342 CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getEvaluation().functionclass_->getName() + " " + GetLocalisation("commandexecutorunknownsecondargumentstart") + " " + CommandExecutor::getArgument(1) + "."; … … 355 355 else 356 356 { 357 // There is no classname - move on to C S_ParamPreparation358 } 359 } 360 case C S_ParamPreparation:357 // There is no classname - move on to CommandState::ParamPreparation 358 } 359 } 360 case CommandState::ParamPreparation: 361 361 { 362 362 if (CommandExecutor::getEvaluation().function_->getParamCount() == 0 || CommandExecutor::enoughArgumentsGiven(CommandExecutor::getEvaluation().function_)) 363 363 { 364 CommandExecutor::getEvaluation().state_ = C S_Finished;364 CommandExecutor::getEvaluation().state_ = CommandState::Finished; 365 365 return; 366 366 } … … 372 372 373 373 CommandExecutor::createListOfPossibleArguments(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber); 374 CommandExecutor::getEvaluation().state_ = C S_Params;374 CommandExecutor::getEvaluation().state_ = CommandState::Params; 375 375 376 376 if (CommandExecutor::getEvaluation().bCommandChanged_) … … 381 381 } 382 382 } 383 case C S_Params:383 case CommandState::Params: 384 384 { 385 385 if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 1) … … 388 388 CommandExecutor::getEvaluation().argument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString(); 389 389 CommandExecutor::getEvaluation().possibleArgument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString(); 390 CommandExecutor::getEvaluation().state_ = C S_ParamPreparation;390 CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation; 391 391 return; 392 392 } … … 394 394 { 395 395 // The user tries something new - we let him do 396 CommandExecutor::getEvaluation().state_ = C S_ParamPreparation;396 CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation; 397 397 CommandExecutor::getEvaluation().argument_ = CommandExecutor::getLastArgument(); 398 398 return; … … 409 409 CommandExecutor::getEvaluation().argument_ = CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleArguments_); 410 410 CommandExecutor::getEvaluation().possibleArgument_ = CommandExecutor::getPossibleArgument(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber); 411 CommandExecutor::getEvaluation().state_ = C S_ParamPreparation;411 CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation; 412 412 return; 413 413 } 414 414 } 415 case C S_Finished:415 case CommandState::Finished: 416 416 { 417 417 // Nothing more to do 418 418 break; 419 419 } 420 case C S_Error:420 case CommandState::Error: 421 421 { 422 422 // Bad, very bad -
code/trunk/src/core/CommandLine.cc
r3196 r3280 29 29 #include "CommandLine.h" 30 30 31 #include <algorithm> 32 #include <sstream> 31 33 #include <boost/filesystem.hpp> 32 34 … … 34 36 #include "util/Debug.h" 35 37 #include "util/Exception.h" 36 #include "util/String .h"38 #include "util/StringUtils.h" 37 39 #include "util/SubString.h" 38 40 #include "Core.h" … … 40 42 namespace orxonox 41 43 { 42 SetCommandLine Argument(optionsFile, "start.ini").shortcut("o");44 SetCommandLineOnlyArgument(optionsFile, "start.ini").shortcut("o"); 43 45 44 46 /** … … 49 51 so that you can have simple command line switches. 50 52 */ 51 void CommandLineArgument::parse(const std::string& value) 52 { 53 if (value_.getType() == MT_bool) 53 void CommandLineArgument::parse(const std::string& value, bool bParsingFile) 54 { 55 if (bParsingFile && this->bCommandLineOnly_) 56 ThrowException(Argument, "Command line argument '" + getName() + "' is not allowed in files."); 57 if (value_.getType() == MT_Type::Bool) 54 58 { 55 59 // simulate command line switch … … 66 70 } 67 71 else 68 {69 72 ThrowException(Argument, "Could not read command line argument '" + getName() + "'."); 70 }71 73 } 72 74 else … … 126 128 Vector of space separated strings. 127 129 */ 128 void CommandLine::_parse(const std::vector<std::string>& arguments) 129 { 130 // why this? See bFirstTimeParse_ declaration. 131 if (bFirstTimeParse_) 132 { 133 // first shove all the shortcuts in a map 134 for (std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgs_.begin(); 135 it != cmdLineArgs_.end(); ++it) 136 { 137 OrxAssert(cmdLineArgsShortcut_.find(it->second->getShortcut()) == cmdLineArgsShortcut_.end(), 138 "Cannot have two command line shortcut with the same name."); 139 if (it->second->getShortcut() != "") 140 cmdLineArgsShortcut_[it->second->getShortcut()] = it->second; 141 } 142 bFirstTimeParse_ = false; 143 } 144 145 std::string name; 146 std::string shortcut; 147 std::string value; 148 for (unsigned int i = 0; i < arguments.size(); ++i) 149 { 150 if (arguments[i].size() != 0) 151 { 152 // sure not "" 153 if (arguments[i][0] == '-') 130 void CommandLine::_parse(const std::vector<std::string>& arguments, bool bParsingFile) 131 { 132 try 133 { 134 // why this? See bFirstTimeParse_ declaration. 135 if (bFirstTimeParse_) 136 { 137 // first shove all the shortcuts in a map 138 for (std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgs_.begin(); 139 it != cmdLineArgs_.end(); ++it) 154 140 { 155 // start with "-" 156 if (arguments[i].size() == 1) 141 OrxAssert(cmdLineArgsShortcut_.find(it->second->getShortcut()) == cmdLineArgsShortcut_.end(), 142 "Cannot have two command line shortcut with the same name."); 143 if (it->second->getShortcut() != "") 144 cmdLineArgsShortcut_[it->second->getShortcut()] = it->second; 145 } 146 bFirstTimeParse_ = false; 147 } 148 149 std::string name; 150 std::string shortcut; 151 std::string value; 152 for (unsigned int i = 0; i < arguments.size(); ++i) 153 { 154 if (arguments[i].size() != 0) 155 { 156 // sure not "" 157 if (arguments[i][0] == '-') 157 158 { 158 // argument[i] is "-", probably a minus sign 159 value += "- "; 160 } 161 else if (arguments[i][1] <= 57 && arguments[i][1] >= 48) 162 { 163 // negative number as a value 164 value += arguments[i] + " "; 159 // start with "-" 160 if (arguments[i].size() == 1) 161 { 162 // argument[i] is "-", probably a minus sign 163 value += "- "; 164 } 165 else if (arguments[i][1] <= 57 && arguments[i][1] >= 48) 166 { 167 // negative number as a value 168 value += arguments[i] + " "; 169 } 170 else 171 { 172 // can be shortcut or full name argument 173 174 // save old data first 175 value = removeTrailingWhitespaces(value); 176 if (name != "") 177 { 178 checkFullArgument(name, value, bParsingFile); 179 name = ""; 180 assert(shortcut == ""); 181 } 182 else if (shortcut != "") 183 { 184 checkShortcut(shortcut, value, bParsingFile); 185 shortcut = ""; 186 assert(name == ""); 187 } 188 189 if (arguments[i][1] == '-') 190 { 191 // full name argument with "--name" 192 name = arguments[i].substr(2); 193 } 194 else 195 { 196 // shortcut with "-s" 197 shortcut = arguments[i].substr(1); 198 } 199 200 // reset value string 201 value = ""; 202 } 165 203 } 166 204 else 167 205 { 168 // can be shortcut or full name argument 169 170 // save old data first 171 value = removeTrailingWhitespaces(value); 172 if (name != "") 206 // value string 207 208 if (name == "" && shortcut == "") 173 209 { 174 checkFullArgument(name, value); 175 name = ""; 176 assert(shortcut == ""); 210 ThrowException(Argument, "Expected \"-\" or \"-\" in command line arguments.\n"); 177 211 } 178 else if (shortcut != "") 179 { 180 checkShortcut(shortcut, value); 181 shortcut = ""; 182 assert(name == ""); 183 } 184 185 if (arguments[i][1] == '-') 186 { 187 // full name argument with "--name" 188 name = arguments[i].substr(2); 189 } 190 else 191 { 192 // shortcut with "-s" 193 shortcut = arguments[i].substr(1); 194 } 195 196 // reset value string 197 value = ""; 212 213 // Concatenate strings as long as there's no new argument by "-" or "--" 214 value += arguments[i] + ' '; 198 215 } 199 216 } 200 else 201 { 202 // value string 203 204 if (name == "" && shortcut == "") 205 { 206 ThrowException(Argument, "Expected \"-\" or \"-\" in command line arguments.\n"); 207 } 208 209 // Concatenate strings as long as there's no new argument by "-" or "--" 210 value += arguments[i] + ' '; 211 } 212 } 213 } 214 215 // parse last argument 216 value = removeTrailingWhitespaces(value); 217 if (name != "") 218 { 219 checkFullArgument(name, value); 220 assert(shortcut == ""); 221 } 222 else if (shortcut != "") 223 { 224 checkShortcut(shortcut, value); 225 assert(name == ""); 217 } 218 219 // parse last argument 220 value = removeTrailingWhitespaces(value); 221 if (name != "") 222 { 223 checkFullArgument(name, value, bParsingFile); 224 assert(shortcut == ""); 225 } 226 else if (shortcut != "") 227 { 228 checkShortcut(shortcut, value, bParsingFile); 229 assert(name == ""); 230 } 231 } 232 catch (const ArgumentException& ex) 233 { 234 COUT(0) << "Could not parse command line (including additional files): " << ex.what() << std::endl; 235 COUT(0) << CommandLine::getUsageInformation() << std::endl; 236 throw GeneralException(""); 226 237 } 227 238 } … … 235 246 String containing the value 236 247 */ 237 void CommandLine::checkFullArgument(const std::string& name, const std::string& value )248 void CommandLine::checkFullArgument(const std::string& name, const std::string& value, bool bParsingFile) 238 249 { 239 250 std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgs_.find(name); … … 241 252 ThrowException(Argument, "Command line argument '" + name + "' does not exist."); 242 253 243 it->second->parse(value );254 it->second->parse(value, bParsingFile); 244 255 } 245 256 … … 252 263 String containing the value 253 264 */ 254 void CommandLine::checkShortcut(const std::string& shortcut, const std::string& value )265 void CommandLine::checkShortcut(const std::string& shortcut, const std::string& value, bool bParsingFile) 255 266 { 256 267 std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgsShortcut_.find(shortcut); … … 258 269 ThrowException(Argument, "Command line shortcut '" + shortcut + "' does not exist."); 259 270 260 it->second->parse(value );271 it->second->parse(value, bParsingFile); 261 272 } 262 273 263 274 std::string CommandLine::getUsageInformation() 264 275 { 265 CommandLine* inst = &_getInstance(); 266 std::string infoStr; 267 for (std::map<std::string, CommandLineArgument*>::const_iterator it = inst->cmdLineArgs_.begin(); 268 it != inst->cmdLineArgs_.end(); ++it) 269 { 270 infoStr += "[--" + it->second->getName() + " " + it->second->getInformation() + "] "; 271 } 272 return infoStr; 276 CommandLine& inst = _getInstance(); 277 std::ostringstream infoStr; 278 279 // determine maximum name size 280 size_t maxNameSize = 0; 281 for (std::map<std::string, CommandLineArgument*>::const_iterator it = inst.cmdLineArgs_.begin(); 282 it != inst.cmdLineArgs_.end(); ++it) 283 { 284 maxNameSize = std::max(it->second->getName().size(), maxNameSize); 285 } 286 287 infoStr << "Usage: orxonox [options]" << std::endl; 288 infoStr << "Available options:" << std::endl; 289 290 for (std::map<std::string, CommandLineArgument*>::const_iterator it = inst.cmdLineArgs_.begin(); 291 it != inst.cmdLineArgs_.end(); ++it) 292 { 293 if (it->second->getShortcut() != "") 294 infoStr << " [-" << it->second->getShortcut() << "] "; 295 else 296 infoStr << " "; 297 infoStr << "--" << it->second->getName() << " "; 298 if (it->second->getValue().getType() != MT_Type::Bool) 299 infoStr << "ARG "; 300 else 301 infoStr << " "; 302 // fill with the necessary amount of blanks 303 infoStr << std::string(maxNameSize - it->second->getName().size(), ' '); 304 infoStr << ": " << it->second->getInformation(); 305 infoStr << std::endl; 306 } 307 return infoStr.str(); 273 308 } 274 309 … … 295 330 /** 296 331 @brief 297 Parses both command line and start.ini for CommandLineArguments. 298 */ 299 void CommandLine::_parseAll(int argc, char** argv) 300 { 301 // parse command line first 332 Parses only the command line for CommandLineArguments. 333 */ 334 void CommandLine::_parseCommandLine(int argc, char** argv) 335 { 302 336 std::vector<std::string> args; 303 337 for (int i = 1; i < argc; ++i) 304 338 args.push_back(argv[i]); 305 this->_parse(args); 306 339 this->_parse(args, false); 340 } 341 342 /** 343 @brief 344 Parses start.ini (or the file specified with --optionsFile) for CommandLineArguments. 345 */ 346 void CommandLine::_parseFile() 347 { 307 348 std::string filename = CommandLine::getValue("optionsFile").getString(); 308 349 boost::filesystem::path filepath(Core::getConfigPath() / filename); … … 312 353 std::ifstream file; 313 354 file.open(filepath.string().c_str()); 314 args.clear();355 std::vector<std::string> args; 315 356 if (file) 316 357 { … … 332 373 } 333 374 334 try 335 { 336 _parse(args); 337 } 338 catch (orxonox::ArgumentException& ex) 339 { 340 COUT(1) << "An Exception occured while parsing " << filename << std::endl; 341 throw(ex); 342 } 375 _parse(args, true); 343 376 } 344 377 } -
code/trunk/src/core/CommandLine.h
r3196 r3280 38 38 #define SetCommandLineArgument(name, defaultValue) \ 39 39 orxonox::CommandLineArgument& CmdArgumentDummyBoolVar##name \ 40 = orxonox::CommandLine::addArgument(#name, defaultValue) 40 = orxonox::CommandLine::addArgument(#name, defaultValue, false) 41 #define SetCommandLineOnlyArgument(name, defaultValue) \ 42 orxonox::CommandLineArgument& CmdArgumentDummyBoolVar##name \ 43 = orxonox::CommandLine::addArgument(#name, defaultValue, true) 41 44 #define SetCommandLineSwitch(name) \ 42 45 orxonox::CommandLineArgument& CmdArgumentDummyBoolVar##name \ 43 = orxonox::CommandLine::addArgument(#name, false) 46 = orxonox::CommandLine::addArgument(#name, false, false) 47 #define SetCommandLineOnlySwitch(name) \ 48 orxonox::CommandLineArgument& CmdArgumentDummyBoolVar##name \ 49 = orxonox::CommandLine::addArgument(#name, false, true) 44 50 45 51 … … 74 80 75 81 //! Returns the shortcut (example: "-p 22" for "--port 22") of the argument. 76 //! Evaluates to "" if nonethere is none.82 //! Evaluates to "" if there is none. 77 83 const std::string& getShortcut() const { return shortcut_; } 78 84 //! Sets the shortcut for the argument … … 93 99 private: 94 100 //! Constructor initialises both value_ and defaultValue_ with defaultValue. 95 CommandLineArgument(const std::string& name, const MultiType& defaultValue )101 CommandLineArgument(const std::string& name, const MultiType& defaultValue, bool bCommandLineOnly) 96 102 : bHasDefaultValue_(true) 97 103 , name_(name) 98 104 , value_(defaultValue) 99 105 , defaultValue_(defaultValue) 106 , bCommandLineOnly_(bCommandLineOnly) 100 107 { } 101 108 … … 105 112 106 113 //! Parses the value string of a command line argument. 107 void parse(const std::string& value );114 void parse(const std::string& value, bool bParsingFile); 108 115 109 116 //! Tells whether the value has been changed by the command line. … … 115 122 std::string usageInformation_; //!< Tells about the usage of this parameter 116 123 117 MultiType value_; //!< The actual value 118 MultiType defaultValue_; //!< Default value. Should not be changed. 124 MultiType value_; //!< The actual value 125 MultiType defaultValue_; //!< Default value. Should not be changed. 126 bool bCommandLineOnly_; //!< Whether you cannot specify the value in a text file 119 127 }; 120 128 … … 134 142 135 143 //! Parse redirection to internal member method. 136 static void parseAll(int argc, char** argv) { _getInstance()._parseAll(argc, argv); } 144 static void parseCommandLine(int argc, char** argv) { _getInstance()._parseCommandLine(argc, argv); } 145 static void parseFile() { _getInstance()._parseFile(); } 137 146 138 147 static std::string getUsageInformation(); … … 146 155 { return getArgument(name)->getValue(); } 147 156 template <class T> 148 static CommandLineArgument& addArgument(const std::string& name, T defaultValue );157 static CommandLineArgument& addArgument(const std::string& name, T defaultValue, bool bCommandLineOnly); 149 158 150 159 static bool existsArgument(const std::string& name) … … 165 174 static CommandLine& _getInstance(); 166 175 167 void _parseAll(int argc, char** argv); 168 void _parse(const std::vector<std::string>& arguments); 169 void checkFullArgument(const std::string& name, const std::string& value); 170 void checkShortcut(const std::string& shortcut, const std::string& value); 176 void _parseCommandLine(int argc, char** argv); 177 void _parseFile(); 178 void _parse(const std::vector<std::string>& arguments, bool bParsingFile); 179 void checkFullArgument(const std::string& name, const std::string& value, bool bParsingFile); 180 void checkShortcut(const std::string& shortcut, const std::string& value, bool bParsingFile); 171 181 172 182 /** … … 199 209 */ 200 210 template <class T> 201 CommandLineArgument& CommandLine::addArgument(const std::string& name, T defaultValue )211 CommandLineArgument& CommandLine::addArgument(const std::string& name, T defaultValue, bool bCommandLineOnly) 202 212 { 203 213 OrxAssert(!_getInstance().existsArgument(name), 204 214 "Cannot add a command line argument with name '" + name + "' twice."); 205 206 return *(_getInstance().cmdLineArgs_[name] = new CommandLineArgument(name, defaultValue)); 215 OrxAssert(MultiType(defaultValue).getType() != MT_Type::Bool || MultiType(defaultValue).getBool() != true, 216 "Boolean command line arguments with positive default values are not supported." << std::endl 217 << "Please use SetCommandLineSwitch and adjust your argument: " << name); 218 219 return *(_getInstance().cmdLineArgs_[name] = new CommandLineArgument(name, defaultValue, bCommandLineOnly)); 207 220 } 208 221 } -
code/trunk/src/core/ConfigFileManager.cc
r3198 r3280 33 33 #include "util/Convert.h" 34 34 #include "util/Math.h" 35 #include "util/String .h"35 #include "util/StringUtils.h" 36 36 #include "ConsoleCommand.h" 37 37 #include "ConfigValueContainer.h" … … 124 124 { 125 125 if (this->additionalComment_ == "" || this->additionalComment_.size() == 0) 126 return (this->name_ + "[" + getConvertedValue<unsigned int, std::string>(this->index_, "0") + "]" + "=" + this->value_);127 else 128 return (this->name_ + "[" + getConvertedValue<unsigned int, std::string>(this->index_, "0") + "]=" + this->value_ + " " + this->additionalComment_);126 return (this->name_ + "[" + multi_cast<std::string>(this->index_) + "]" + "=" + this->value_); 127 else 128 return (this->name_ + "[" + multi_cast<std::string>(this->index_) + "]=" + this->value_ + " " + this->additionalComment_); 129 129 } 130 130 -
code/trunk/src/core/ConfigValueContainer.cc
r3196 r3280 78 78 for (unsigned int i = 0; i < this->valueVector_.size(); i++) 79 79 { 80 ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isType(MT_ string));80 ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isType(MT_Type::String)); 81 81 this->defvalueStringVector_.push_back(this->valueVector_[i]); 82 82 } … … 109 109 if (this->tset(input)) 110 110 { 111 ConfigFileManager::getInstance().setValue(this->type_, this->sectionname_, this->varname_, input, this->value_.isType(MT_ string));111 ConfigFileManager::getInstance().setValue(this->type_, this->sectionname_, this->varname_, input, this->value_.isType(MT_Type::String)); 112 112 return true; 113 113 } … … 128 128 if (this->tset(index, input)) 129 129 { 130 ConfigFileManager::getInstance().setValue(this->type_, this->sectionname_, this->varname_, index, input, this->value_.isType(MT_ string));130 ConfigFileManager::getInstance().setValue(this->type_, this->sectionname_, this->varname_, index, input, this->value_.isType(MT_Type::String)); 131 131 return true; 132 132 } … … 228 228 this->valueVector_.erase(this->valueVector_.begin() + index); 229 229 for (unsigned int i = index; i < this->valueVector_.size(); i++) 230 ConfigFileManager::getInstance().setValue(this->type_, this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isType(MT_ string));230 ConfigFileManager::getInstance().setValue(this->type_, this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isType(MT_Type::String)); 231 231 ConfigFileManager::getInstance().deleteVectorEntries(this->type_, this->sectionname_, this->varname_, this->valueVector_.size()); 232 232 … … 264 264 { 265 265 if (!this->bIsVector_) 266 this->value_ = ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, this->defvalueString_, this->value_.isType(MT_ string));266 this->value_ = ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, this->defvalueString_, this->value_.isType(MT_Type::String)); 267 267 else 268 268 { … … 273 273 if (i < this->defvalueStringVector_.size()) 274 274 { 275 this->value_ = ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, i, this->defvalueStringVector_[i], this->value_.isType(MT_ string));275 this->value_ = ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, i, this->defvalueStringVector_[i], this->value_.isType(MT_Type::String)); 276 276 } 277 277 else 278 278 { 279 this->value_ = ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, i, MultiType(), this->value_.isType(MT_ string));279 this->value_ = ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, i, MultiType(), this->value_.isType(MT_Type::String)); 280 280 } 281 281 -
code/trunk/src/core/ConfigValueIncludes.h
r2171 r3280 52 52 if (!container##varname) \ 53 53 { \ 54 container##varname = new orxonox::ConfigValueContainer( ConfigFileType::Settings, identifier##varname, identifier##varname->getName(), #varname, defvalue, varname); \54 container##varname = new orxonox::ConfigValueContainer(type, identifier##varname, identifier##varname->getName(), #varname, defvalue, varname); \ 55 55 identifier##varname->addConfigValueContainer(#varname, container##varname); \ 56 56 } \ … … 70 70 if (!container##varname) \ 71 71 { \ 72 container##varname = new orxonox::ConfigValueContainer( ConfigFileType::Settings, identifier##varname, identifier##varname->getName(), #varname, defvalue); \72 container##varname = new orxonox::ConfigValueContainer(type, identifier##varname, identifier##varname->getName(), #varname, defvalue); \ 73 73 identifier##varname->addConfigValueContainer(#varname, container##varname); \ 74 74 } \ -
code/trunk/src/core/ConsoleCommand.h
r3196 r3280 71 71 namespace AccessLevel 72 72 { 73 enum Level73 enum Value 74 74 { 75 75 None, … … 106 106 { this->Executor::setDefaultValue(index, param); return (*this); } 107 107 108 inline ConsoleCommand& accessLevel(AccessLevel:: Levellevel)108 inline ConsoleCommand& accessLevel(AccessLevel::Value level) 109 109 { this->accessLevel_ = level; return (*this); } 110 inline AccessLevel:: LevelgetAccessLevel() const110 inline AccessLevel::Value getAccessLevel() const 111 111 { return this->accessLevel_; } 112 112 … … 130 130 } 131 131 132 inline ConsoleCommand& keybindMode(KeybindMode:: Enummode)132 inline ConsoleCommand& keybindMode(KeybindMode::Value mode) 133 133 { this->keybindMode_ = mode; return *this; } 134 inline KeybindMode:: EnumgetKeybindMode() const134 inline KeybindMode::Value getKeybindMode() const 135 135 { return this->keybindMode_; } 136 136 … … 141 141 142 142 private: 143 AccessLevel:: LevelaccessLevel_;143 AccessLevel::Value accessLevel_; 144 144 ArgumentCompleter* argumentCompleter_[5]; 145 145 ArgumentCompletionList argumentList_; 146 146 147 KeybindMode:: EnumkeybindMode_;147 KeybindMode::Value keybindMode_; 148 148 int inputConfiguredParam_; 149 149 }; -
code/trunk/src/core/Core.cc
r3214 r3280 77 77 namespace orxonox 78 78 { 79 //! Path to the parent directory of the ones above if program was installed with relativ pahts80 static boost::filesystem::path rootPath_g;81 static boost::filesystem::path executablePath_g; //!< Path to the executable82 static boost::filesystem::path mediaPath_g; //!< Path to the media file folder83 static boost::filesystem::path configPath_g; //!< Path to the config file folder84 static boost::filesystem::path logPath_g; //!< Path to the log file folder85 86 79 //! Static pointer to the singleton 87 80 Core* Core::singletonRef_s = 0; 88 81 89 SetCommandLineArgument(mediaPath, "").information("PATH"); 90 SetCommandLineArgument(writingPathSuffix, "").information("DIR"); 91 SetCommandLineArgument(settingsFile, "orxonox.ini"); 92 SetCommandLineArgument(limitToCPU, 0).information("0: off | #cpu"); 93 94 Core::Core() 95 { 96 RegisterRootObject(Core); 97 98 assert(Core::singletonRef_s == 0); 82 SetCommandLineArgument(mediaPath, "").information("Path to the media/data files"); 83 SetCommandLineOnlyArgument(writingPathSuffix, "").information("Additional subfolder for config and log files"); 84 SetCommandLineArgument(settingsFile, "orxonox.ini").information("THE configuration file"); 85 #ifdef ORXONOX_PLATFORM_WINDOWS 86 SetCommandLineArgument(limitToCPU, 0).information("Limits the program to one cpu/core (1, 2, 3, etc.). 0 turns it off (default)"); 87 #endif 88 89 /** 90 @brief 91 Helper class for the Core singleton: we cannot derive 92 Core from OrxonoxClass because we need to handle the Identifier 93 destruction in the Core destructor. 94 */ 95 class CoreConfiguration : public OrxonoxClass 96 { 97 public: 98 CoreConfiguration() 99 { 100 } 101 102 void initialise() 103 { 104 RegisterRootObject(CoreConfiguration); 105 this->setConfigValues(); 106 107 // Possible media path override by the command line 108 if (!CommandLine::getArgument("mediaPath")->hasDefaultValue()) 109 tsetMediaPath(CommandLine::getValue("mediaPath")); 110 } 111 112 /** 113 @brief Function to collect the SetConfigValue-macro calls. 114 */ 115 void setConfigValues() 116 { 117 #ifdef NDEBUG 118 const unsigned int defaultLevelConsole = 1; 119 const unsigned int defaultLevelLogfile = 3; 120 const unsigned int defaultLevelShell = 1; 121 #else 122 const unsigned int defaultLevelConsole = 3; 123 const unsigned int defaultLevelLogfile = 4; 124 const unsigned int defaultLevelShell = 3; 125 #endif 126 SetConfigValue(softDebugLevelConsole_, defaultLevelConsole) 127 .description("The maximal level of debug output shown in the console") 128 .callback(this, &CoreConfiguration::debugLevelChanged); 129 SetConfigValue(softDebugLevelLogfile_, defaultLevelLogfile) 130 .description("The maximal level of debug output shown in the logfile") 131 .callback(this, &CoreConfiguration::debugLevelChanged); 132 SetConfigValue(softDebugLevelShell_, defaultLevelShell) 133 .description("The maximal level of debug output shown in the ingame shell") 134 .callback(this, &CoreConfiguration::debugLevelChanged); 135 136 SetConfigValue(language_, Language::getLanguage().defaultLanguage_) 137 .description("The language of the ingame text") 138 .callback(this, &CoreConfiguration::languageChanged); 139 SetConfigValue(bInitializeRandomNumberGenerator_, true) 140 .description("If true, all random actions are different each time you start the game") 141 .callback(this, &CoreConfiguration::initializeRandomNumberGenerator); 142 143 SetConfigValue(mediaPathString_, mediaPath_.string()) 144 .description("Relative path to the game data.") 145 .callback(this, &CoreConfiguration::mediaPathChanged); 146 } 147 148 /** 149 @brief Callback function if the debug level has changed. 150 */ 151 void debugLevelChanged() 152 { 153 // softDebugLevel_ is the maximum of the 3 variables 154 this->softDebugLevel_ = this->softDebugLevelConsole_; 155 if (this->softDebugLevelLogfile_ > this->softDebugLevel_) 156 this->softDebugLevel_ = this->softDebugLevelLogfile_; 157 if (this->softDebugLevelShell_ > this->softDebugLevel_) 158 this->softDebugLevel_ = this->softDebugLevelShell_; 159 160 OutputHandler::setSoftDebugLevel(OutputHandler::LD_All, this->softDebugLevel_); 161 OutputHandler::setSoftDebugLevel(OutputHandler::LD_Console, this->softDebugLevelConsole_); 162 OutputHandler::setSoftDebugLevel(OutputHandler::LD_Logfile, this->softDebugLevelLogfile_); 163 OutputHandler::setSoftDebugLevel(OutputHandler::LD_Shell, this->softDebugLevelShell_); 164 } 165 166 /** 167 @brief Callback function if the language has changed. 168 */ 169 void languageChanged() 170 { 171 // Read the translation file after the language was configured 172 Language::getLanguage().readTranslatedLanguageFile(); 173 } 174 175 /** 176 @brief 177 Callback function if the media path has changed. 178 */ 179 void mediaPathChanged() 180 { 181 mediaPath_ = boost::filesystem::path(this->mediaPathString_); 182 } 183 184 /** 185 @brief Sets the language in the config-file back to the default. 186 */ 187 void resetLanguage() 188 { 189 ResetConfigValue(language_); 190 } 191 192 /** 193 @brief 194 Temporary sets the media path 195 @param path 196 The new media path 197 */ 198 void tsetMediaPath(const std::string& path) 199 { 200 ModifyConfigValue(mediaPathString_, tset, path); 201 } 202 203 void initializeRandomNumberGenerator() 204 { 205 static bool bInitialized = false; 206 if (!bInitialized && this->bInitializeRandomNumberGenerator_) 207 { 208 srand(static_cast<unsigned int>(time(0))); 209 rand(); 210 bInitialized = true; 211 } 212 } 213 214 int softDebugLevel_; //!< The debug level 215 int softDebugLevelConsole_; //!< The debug level for the console 216 int softDebugLevelLogfile_; //!< The debug level for the logfile 217 int softDebugLevelShell_; //!< The debug level for the ingame shell 218 std::string language_; //!< The language 219 bool bInitializeRandomNumberGenerator_; //!< If true, srand(time(0)) is called 220 std::string mediaPathString_; //!< Path to the data/media file folder as string 221 222 //! Path to the parent directory of the ones above if program was installed with relativ pahts 223 boost::filesystem::path rootPath_; 224 boost::filesystem::path executablePath_; //!< Path to the executable 225 boost::filesystem::path mediaPath_; //!< Path to the media file folder 226 boost::filesystem::path configPath_; //!< Path to the config file folder 227 boost::filesystem::path logPath_; //!< Path to the log file folder 228 }; 229 230 231 Core::Core(int argc, char** argv) 232 { 233 if (singletonRef_s != 0) 234 { 235 COUT(0) << "Error: The Core singleton cannot be recreated! Shutting down." << std::endl; 236 abort(); 237 } 99 238 Core::singletonRef_s = this; 100 } 101 102 void Core::initialise(int argc, char** argv) 103 { 104 // Parse command line arguments fist 105 try 106 { 107 CommandLine::parseAll(argc, argv); 108 } 109 catch (ArgumentException& ex) 110 { 111 COUT(1) << ex.what() << std::endl; 112 COUT(0) << "Usage:" << std::endl << "orxonox " << CommandLine::getUsageInformation() << std::endl; 113 } 114 239 240 // We need the variables very soon. But don't configure them yet! 241 this->configuration_ = new CoreConfiguration(); 242 243 // Parse command line arguments first 244 CommandLine::parseCommandLine(argc, argv); 245 246 // Determine and set the location of the executable 247 setExecutablePath(); 248 249 // Determine whether we have an installed or a binary dir run 250 // The latter occurs when simply running from the build directory 251 checkDevBuild(); 252 253 // Make sure the directories we write in exist or else make them 254 createDirectories(); 255 256 // create a signal handler (only active for linux) 257 // This call is placed as soon as possible, but after the directories are set 258 this->signalHandler_ = new SignalHandler(); 259 this->signalHandler_->doCatch(configuration_->executablePath_.string(), Core::getLogPathString() + "orxonox_crash.log"); 260 261 // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used 262 OutputHandler::getOutStream().setLogPath(Core::getLogPathString()); 263 264 // Parse additional options file now that we know its path 265 CommandLine::parseFile(); 266 267 #ifdef ORXONOX_PLATFORM_WINDOWS 115 268 // limit the main thread to the first core so that QueryPerformanceCounter doesn't jump 116 269 // do this after ogre has initialised. Somehow Ogre changes the settings again (not through … … 118 271 int limitToCPU = CommandLine::getValue("limitToCPU"); 119 272 if (limitToCPU > 0) 120 setThreadAffinity((unsigned int)limitToCPU); 121 122 // Determine and set the location of the executable 123 setExecutablePath(); 124 125 // Determine whether we have an installed or a binary dir run 126 // The latter occurs when simply running from the build directory 127 checkDevBuild(); 128 129 // Make sure the directories we write in exist or else make them 130 createDirectories(); 131 132 // create a signal handler (only active for linux) 133 // This call is placed as soon as possible, but after the directories are set 134 this->signalHandler_ = new SignalHandler(); 135 this->signalHandler_->doCatch(executablePath_g.string(), Core::getLogPathString() + "orxonox_crash.log"); 136 137 // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used 138 OutputHandler::getOutStream().setLogPath(Core::getLogPathString()); 273 setThreadAffinity(static_cast<unsigned int>(limitToCPU)); 274 #endif 139 275 140 276 // Manage ini files and set the default settings file (usually orxonox.ini) … … 143 279 CommandLine::getValue("settingsFile").getString()); 144 280 281 // Required as well for the config values 145 282 this->languageInstance_ = new Language(); 146 283 147 284 // Do this soon after the ConfigFileManager has been created to open up the 148 285 // possibility to configure everything below here 149 this->setConfigValues(); 150 151 // Possible media path override by the command line 152 if (!CommandLine::getArgument("mediaPath")->hasDefaultValue()) 153 { 154 //std::string mediaPath = CommandLine::getValue("mediaPath"); 155 Core::tsetMediaPath(CommandLine::getValue("mediaPath")); 156 } 286 this->configuration_->initialise(); 157 287 158 288 // Create the lua interface … … 168 298 // creates the class hierarchy for all classes with factories 169 299 Factory::createClassHierarchy(); 170 171 this->loaded_ = true;172 300 } 173 301 … … 177 305 Core::~Core() 178 306 { 179 this->loaded_ = false;180 181 307 delete this->shell_; 182 308 delete this->tclThreadManager_; 183 309 delete this->tclBind_; 184 310 delete this->luaBind_; 311 delete this->configuration_; 185 312 delete this->languageInstance_; 186 313 delete this->configFileManager_; … … 190 317 // Also delete external console command that don't belong to an Identifier 191 318 CommandExecutor::destroyExternalCommands(); 192 193 assert(Core::singletonRef_s);194 Core::singletonRef_s = 0; 319 // Clean up class hierarchy stuff (identifiers, XMLPort, configValues, consoleCommand) 320 Identifier::destroyAllIdentifiers(); 321 195 322 delete this->signalHandler_; 196 } 197 198 /** 199 @brief Function to collect the SetConfigValue-macro calls. 200 */ 201 void Core::setConfigValues() 202 { 203 #ifdef NDEBUG 204 const unsigned int defaultLevelConsole = 1; 205 const unsigned int defaultLevelLogfile = 3; 206 const unsigned int defaultLevelShell = 1; 207 #else 208 const unsigned int defaultLevelConsole = 3; 209 const unsigned int defaultLevelLogfile = 4; 210 const unsigned int defaultLevelShell = 3; 211 #endif 212 SetConfigValue(softDebugLevelConsole_, defaultLevelConsole) 213 .description("The maximal level of debug output shown in the console").callback(this, &Core::debugLevelChanged); 214 SetConfigValue(softDebugLevelLogfile_, defaultLevelLogfile) 215 .description("The maximal level of debug output shown in the logfile").callback(this, &Core::debugLevelChanged); 216 SetConfigValue(softDebugLevelShell_, defaultLevelShell) 217 .description("The maximal level of debug output shown in the ingame shell").callback(this, &Core::debugLevelChanged); 218 219 SetConfigValue(language_, Language::getLanguage().defaultLanguage_).description("The language of the ingame text").callback(this, &Core::languageChanged); 220 SetConfigValue(bInitializeRandomNumberGenerator_, true).description("If true, all random actions are different each time you start the game").callback(this, &Core::initializeRandomNumberGenerator); 221 222 SetConfigValue(mediaPathString_, mediaPath_g.string()) 223 .description("Relative path to the game data.").callback(this, &Core::mediaPathChanged); 224 } 225 226 /** 227 @brief Callback function if the debug level has changed. 228 */ 229 void Core::debugLevelChanged() 230 { 231 // softDebugLevel_ is the maximum of the 3 variables 232 this->softDebugLevel_ = this->softDebugLevelConsole_; 233 if (this->softDebugLevelLogfile_ > this->softDebugLevel_) 234 this->softDebugLevel_ = this->softDebugLevelLogfile_; 235 if (this->softDebugLevelShell_ > this->softDebugLevel_) 236 this->softDebugLevel_ = this->softDebugLevelShell_; 237 238 OutputHandler::setSoftDebugLevel(OutputHandler::LD_All, this->softDebugLevel_); 239 OutputHandler::setSoftDebugLevel(OutputHandler::LD_Console, this->softDebugLevelConsole_); 240 OutputHandler::setSoftDebugLevel(OutputHandler::LD_Logfile, this->softDebugLevelLogfile_); 241 OutputHandler::setSoftDebugLevel(OutputHandler::LD_Shell, this->softDebugLevelShell_); 242 } 243 244 /** 245 @brief Callback function if the language has changed. 246 */ 247 void Core::languageChanged() 248 { 249 // Read the translation file after the language was configured 250 Language::getLanguage().readTranslatedLanguageFile(); 251 } 252 253 /** 254 @brief 255 Callback function if the media path has changed. 256 */ 257 void Core::mediaPathChanged() 258 { 259 mediaPath_g = boost::filesystem::path(this->mediaPathString_); 260 } 261 262 /** 263 @brief Returns the softDebugLevel for the given device (returns a default-value if the class ist right about to be created). 323 324 // Don't assign singletonRef_s with NULL! Recreation is not supported 325 } 326 327 /** 328 @brief Returns the softDebugLevel for the given device (returns a default-value if the class is right about to be created). 264 329 @param device The device 265 330 @return The softDebugLevel 266 331 */ 267 int Core::getSoftDebugLevel(OutputHandler::OutputDevice device)332 /*static*/ int Core::getSoftDebugLevel(OutputHandler::OutputDevice device) 268 333 { 269 334 switch (device) 270 335 { 271 336 case OutputHandler::LD_All: 272 return Core::getInstance(). softDebugLevel_;337 return Core::getInstance().configuration_->softDebugLevel_; 273 338 case OutputHandler::LD_Console: 274 return Core::getInstance(). softDebugLevelConsole_;339 return Core::getInstance().configuration_->softDebugLevelConsole_; 275 340 case OutputHandler::LD_Logfile: 276 return Core::getInstance(). softDebugLevelLogfile_;341 return Core::getInstance().configuration_->softDebugLevelLogfile_; 277 342 case OutputHandler::LD_Shell: 278 return Core::getInstance(). softDebugLevelShell_;343 return Core::getInstance().configuration_->softDebugLevelShell_; 279 344 default: 280 345 assert(0); … … 288 353 @param level The level 289 354 */ 290 void Core::setSoftDebugLevel(OutputHandler::OutputDevice device, int level)291 355 /*static*/ void Core::setSoftDebugLevel(OutputHandler::OutputDevice device, int level) 356 { 292 357 if (device == OutputHandler::LD_All) 293 Core::getInstance(). softDebugLevel_ = level;358 Core::getInstance().configuration_->softDebugLevel_ = level; 294 359 else if (device == OutputHandler::LD_Console) 295 Core::getInstance(). softDebugLevelConsole_ = level;360 Core::getInstance().configuration_->softDebugLevelConsole_ = level; 296 361 else if (device == OutputHandler::LD_Logfile) 297 Core::getInstance(). softDebugLevelLogfile_ = level;362 Core::getInstance().configuration_->softDebugLevelLogfile_ = level; 298 363 else if (device == OutputHandler::LD_Shell) 299 Core::getInstance(). softDebugLevelShell_ = level;364 Core::getInstance().configuration_->softDebugLevelShell_ = level; 300 365 301 366 OutputHandler::setSoftDebugLevel(device, level); 302 367 } 303 368 304 369 /** 305 370 @brief Returns the configured language. 306 371 */ 307 const std::string& Core::getLanguage()308 { 309 return Core::getInstance(). language_;372 /*static*/ const std::string& Core::getLanguage() 373 { 374 return Core::getInstance().configuration_->language_; 310 375 } 311 376 … … 313 378 @brief Sets the language in the config-file back to the default. 314 379 */ 315 void Core::resetLanguage() 316 { 317 Core::getInstance().resetLanguageIntern(); 318 } 319 320 /** 321 @brief Sets the language in the config-file back to the default. 322 */ 323 void Core::resetLanguageIntern() 324 { 325 ResetConfigValue(language_); 326 } 327 328 /** 329 @brief 330 Temporary sets the media path 331 @param path 332 The new media path 333 */ 334 void Core::_tsetMediaPath(const std::string& path) 335 { 336 ModifyConfigValue(mediaPathString_, tset, path); 380 /*static*/ void Core::resetLanguage() 381 { 382 Core::getInstance().configuration_->resetLanguage(); 383 } 384 385 /*static*/ void Core::tsetMediaPath(const std::string& path) 386 { 387 getInstance().configuration_->tsetMediaPath(path); 337 388 } 338 389 339 390 /*static*/ const boost::filesystem::path& Core::getMediaPath() 340 391 { 341 return mediaPath_g;392 return getInstance().configuration_->mediaPath_; 342 393 } 343 394 /*static*/ std::string Core::getMediaPathString() 344 395 { 345 return mediaPath_g.string() + '/';396 return getInstance().configuration_->mediaPath_.string() + '/'; 346 397 } 347 398 348 399 /*static*/ const boost::filesystem::path& Core::getConfigPath() 349 400 { 350 return configPath_g;401 return getInstance().configuration_->configPath_; 351 402 } 352 403 /*static*/ std::string Core::getConfigPathString() 353 404 { 354 return configPath_g.string() + '/';405 return getInstance().configuration_->configPath_.string() + '/'; 355 406 } 356 407 357 408 /*static*/ const boost::filesystem::path& Core::getLogPath() 358 409 { 359 return logPath_g;410 return getInstance().configuration_->logPath_; 360 411 } 361 412 /*static*/ std::string Core::getLogPathString() 362 413 { 363 return logPath_g.string() + '/'; 364 } 365 366 void Core::initializeRandomNumberGenerator() 367 { 368 static bool bInitialized = false; 369 if (!bInitialized && this->bInitializeRandomNumberGenerator_) 370 { 371 srand(static_cast<unsigned int>(time(0))); 372 rand(); 373 bInitialized = true; 374 } 375 } 376 414 return getInstance().configuration_->logPath_.string() + '/'; 415 } 377 416 378 417 /** … … 388 427 void Core::setThreadAffinity(int limitToCPU) 389 428 { 429 #ifdef ORXONOX_PLATFORM_WINDOWS 430 390 431 if (limitToCPU <= 0) 391 432 return; 392 433 393 #ifdef ORXONOX_PLATFORM_WINDOWS394 434 unsigned int coreNr = limitToCPU - 1; 395 435 // Get the current process core mask … … 465 505 #endif 466 506 467 executablePath_g= boost::filesystem::path(buffer);507 configuration_->executablePath_ = boost::filesystem::path(buffer); 468 508 #ifndef ORXONOX_PLATFORM_APPLE 469 executablePath_g = executablePath_g.branch_path(); // remove executable name509 configuration_->executablePath_ = configuration_->executablePath_.branch_path(); // remove executable name 470 510 #endif 471 511 } … … 481 521 void Core::checkDevBuild() 482 522 { 483 if (boost::filesystem::exists( executablePath_g/ "orxonox_dev_build.keep_me"))523 if (boost::filesystem::exists(configuration_->executablePath_ / "orxonox_dev_build.keep_me")) 484 524 { 485 525 COUT(1) << "Running from the build tree." << std::endl; 486 526 Core::isDevBuild_ = true; 487 mediaPath_g= ORXONOX_MEDIA_DEV_PATH;488 config Path_g= ORXONOX_CONFIG_DEV_PATH;489 logPath_g= ORXONOX_LOG_DEV_PATH;527 configuration_->mediaPath_ = ORXONOX_MEDIA_DEV_PATH; 528 configuration_->configPath_ = ORXONOX_CONFIG_DEV_PATH; 529 configuration_->logPath_ = ORXONOX_LOG_DEV_PATH; 490 530 } 491 531 else … … 494 534 // Also set the root path 495 535 boost::filesystem::path relativeExecutablePath(ORXONOX_RUNTIME_INSTALL_PATH); 496 rootPath_g = executablePath_g; 497 while (!boost::filesystem::equivalent(rootPath_g / relativeExecutablePath, executablePath_g) && !rootPath_g.empty()) 498 rootPath_g = rootPath_g.branch_path(); 499 if (rootPath_g.empty()) 536 configuration_->rootPath_ = configuration_->executablePath_; 537 while (!boost::filesystem::equivalent(configuration_->rootPath_ / relativeExecutablePath, configuration_->executablePath_) 538 && !configuration_->rootPath_.empty()) 539 configuration_->rootPath_ = configuration_->rootPath_.branch_path(); 540 if (configuration_->rootPath_.empty()) 500 541 ThrowException(General, "Could not derive a root directory. Might the binary installation directory contain '..' when taken relative to the installation prefix path?"); 501 542 502 543 // Using paths relative to the install prefix, complete them 503 mediaPath_g = rootPath_g/ ORXONOX_MEDIA_INSTALL_PATH;504 config Path_g = rootPath_g/ ORXONOX_CONFIG_INSTALL_PATH;505 logPath_g = rootPath_g/ ORXONOX_LOG_INSTALL_PATH;544 configuration_->mediaPath_ = configuration_->rootPath_ / ORXONOX_MEDIA_INSTALL_PATH; 545 configuration_->configPath_ = configuration_->rootPath_ / ORXONOX_CONFIG_INSTALL_PATH; 546 configuration_->logPath_ = configuration_->rootPath_ / ORXONOX_LOG_INSTALL_PATH; 506 547 #else 507 548 // There is no root path, so don't set it at all 508 549 509 mediaPath_g= ORXONOX_MEDIA_INSTALL_PATH;550 configuration_->mediaPath_ = ORXONOX_MEDIA_INSTALL_PATH; 510 551 511 552 // Get user directory … … 520 561 userDataPath /= ".orxonox"; 521 562 522 config Path_g= userDataPath / ORXONOX_CONFIG_INSTALL_PATH;523 logPath_g= userDataPath / ORXONOX_LOG_INSTALL_PATH;563 configuration_->configPath_ = userDataPath / ORXONOX_CONFIG_INSTALL_PATH; 564 configuration_->logPath_ = userDataPath / ORXONOX_LOG_INSTALL_PATH; 524 565 #endif 525 566 } … … 529 570 { 530 571 std::string directory(CommandLine::getValue("writingPathSuffix").getString()); 531 config Path_g = configPath_g/ directory;532 logPath_g = logPath_g/ directory;572 configuration_->configPath_ = configuration_->configPath_ / directory; 573 configuration_->logPath_ = configuration_->logPath_ / directory; 533 574 } 534 575 } … … 544 585 { 545 586 std::vector<std::pair<boost::filesystem::path, std::string> > directories; 546 directories.push_back(std::make_pair(boost::filesystem::path(config Path_g), "config"));547 directories.push_back(std::make_pair(boost::filesystem::path( logPath_g), "log"));587 directories.push_back(std::make_pair(boost::filesystem::path(configuration_->configPath_), "config")); 588 directories.push_back(std::make_pair(boost::filesystem::path(configuration_->logPath_), "log")); 548 589 549 590 for (std::vector<std::pair<boost::filesystem::path, std::string> >::iterator it = directories.begin(); -
code/trunk/src/core/Core.h
r3196 r3280 43 43 44 44 #include <cassert> 45 #include "OrxonoxClass.h"46 45 #include "util/OutputHandler.h" 47 46 48 47 namespace orxonox 49 48 { 49 class CoreConfiguration; 50 50 51 /** 51 52 @brief … … 55 56 It determines those by the use of platform specific functions. 56 57 */ 57 class _CoreExport Core : public OrxonoxClass58 class _CoreExport Core 58 59 { 59 60 public: … … 65 66 GeneralException 66 67 */ 67 Core( );68 Core(int argc, char** argv); 68 69 ~Core(); 69 70 70 void initialise(int argc, char** argv);71 71 void setConfigValues(); 72 72 … … 80 80 static void resetLanguage(); 81 81 82 static void tsetMediaPath(const std::string& path) 83 { assert(singletonRef_s); singletonRef_s->_tsetMediaPath(path); } 82 static void tsetMediaPath(const std::string& path); 84 83 //! Returns the path to the config files as boost::filesystem::path 85 84 static const boost::filesystem::path& getMediaPath(); … … 103 102 void setThreadAffinity(int limitToCPU); 104 103 105 void resetLanguageIntern();106 void initializeRandomNumberGenerator();107 void debugLevelChanged();108 void languageChanged();109 void mediaPathChanged();110 void _tsetMediaPath(const std::string& path);111 112 104 // Singletons 113 105 ConfigFileManager* configFileManager_; … … 119 111 TclThreadManager* tclThreadManager_; 120 112 121 int softDebugLevel_; //!< The debug level122 int softDebugLevelConsole_; //!< The debug level for the console123 int softDebugLevelLogfile_; //!< The debug level for the logfile124 int softDebugLevelShell_; //!< The debug level for the ingame shell125 std::string language_; //!< The language126 bool bInitializeRandomNumberGenerator_; //!< If true, srand(time(0)) is called127 std::string mediaPathString_; //!< Path to the data/media file folder as string128 113 bool isDevBuild_; //!< True for builds in the build directory (not installed) 129 bool loaded_; //!< Only true if constructor was interrupted114 CoreConfiguration* configuration_; 130 115 131 116 static Core* singletonRef_s; -
code/trunk/src/core/CorePrereqs.h
r3196 r3280 74 74 namespace KeybindMode 75 75 { 76 enum Enum76 enum Value 77 77 { 78 78 OnPress, … … 165 165 // game states 166 166 class Game; 167 struct GameStateConstrParams; 167 168 class GameState; 168 169 struct GameStateTreeNode; -
code/trunk/src/core/Executor.cc
r3196 r3280 99 99 100 100 // assign all given arguments to the multitypes 101 for (unsigned int i = 0; i < min(tokens.size(), (unsigned int)MAX_FUNCTOR_ARGUMENTS); i++)101 for (unsigned int i = 0; i < std::min(tokens.size(), (unsigned int)MAX_FUNCTOR_ARGUMENTS); i++) 102 102 param[i] = tokens[i]; 103 103 104 104 // fill the remaining multitypes with default values 105 for (unsigned int i = tokens.size(); i < min(paramCount, (unsigned int)MAX_FUNCTOR_ARGUMENTS); i++)105 for (unsigned int i = tokens.size(); i < std::min(paramCount, (unsigned int)MAX_FUNCTOR_ARGUMENTS); i++) 106 106 param[i] = this->defaultValue_[i]; 107 107 108 108 // evaluate the param types through the functor 109 for (unsigned int i = 0; i < min(paramCount, (unsigned int)MAX_FUNCTOR_ARGUMENTS); i++)109 for (unsigned int i = 0; i < std::min(paramCount, (unsigned int)MAX_FUNCTOR_ARGUMENTS); i++) 110 110 this->functor_->evaluateParam(i, param[i]); 111 111 -
code/trunk/src/core/Executor.h
r3196 r3280 33 33 #include "CorePrereqs.h" 34 34 35 #include <algorithm> 36 #include <string> 37 35 38 #include "util/Debug.h" 36 39 #include "util/Math.h" 37 #include "util/String .h"40 #include "util/StringUtils.h" 38 41 #include "util/SubString.h" 39 42 #include "Functor.h" … … 101 104 COUT(5) << tokens[i]; \ 102 105 } \ 103 COUT(5) << ") and " << max((int)paramCount - (int)tokens.size(), 0) << " default values ("; \106 COUT(5) << ") and " << std::max((int)paramCount - (int)tokens.size(), 0) << " default values ("; \ 104 107 for (unsigned int i = tokens.size(); i < paramCount; i++) \ 105 108 { \ … … 175 178 inline bool hasReturnvalue() const 176 179 { return this->functor_->hasReturnvalue(); } 177 inline FunctionType getType() const180 inline FunctionType::Value getType() const 178 181 { return this->functor_->getType(); } 179 182 inline const MultiType& getReturnvalue() const … … 201 204 return this->defaultValue_[index]; 202 205 203 return MT_ null;206 return MT_Type::Null; 204 207 } 205 208 -
code/trunk/src/core/Functor.h
r3196 r3280 35 35 #include "util/Debug.h" 36 36 #include "util/MultiType.h" 37 #include "util/String .h"37 #include "util/StringUtils.h" 38 38 39 39 namespace orxonox … … 41 41 const unsigned int MAX_FUNCTOR_ARGUMENTS = 5; 42 42 43 enumFunctionType43 namespace FunctionType 44 44 { 45 FT_MEMBER, 46 FT_CONSTMEMBER, 47 FT_STATIC 48 }; 45 enum Value 46 { 47 Member, 48 ConstMember, 49 Static 50 }; 51 } 49 52 50 53 … … 98 101 virtual ~Functor() {} 99 102 100 virtual void operator()(const MultiType& param1 = MT_ null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) = 0;103 virtual void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0; 101 104 102 105 inline unsigned int getParamCount() const { return this->numParams_; } 103 106 inline bool hasReturnvalue() const { return this->hasReturnValue_; } 104 inline FunctionType getType() const { return this->type_; }107 inline FunctionType::Value getType() const { return this->type_; } 105 108 inline const MultiType& getReturnvalue() const { return this->returnedValue_; } 106 109 … … 113 116 unsigned int numParams_; 114 117 bool hasReturnValue_; 115 FunctionType type_;118 FunctionType::Value type_; 116 119 MultiType returnedValue_; 117 120 … … 124 127 public: 125 128 virtual ~FunctorStatic() {} 126 virtual void operator()(const MultiType& param1 = MT_ null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) = 0;129 virtual void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0; 127 130 }; 128 131 … … 139 142 virtual ~FunctorMember() {} 140 143 141 virtual void operator()(T* object, const MultiType& param1 = MT_ null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) = 0;142 virtual void operator()(const T* object, const MultiType& param1 = MT_ null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) = 0;143 144 virtual void operator()(const MultiType& param1 = MT_ null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null)144 virtual void operator()(T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0; 145 virtual void operator()(const T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0; 146 147 virtual void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) 145 148 { 146 149 if (this->bConstObject_) … … 322 325 this->numParams_ = numparams; \ 323 326 this->hasReturnValue_ = returnvalue; \ 324 this->type_ = F T_STATIC; \327 this->type_ = FunctionType::Static; \ 325 328 this->functionPointer_ = functionPointer; \ 326 329 \ … … 329 332 } \ 330 333 \ 331 void operator()(const MultiType& param1 = MT_ null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) \334 void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \ 332 335 { \ 333 336 FUNCTOR_STORE_RETURNVALUE(returnvalue, (*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \ … … 363 366 this->numParams_ = numparams; \ 364 367 this->hasReturnValue_ = returnvalue; \ 365 this->type_ = F T_MEMBER; \368 this->type_ = FunctionType::Member; \ 366 369 this->functionPointer_ = functionPointer; \ 367 370 } \ 368 371 \ 369 void operator()(T* object, const MultiType& param1 = MT_ null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) \372 void operator()(T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \ 370 373 { \ 371 374 FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \ 372 375 } \ 373 376 \ 374 void operator()(const T* object, const MultiType& param1 = MT_ null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) \377 void operator()(const T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \ 375 378 { \ 376 379 COUT(1) << "An error occurred in Functor.h:" << std::endl; \ … … 396 399 this->numParams_ = numparams; \ 397 400 this->hasReturnValue_ = returnvalue; \ 398 this->type_ = F T_CONSTMEMBER; \401 this->type_ = FunctionType::ConstMember; \ 399 402 this->functionPointer_ = functionPointer; \ 400 403 } \ 401 404 \ 402 void operator()(T* object, const MultiType& param1 = MT_ null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) \405 void operator()(T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \ 403 406 { \ 404 407 FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \ 405 408 } \ 406 409 \ 407 void operator()(const T* object, const MultiType& param1 = MT_ null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) \410 void operator()(const T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \ 408 411 { \ 409 412 FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \ -
code/trunk/src/core/Game.cc
r3196 r3280 58 58 SetConsoleCommandShortcutExternAlias(stop_game, "exit"); 59 59 60 struct _CoreExport GameStateTreeNode 60 std::map<std::string, Game::GameStateInfo> Game::gameStateDeclarations_s; 61 Game* Game::singletonRef_s = 0; 62 63 64 /** 65 @brief 66 Represents one node of the game state tree. 67 */ 68 struct GameStateTreeNode 61 69 { 62 70 GameState* state_; … … 65 73 }; 66 74 67 std::map<std::string, GameState*> Game::allStates_s; 68 Game* Game::singletonRef_s = 0; 75 76 /** 77 @brief 78 Another helper class for the Game singleton: we cannot derive 79 Game from OrxonoxClass because we need to handle the Identifier 80 destruction in the Core destructor. 81 */ 82 class GameConfiguration : public OrxonoxClass 83 { 84 public: 85 GameConfiguration() 86 { 87 RegisterRootObject(GameConfiguration); 88 this->setConfigValues(); 89 } 90 91 void setConfigValues() 92 { 93 SetConfigValue(statisticsRefreshCycle_, 250000) 94 .description("Sets the time in microseconds interval at which average fps, etc. get updated."); 95 SetConfigValue(statisticsAvgLength_, 1000000) 96 .description("Sets the time in microseconds interval at which average fps, etc. gets calculated."); 97 } 98 99 unsigned int statisticsRefreshCycle_; 100 unsigned int statisticsAvgLength_; 101 }; 102 69 103 70 104 /** … … 74 108 Game::Game(int argc, char** argv) 75 109 { 76 assert(singletonRef_s == 0); 110 if (singletonRef_s != 0) 111 { 112 COUT(0) << "Error: The Game singleton cannot be recreated! Shutting down." << std::endl; 113 abort(); 114 } 77 115 singletonRef_s = this; 78 116 79 this->abort_ = false; 117 this->bAbort_ = false; 118 bChangingState_ = false; 119 120 // Create an empty root state 121 declareGameState<GameState>("GameState", "emptyRootGameState", true, false); 80 122 81 123 // reset statistics … … 87 129 this->avgTickTime_ = 0.0f; 88 130 89 90 131 // Set up a basic clock to keep time 91 132 this->gameClock_ = new Clock(); 92 133 93 this->core_ = new orxonox::Core(); 94 this->core_->initialise(argc, argv); 95 96 RegisterRootObject(Game); 97 this->setConfigValues(); 134 // Create the Core 135 this->core_ = new Core(argc, argv); 136 137 // After the core has been created, we can safely instantiate the GameStates 138 for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin(); 139 it != gameStateDeclarations_s.end(); ++it) 140 { 141 // Only create the states appropriate for the game mode 142 //if (GameMode::showsGraphics || !it->second.bGraphicsMode) 143 GameStateConstrParams params = { it->second.stateName, it->second.bIgnoreTickTime }; 144 gameStates_[getLowercase(it->second.stateName)] = GameStateFactory::fabricate(it->second.className, params); 145 } 146 147 // The empty root state is ALWAYS loaded! 148 this->rootStateNode_ = shared_ptr<GameStateTreeNode>(new GameStateTreeNode()); 149 this->rootStateNode_->state_ = getState("emptyRootGameState"); 150 this->activeStateNode_ = this->rootStateNode_; 151 this->activeStates_.push_back(this->rootStateNode_->state_); 152 153 // Do this after the Core creation! 154 this->configuration_ = new GameConfiguration(); 98 155 } 99 156 … … 103 160 Game::~Game() 104 161 { 105 // Destroy pretty much everyhting left 162 // Destroy the configuration helper class instance 163 delete this->configuration_; 164 165 // Destroy the GameStates (note that the nodes still point to them, but doesn't matter) 166 for (std::map<std::string, GameState*>::const_iterator it = gameStates_.begin(); 167 it != gameStates_.end(); ++it) 168 delete it->second; 169 170 // Destroy the Core and with it almost everything 106 171 delete this->core_; 107 108 172 delete this->gameClock_; 109 173 110 assert(singletonRef_s); 111 singletonRef_s = 0; 112 } 113 114 void Game::setConfigValues() 115 { 116 SetConfigValue(statisticsRefreshCycle_, 250000) 117 .description("Sets the time in microseconds interval at which average fps, etc. get updated."); 118 SetConfigValue(statisticsAvgLength_, 1000000) 119 .description("Sets the time in microseconds interval at which average fps, etc. gets calculated."); 120 SetConfigValue(levelName_, "presentation_dm.oxw") 121 .description("Sets the preselection of the level in the main menu."); 122 } 123 124 void Game::setLevel(std::string levelName) 125 { 126 ModifyConfigValue(levelName_, set, levelName); 127 } 128 129 std::string Game::getLevel() 130 { 131 std::string levelName; 132 CommandLine::getValue("level", &levelName); 133 if (levelName == "") 134 return levelName_; 135 else 136 return levelName; 174 // Take care of the GameStateFactories 175 GameStateFactory::destroyFactories(); 176 177 // Don't assign singletonRef_s with NULL! Recreation is not supported 137 178 } 138 179 … … 147 188 void Game::run() 148 189 { 149 // Always start with the ROOT state 150 this->requestedStateNodes_.push_back(this->rootStateNode_); 151 this->activeStateNode_ = this->rootStateNode_; 152 this->loadState(this->rootStateNode_->state_); 190 if (this->requestedStateNodes_.empty()) 191 COUT(0) << "Warning: Starting game without requesting GameState. This automatically terminates the program." << std::endl; 153 192 154 193 // START GAME 155 194 this->gameClock_->capture(); // first delta time should be about 0 seconds 156 while (!this-> abort_ && !this->activeStates_.empty())195 while (!this->bAbort_ && (!this->activeStates_.empty() || this->requestedStateNodes_.size() > 0)) 157 196 { 158 197 this->gameClock_->capture(); … … 160 199 161 200 // STATISTICS 162 statisticsTickInfo tickInfo = {currentTime, 0};201 StatisticsTickInfo tickInfo = {currentTime, 0}; 163 202 statisticsTickTimes_.push_back(tickInfo); 164 203 this->periodTime_ += this->gameClock_->getDeltaTimeMicroseconds(); 165 204 166 205 // UPDATE STATE STACK 167 while (this->requestedStateNodes_.size() > 1)168 { 169 // Note: this->requestedStateNodes_.front() is the currently active state node170 std::vector<shared_ptr<GameStateTreeNode> >::iterator it = this->requestedStateNodes_.begin() + 1;171 if ( *it== this->activeStateNode_->parent_.lock())206 while (this->requestedStateNodes_.size() > 0) 207 { 208 shared_ptr<GameStateTreeNode> requestedStateNode = this->requestedStateNodes_.front(); 209 assert(this->activeStateNode_); 210 if (!this->activeStateNode_->parent_.expired() && requestedStateNode == this->activeStateNode_->parent_.lock()) 172 211 this->unloadState(this->activeStateNode_->state_); 173 212 else // has to be child 174 this->loadState((*it)->state_); 175 this->activeStateNode_ = *it; 213 { 214 try 215 { 216 this->loadState(requestedStateNode->state_); 217 } 218 catch (const std::exception& ex) 219 { 220 COUT(1) << "Error: Loading GameState '" << requestedStateNode->state_->getName() << "' failed: " << ex.what() << std::endl; 221 // All scheduled operations have now been rendered inert --> flush them and issue a warning 222 if (this->requestedStateNodes_.size() > 1) 223 COUT(1) << "All " << this->requestedStateNodes_.size() - 1 << " scheduled transitions have been ignored." << std::endl; 224 this->requestedStateNodes_.clear(); 225 break; 226 } 227 } 228 this->activeStateNode_ = requestedStateNode; 176 229 this->requestedStateNodes_.erase(this->requestedStateNodes_.begin()); 177 230 } 178 231 179 // UPDATE, bottom to top in the stack 180 this->core_->update(*this->gameClock_); 181 for (std::vector<GameState*>::const_iterator it = this->activeStates_.begin(); 232 // UPDATE, Core first 233 try 234 { 235 this->core_->update(*this->gameClock_); 236 } 237 catch (...) 238 { 239 COUT(0) << "An exception occured while ticking the Core. This should really never happen!" << std::endl; 240 COUT(0) << "Closing the program." << std::endl; 241 this->stop(); 242 break; 243 } 244 245 // UPDATE, GameStates bottom to top in the stack 246 // Note: The first element is the empty root state, which doesn't need ticking 247 for (std::vector<GameState*>::const_iterator it = this->activeStates_.begin() + 1; 182 248 it != this->activeStates_.end(); ++it) 183 249 { 184 // Add tick time for most of the states 185 uint64_t timeBeforeTick; 186 if ((*it)->getCountTickTime()) 187 timeBeforeTick = this->gameClock_->getRealMicroseconds(); 188 189 (*it)->update(*this->gameClock_); 190 191 if ((*it)->getCountTickTime()) 192 this->addTickTime(static_cast<uint32_t>(this->gameClock_->getRealMicroseconds() - timeBeforeTick)); 250 bool threwException = false; 251 try 252 { 253 // Add tick time for most of the states 254 uint64_t timeBeforeTick; 255 if (!(*it)->ignoreTickTime()) 256 timeBeforeTick = this->gameClock_->getRealMicroseconds(); 257 (*it)->update(*this->gameClock_); 258 if (!(*it)->ignoreTickTime()) 259 this->addTickTime(static_cast<uint32_t>(this->gameClock_->getRealMicroseconds() - timeBeforeTick)); 260 } 261 catch (const std::exception& ex) 262 { 263 threwException = true; 264 COUT(0) << "Exception while ticking: " << ex.what() << std::endl; 265 } 266 catch (...) 267 { 268 threwException = true; 269 } 270 if (threwException) 271 { 272 COUT(1) << "An exception occured while ticking GameState '" << (*it)->getName() << "'. This should really never happen!" << std::endl; 273 COUT(1) << "Unloading all GameStates depending on the one that crashed." << std::endl; 274 if ((*it)->getParent() != NULL) 275 this->requestState((*it)->getParent()->getName()); 276 else 277 this->stop(); 278 break; 279 } 280 193 281 } 194 282 195 283 // STATISTICS 196 if (this->periodTime_ > statisticsRefreshCycle_)197 { 198 std::list< statisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();284 if (this->periodTime_ > this->configuration_->statisticsRefreshCycle_) 285 { 286 std::list<StatisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin(); 199 287 assert(it != this->statisticsTickTimes_.end()); 200 int64_t lastTime = currentTime - this-> statisticsAvgLength_;288 int64_t lastTime = currentTime - this->configuration_->statisticsAvgLength_; 201 289 if ((int64_t)it->tickTime < lastTime) 202 290 { 203 291 do 204 292 { 205 assert(this->periodTickTime_ > it->tickLength);293 assert(this->periodTickTime_ >= it->tickLength); 206 294 this->periodTickTime_ -= it->tickLength; 207 295 ++it; … … 215 303 this->avgTickTime_ = static_cast<float>(this->periodTickTime_) / framesPerPeriod / 1000.0f; 216 304 217 this->periodTime_ -= this-> statisticsRefreshCycle_;305 this->periodTime_ -= this->configuration_->statisticsRefreshCycle_; 218 306 } 219 307 } 220 308 221 309 // UNLOAD all remaining states 222 while ( !this->activeStates_.empty())310 while (this->activeStates_.size() > 1) 223 311 this->unloadState(this->activeStates_.back()); 224 this->activeStateNode_ .reset();312 this->activeStateNode_ = this->rootStateNode_; 225 313 this->requestedStateNodes_.clear(); 226 314 } … … 228 316 void Game::stop() 229 317 { 230 this-> abort_ = true;318 this->bAbort_ = true; 231 319 } 232 320 … … 244 332 { 245 333 GameState* state = this->getState(name); 246 if (state == NULL || this->activeStateNode_ == NULL)334 if (state == NULL) 247 335 return; 248 336 249 shared_ptr<GameStateTreeNode> requestedNode; 250 251 // this->requestedStateNodes_.back() is the currently active state 252 shared_ptr<GameStateTreeNode> lastRequestedNode = this->requestedStateNodes_.back(); 253 254 // Already the active node? 337 //if (this->bChangingState_) 338 //{ 339 // COUT(2) << "Warning: Requesting GameStates while loading/unloading a GameState is illegal! Ignoring." << std::endl; 340 // return; 341 //} 342 343 shared_ptr<GameStateTreeNode> lastRequestedNode; 344 if (this->requestedStateNodes_.empty()) 345 lastRequestedNode = this->activeStateNode_; 346 else 347 lastRequestedNode = this->requestedStateNodes_.back(); 255 348 if (state == lastRequestedNode->state_) 256 349 { … … 260 353 261 354 // Check children first 355 std::vector<shared_ptr<GameStateTreeNode> > requestedNodes; 262 356 for (unsigned int i = 0; i < lastRequestedNode->children_.size(); ++i) 263 357 { 264 358 if (lastRequestedNode->children_[i]->state_ == state) 265 359 { 266 requestedNode = lastRequestedNode->children_[i];360 requestedNodes.push_back(lastRequestedNode->children_[i]); 267 361 break; 268 362 } 269 363 } 270 364 271 // Check parent and all its grand parents 272 shared_ptr<GameStateTreeNode> currentNode = lastRequestedNode; 273 while (requestedNode == NULL && currentNode != NULL) 274 { 275 if (currentNode->state_ == state) 276 requestedNode = currentNode; 277 currentNode = currentNode->parent_.lock(); 278 } 279 280 if (requestedNode == NULL) 365 if (requestedNodes.empty()) 366 { 367 // Check parent and all its grand parents 368 shared_ptr<GameStateTreeNode> currentNode = lastRequestedNode; 369 while (currentNode != NULL) 370 { 371 if (currentNode->state_ == state) 372 break; 373 currentNode = currentNode->parent_.lock(); 374 requestedNodes.push_back(currentNode); 375 } 376 } 377 378 if (requestedNodes.empty()) 281 379 COUT(1) << "Error: Requested GameState transition is not allowed. Ignoring." << std::endl; 282 380 else 283 this->requestedStateNodes_. push_back(requestedNode);381 this->requestedStateNodes_.insert(requestedStateNodes_.end(), requestedNodes.begin(), requestedNodes.end()); 284 382 } 285 383 … … 293 391 void Game::popState() 294 392 { 295 if (this->activeStateNode_ != NULL && this->requestedStateNodes_.back()->parent_.lock()) 296 this->requestState(this->requestedStateNodes_.back()->parent_.lock()->state_->getName()); 393 shared_ptr<GameStateTreeNode> lastRequestedNode; 394 if (this->requestedStateNodes_.empty()) 395 lastRequestedNode = this->activeStateNode_; 297 396 else 298 COUT(2) << "Warning: Could not pop GameState. Ignoring." << std::endl; 397 lastRequestedNode = this->requestedStateNodes_.back(); 398 if (lastRequestedNode != this->rootStateNode_) 399 this->requestState(lastRequestedNode->parent_.lock()->state_->getName()); 400 else 401 COUT(2) << "Warning: Can't pop the internal dummy root GameState" << std::endl; 299 402 } 300 403 301 404 GameState* Game::getState(const std::string& name) 302 405 { 303 std::map<std::string, GameState*>::const_iterator it = allStates_s.find(getLowercase(name));304 if (it != allStates_s.end())406 std::map<std::string, GameState*>::const_iterator it = gameStates_.find(getLowercase(name)); 407 if (it != gameStates_.end()) 305 408 return it->second; 306 409 else … … 325 428 while(pos < str.size() && str[pos] != ' ') 326 429 ++pos; 327 stateStrings.push_back(std::pair<std::string, unsigned>( 328 str.substr(startPos, pos - startPos), indentation)); 430 stateStrings.push_back(std::make_pair(str.substr(startPos, pos - startPos), indentation)); 329 431 } 330 432 unsigned int currentLevel = 0; 331 shared_ptr<GameStateTreeNode> currentNode ;433 shared_ptr<GameStateTreeNode> currentNode = this->rootStateNode_; 332 434 for (std::vector<std::pair<std::string, unsigned> >::const_iterator it = stateStrings.begin(); it != stateStrings.end(); ++it) 333 435 { 334 436 std::string newStateName = it->first; 335 unsigned newLevel = it->second ;437 unsigned newLevel = it->second + 1; // empty root is 0 336 438 GameState* newState = this->getState(newStateName); 337 439 if (!newState) 338 ThrowException(GameState, std::string("GameState with name '") + newStateName + "' not found!"); 339 if (newLevel == 0) 340 { 341 // root 342 if (this->rootStateNode_ != NULL) 343 ThrowException(GameState, "No two root GameStates are allowed!"); 344 shared_ptr<GameStateTreeNode> newNode(new GameStateTreeNode); 345 newNode->state_ = newState; 346 this->rootStateNode_ = newNode; 347 currentNode = this->rootStateNode_; 348 } 349 else if (currentNode) 350 { 351 shared_ptr<GameStateTreeNode> newNode(new GameStateTreeNode); 352 newNode->state_ = newState; 353 if (newLevel < currentLevel) 354 { 355 // Get down the hierarchy 356 do 357 currentNode = currentNode->parent_.lock(); 358 while (newLevel < --currentLevel); 359 } 360 if (newLevel == currentLevel) 361 { 362 // same level 363 newNode->parent_ = currentNode->parent_; 364 newNode->parent_.lock()->children_.push_back(newNode); 365 } 366 else if (newLevel == currentLevel + 1) 367 { 368 // child 369 newNode->parent_ = currentNode; 370 currentNode->children_.push_back(newNode); 371 } 372 else 373 ThrowException(GameState, "Indentation error while parsing the hierarchy."); 374 currentNode = newNode; 375 currentLevel = newLevel; 440 ThrowException(GameState, "GameState with name '" << newStateName << "' not found!"); 441 if (newState == this->rootStateNode_->state_) 442 ThrowException(GameState, "You shouldn't use 'emptyRootGameState' in the hierarchy..."); 443 shared_ptr<GameStateTreeNode> newNode(new GameStateTreeNode); 444 newNode->state_ = newState; 445 446 if (newLevel <= currentLevel) 447 { 448 do 449 currentNode = currentNode->parent_.lock(); 450 while (newLevel <= --currentLevel); 451 } 452 if (newLevel == currentLevel + 1) 453 { 454 // Add the child 455 newNode->parent_ = currentNode; 456 currentNode->children_.push_back(newNode); 457 currentNode->state_->addChild(newNode->state_); 376 458 } 377 459 else 378 {379 ThrowException(GameState, "No root GameState specified!");380 }460 ThrowException(GameState, "Indentation error while parsing the hierarchy."); 461 currentNode = newNode; 462 currentLevel = newLevel; 381 463 } 382 464 } … … 386 468 void Game::loadState(GameState* state) 387 469 { 470 this->bChangingState_ = true; 471 state->activate(); 388 472 if (!this->activeStates_.empty()) 389 473 this->activeStates_.back()->activity_.topState = false; 390 state->activate();474 this->activeStates_.push_back(state); 391 475 state->activity_.topState = true; 392 this-> activeStates_.push_back(state);476 this->bChangingState_ = false; 393 477 } 394 478 395 479 void Game::unloadState(orxonox::GameState* state) 396 480 { 481 this->bChangingState_ = true; 397 482 state->activity_.topState = false; 398 state->deactivate();399 483 this->activeStates_.pop_back(); 400 484 if (!this->activeStates_.empty()) 401 485 this->activeStates_.back()->activity_.topState = true; 402 } 403 404 /*static*/ bool Game::addGameState(GameState* state) 405 { 406 std::map<std::string, GameState*>::const_iterator it = allStates_s.find(getLowercase(state->getName())); 407 if (it == allStates_s.end()) 408 allStates_s[getLowercase(state->getName())] = state; 409 else 410 ThrowException(GameState, "Cannot add two GameStates with the same name to 'Game'."); 411 412 // just a required dummy return value 413 return true; 414 } 415 416 /*static*/ void Game::destroyStates() 417 { 418 // Delete all GameStates created by the macros 419 for (std::map<std::string, GameState*>::const_iterator it = allStates_s.begin(); it != allStates_s.end(); ++it) 486 try 487 { 488 state->deactivate(); 489 } 490 catch (const std::exception& ex) 491 { 492 COUT(2) << "Warning: Unloading GameState '" << state->getName() << "' threw an exception: " << ex.what() << std::endl; 493 COUT(2) << " There might be potential resource leaks involved! To avoid this, improve exception-safety." << std::endl; 494 } 495 this->bChangingState_ = false; 496 } 497 498 std::map<std::string, Game::GameStateFactory*> Game::GameStateFactory::factories_s; 499 500 /*static*/ GameState* Game::GameStateFactory::fabricate(const std::string& className, const GameStateConstrParams& params) 501 { 502 std::map<std::string, GameStateFactory*>::const_iterator it = factories_s.find(className); 503 assert(it != factories_s.end()); 504 return it->second->fabricate(params); 505 } 506 507 /*static*/ void Game::GameStateFactory::destroyFactories() 508 { 509 for (std::map<std::string, GameStateFactory*>::const_iterator it = factories_s.begin(); it != factories_s.end(); ++it) 420 510 delete it->second; 421 allStates_s.clear();511 factories_s.clear(); 422 512 } 423 513 } -
code/trunk/src/core/Game.h
r3196 r3280 46 46 #include <boost/preprocessor/cat.hpp> 47 47 48 #include "OrxonoxClass.h" 48 #include "util/Debug.h" 49 #include "util/StringUtils.h" 49 50 50 51 /** … … 53 54 and every following paramter is a constructor argument (which is usually non existent) 54 55 */ 55 #define AddGameState(classname, ...) \56 static bool BOOST_PP_CAT(bGameStateDummy_##class name, __LINE__) = orxonox::Game::addGameState(new classname(__VA_ARGS__))56 #define DeclareGameState(className, stateName, bIgnoreTickTime, bGraphicsMode) \ 57 static bool BOOST_PP_CAT(bGameStateDummy_##className, __LINE__) = orxonox::Game::declareGameState<className>(#className, stateName, bIgnoreTickTime, bGraphicsMode) 57 58 58 // tolua_begin59 59 namespace orxonox 60 60 { 61 class GameConfiguration; 62 61 63 /** 62 64 @brief … … 64 66 */ 65 67 class _CoreExport Game 66 // tolua_end67 : public OrxonoxClass68 // tolua_begin69 68 { 70 //tolua_end71 69 public: 72 70 Game(int argc, char** argv); 73 71 ~Game(); 74 void setConfigValues();75 72 76 73 void setStateHierarchy(const std::string& str); … … 91 88 void addTickTime(uint32_t length); 92 89 93 static bool addGameState(GameState* state); 94 static void destroyStates(); 95 static Game& getInstance() { assert(singletonRef_s); return *singletonRef_s; } //tolua_export 96 97 void setLevel(std::string levelName); //tolua_export 98 std::string getLevel(); //tolua_export 90 template <class T> 91 static bool declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bConsoleMode); 92 static Game& getInstance() { assert(singletonRef_s); return *singletonRef_s; } 99 93 100 94 private: 101 struct statisticsTickInfo 95 class _CoreExport GameStateFactory 96 { 97 public: 98 virtual ~GameStateFactory() { } 99 static GameState* fabricate(const std::string& className, const GameStateConstrParams& params); 100 template <class T> 101 static void createFactory(const std::string& className) 102 { factories_s[className] = new TemplateGameStateFactory<T>(); } 103 static void destroyFactories(); 104 private: 105 virtual GameState* fabricate(const GameStateConstrParams& params) = 0; 106 static std::map<std::string, GameStateFactory*> factories_s; 107 }; 108 template <class T> 109 class TemplateGameStateFactory : public GameStateFactory 110 { 111 public: 112 GameState* fabricate(const GameStateConstrParams& params) 113 { return new T(params); } 114 }; 115 116 struct GameStateInfo 117 { 118 std::string stateName; 119 std::string className; 120 bool bIgnoreTickTime; 121 bool bGraphicsMode; 122 }; 123 124 struct StatisticsTickInfo 102 125 { 103 126 uint64_t tickTime; … … 110 133 void unloadState(GameState* state); 111 134 112 std::vector<GameState*> activeStates_; 135 std::map<std::string, GameState*> gameStates_; 136 std::vector<GameState*> activeStates_; 113 137 boost::shared_ptr<GameStateTreeNode> rootStateNode_; 114 138 boost::shared_ptr<GameStateTreeNode> activeStateNode_; … … 117 141 Core* core_; 118 142 Clock* gameClock_; 143 GameConfiguration* configuration_; 119 144 120 bool abort_; 145 bool bChangingState_; 146 bool bAbort_; 121 147 122 148 // variables for time statistics 123 149 uint64_t statisticsStartTime_; 124 std::list< statisticsTickInfo> statisticsTickTimes_;150 std::list<StatisticsTickInfo> statisticsTickTimes_; 125 151 uint32_t periodTime_; 126 152 uint32_t periodTickTime_; … … 128 154 float avgTickTime_; 129 155 130 // config values 131 unsigned int statisticsRefreshCycle_; 132 unsigned int statisticsAvgLength_; 133 std::string levelName_; 156 static std::map<std::string, GameStateInfo> gameStateDeclarations_s; 157 static Game* singletonRef_s; //!< Pointer to the Singleton 158 }; 134 159 135 static std::map<std::string, GameState*> allStates_s; 136 static Game* singletonRef_s; //!< Pointer to the Singleton 137 // tolua_begin 138 }; 160 template <class T> 161 /*static*/ bool Game::declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bGraphicsMode) 162 { 163 std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(getLowercase(stateName)); 164 if (it == gameStateDeclarations_s.end()) 165 { 166 GameStateInfo& info = gameStateDeclarations_s[getLowercase(stateName)]; 167 info.stateName = stateName; 168 info.className = className; 169 info.bIgnoreTickTime = bIgnoreTickTime; 170 info.bGraphicsMode = bGraphicsMode; 171 } 172 else 173 { 174 COUT(0) << "Error: Cannot declare two GameStates with the same name." << std::endl; 175 COUT(0) << " Ignoring second one ('" << stateName << "')." << std::endl; 176 } 177 178 // Create a factory to delay GameState creation 179 GameStateFactory::createFactory<T>(className); 180 181 // just a required dummy return value 182 return true; 183 } 139 184 } 140 //tolua_end 185 141 186 #endif /* _Game_H__ */ -
code/trunk/src/core/GameState.cc
r3196 r3280 45 45 Constructor only initialises variables and sets the name permanently. 46 46 */ 47 GameState::GameState(const std::string& name, bool countTickTime)48 : name_( name)49 , b CountTickTime_(countTickTime)47 GameState::GameState(const GameStateConstrParams& params) 48 : name_(params.name) 49 , bIgnoreTickTime_(params.bIgnoreTickTime) 50 50 , parent_(0) 51 51 { -
code/trunk/src/core/GameState.h
r3196 r3280 45 45 /** 46 46 @brief 47 Helper class to group construction parameters for better genericity. 48 */ 49 struct GameStateConstrParams 50 { 51 std::string name; 52 bool bIgnoreTickTime; 53 }; 54 55 /** 56 @brief 47 57 An implementation of a tree to manage game states. 48 58 This leads to a certain hierarchy that is created at runtime. … … 77 87 78 88 public: 79 GameState(const std::string& name, bool countTicktime = true);89 GameState(const GameStateConstrParams& params); 80 90 virtual ~GameState(); 81 91 … … 84 94 GameState* getParent() const { return this->parent_; } 85 95 86 bool getCountTickTime() const { return this->bCountTickTime_; }96 bool ignoreTickTime() const { return this->bIgnoreTickTime_; } 87 97 88 98 void addChild(GameState* state); … … 90 100 91 101 protected: 92 virtual void activate() = 0;93 virtual void deactivate() = 0;94 virtual void update(const Clock& time) = 0;102 virtual void activate() { } 103 virtual void deactivate() { } 104 virtual void update(const Clock& time) { } 95 105 96 106 private: … … 103 113 const std::string name_; 104 114 State activity_; 105 const bool b CountTickTime_;115 const bool bIgnoreTickTime_; 106 116 GameState* parent_; 107 117 std::map<std::string, GameState*> children_; -
code/trunk/src/core/IRC.cc
r3196 r3280 68 68 { COUT(1) << "Error while initializing Tcl (IRC): " << e.what(); } 69 69 70 this->nickname_ = "orx" + getConvertedValue<int, std::string>((unsigned int)rand());70 this->nickname_ = "orx" + multi_cast<std::string>(static_cast<unsigned int>(rand())); 71 71 TclThreadManager::execute(threadID, "set nickname " + this->nickname_); 72 72 TclThreadManager::execute(threadID, "source irc.tcl"); -
code/trunk/src/core/Identifier.cc
r3196 r3280 36 36 #include <ostream> 37 37 38 #include "util/String .h"38 #include "util/StringUtils.h" 39 39 #include "ConfigValueContainer.h" 40 40 #include "ConsoleCommand.h" -
code/trunk/src/core/Language.cc
r3198 r3280 194 194 @return The filename 195 195 */ 196 conststd::string Language::getFilename(const std::string& language)196 std::string Language::getFilename(const std::string& language) 197 197 { 198 198 return std::string("translation_" + language + ".lang"); -
code/trunk/src/core/Language.h
r2662 r3280 114 114 class _CoreExport Language 115 115 { 116 friend class Core ;116 friend class CoreConfiguration; 117 117 118 118 public: … … 130 130 void readTranslatedLanguageFile(); 131 131 void writeDefaultLanguageFile() const; 132 static conststd::string getFilename(const std::string& language);132 static std::string getFilename(const std::string& language); 133 133 LanguageEntry* createEntry(const LanguageEntryLabel& label, const std::string& entry); 134 134 -
code/trunk/src/core/LuaBind.cc
r3198 r3280 38 38 39 39 #include "util/Debug.h" 40 #include "util/String .h"40 #include "util/StringUtils.h" 41 41 #include "ToluaBindCore.h" 42 42 #include "Core.h" -
code/trunk/src/core/OrxonoxClass.cc
r3196 r3280 78 78 79 79 /** @brief Returns true if the objects class is of the given type or a derivative. */ 80 bool OrxonoxClass::isA(const SubclassIdentifier<classB>* identifier)80 template <class B> bool OrxonoxClass::isA(const SubclassIdentifier<B>* identifier) 81 81 { return this->getIdentifier()->isA(identifier->getIdentifier()); } 82 82 /** @brief Returns true if the objects class is exactly of the given type. */ 83 bool OrxonoxClass::isExactlyA(const SubclassIdentifier<classB>* identifier)83 template <class B> bool OrxonoxClass::isExactlyA(const SubclassIdentifier<B>* identifier) 84 84 { return this->getIdentifier()->isExactlyA(identifier->getIdentifier()); } 85 85 /** @brief Returns true if the objects class is a child of the given type. */ 86 bool OrxonoxClass::isChildOf(const SubclassIdentifier<classB>* identifier)86 template <class B> bool OrxonoxClass::isChildOf(const SubclassIdentifier<B>* identifier) 87 87 { return this->getIdentifier()->isChildOf(identifier->getIdentifier()); } 88 88 /** @brief Returns true if the objects class is a direct child of the given type. */ 89 bool OrxonoxClass::isDirectChildOf(const SubclassIdentifier<classB>* identifier)89 template <class B> bool OrxonoxClass::isDirectChildOf(const SubclassIdentifier<B>* identifier) 90 90 { return this->getIdentifier()->isDirectChildOf(identifier->getIdentifier()); } 91 91 /** @brief Returns true if the objects class is a parent of the given type. */ 92 bool OrxonoxClass::isParentOf(const SubclassIdentifier<classB>* identifier)92 template <class B> bool OrxonoxClass::isParentOf(const SubclassIdentifier<B>* identifier) 93 93 { return this->getIdentifier()->isParentOf(identifier->getIdentifier()); } 94 94 /** @brief Returns true if the objects class is a direct parent of the given type. */ 95 bool OrxonoxClass::isDirectParentOf(const SubclassIdentifier<classB>* identifier)95 template <class B> bool OrxonoxClass::isDirectParentOf(const SubclassIdentifier<B>* identifier) 96 96 { return this->getIdentifier()->isDirectParentOf(identifier->getIdentifier()); } 97 97 98 98 99 99 /** @brief Returns true if the objects class is of the given type or a derivative. */ 100 bool OrxonoxClass::isA(const SubclassIdentifier<classB> identifier)100 template <class B> bool OrxonoxClass::isA(const SubclassIdentifier<B> identifier) 101 101 { return this->getIdentifier()->isA(identifier.getIdentifier()); } 102 102 /** @brief Returns true if the objects class is exactly of the given type. */ 103 bool OrxonoxClass::isExactlyA(const SubclassIdentifier<classB> identifier)103 template <class B> bool OrxonoxClass::isExactlyA(const SubclassIdentifier<B> identifier) 104 104 { return this->getIdentifier()->isExactlyA(identifier.getIdentifier()); } 105 105 /** @brief Returns true if the objects class is a child of the given type. */ 106 bool OrxonoxClass::isChildOf(const SubclassIdentifier<classB> identifier)106 template <class B> bool OrxonoxClass::isChildOf(const SubclassIdentifier<B> identifier) 107 107 { return this->getIdentifier()->isChildOf(identifier.getIdentifier()); } 108 108 /** @brief Returns true if the objects class is a direct child of the given type. */ 109 bool OrxonoxClass::isDirectChildOf(const SubclassIdentifier<classB> identifier)109 template <class B> bool OrxonoxClass::isDirectChildOf(const SubclassIdentifier<B> identifier) 110 110 { return this->getIdentifier()->isDirectChildOf(identifier.getIdentifier()); } 111 111 /** @brief Returns true if the objects class is a parent of the given type. */ 112 bool OrxonoxClass::isParentOf(const SubclassIdentifier<classB> identifier)112 template <class B> bool OrxonoxClass::isParentOf(const SubclassIdentifier<B> identifier) 113 113 { return this->getIdentifier()->isParentOf(identifier.getIdentifier()); } 114 114 /** @brief Returns true if the objects class is a direct parent of the given type. */ 115 bool OrxonoxClass::isDirectParentOf(const SubclassIdentifier<classB> identifier)115 template <class B> bool OrxonoxClass::isDirectParentOf(const SubclassIdentifier<B> identifier) 116 116 { return this->getIdentifier()->isDirectParentOf(identifier.getIdentifier()); } 117 117 -
code/trunk/src/core/OrxonoxClass.h
r3196 r3280 80 80 bool isDirectParentOf(const Identifier* identifier); 81 81 82 bool isA(const SubclassIdentifier<classB>* identifier);83 bool isExactlyA(const SubclassIdentifier<classB>* identifier);84 bool isChildOf(const SubclassIdentifier<classB>* identifier);85 bool isDirectChildOf(const SubclassIdentifier<classB>* identifier);86 bool isParentOf(const SubclassIdentifier<classB>* identifier);87 bool isDirectParentOf(const SubclassIdentifier<classB>* identifier);82 template <class B> bool isA(const SubclassIdentifier<B>* identifier); 83 template <class B> bool isExactlyA(const SubclassIdentifier<B>* identifier); 84 template <class B> bool isChildOf(const SubclassIdentifier<B>* identifier); 85 template <class B> bool isDirectChildOf(const SubclassIdentifier<B>* identifier); 86 template <class B> bool isParentOf(const SubclassIdentifier<B>* identifier); 87 template <class B> bool isDirectParentOf(const SubclassIdentifier<B>* identifier); 88 88 89 bool isA(const SubclassIdentifier<classB> identifier);90 bool isExactlyA(const SubclassIdentifier<classB> identifier);91 bool isChildOf(const SubclassIdentifier<classB> identifier);92 bool isDirectChildOf(const SubclassIdentifier<classB> identifier);93 bool isParentOf(const SubclassIdentifier<classB> identifier);94 bool isDirectParentOf(const SubclassIdentifier<classB> identifier);89 template <class B> bool isA(const SubclassIdentifier<B> identifier); 90 template <class B> bool isExactlyA(const SubclassIdentifier<B> identifier); 91 template <class B> bool isChildOf(const SubclassIdentifier<B> identifier); 92 template <class B> bool isDirectChildOf(const SubclassIdentifier<B> identifier); 93 template <class B> bool isParentOf(const SubclassIdentifier<B> identifier); 94 template <class B> bool isDirectParentOf(const SubclassIdentifier<B> identifier); 95 95 96 96 bool isA(const OrxonoxClass* object); -
code/trunk/src/core/Shell.cc
r3196 r3280 78 78 OutputHandler::getOutStream().setOutputBuffer(&this->outputBuffer_); 79 79 80 // Get a config file for the command history 81 this->commandHistoryConfigFileType_ = ConfigFileManager::getInstance().getNewConfigFileType(); 82 ConfigFileManager::getInstance().setFilename(this->commandHistoryConfigFileType_, "commandHistory.ini"); 83 80 84 this->setConfigValues(); 81 85 … … 93 97 void Shell::setConfigValues() 94 98 { 95 SetConfigValue(maxHistoryLength_, 100).callback(this, &Shell::commandHistoryLengthChanged); 96 SetConfigValue(historyOffset_, 0).callback(this, &Shell::commandHistoryOffsetChanged); 97 SetConfigValueVector(commandHistory_, std::vector<std::string>()); 99 SetConfigValueGeneric(commandHistoryConfigFileType_, maxHistoryLength_, 100) 100 .callback(this, &Shell::commandHistoryLengthChanged); 101 SetConfigValueGeneric(commandHistoryConfigFileType_, historyOffset_, 0) 102 .callback(this, &Shell::commandHistoryOffsetChanged); 103 SetConfigValueVectorGeneric(commandHistoryConfigFileType_, commandHistory_, std::vector<std::string>()); 98 104 } 99 105 -
code/trunk/src/core/Shell.h
r3196 r3280 37 37 #include <vector> 38 38 39 #include "util/OutputBuffer.h" 40 #include "input/InputBuffer.h" 39 41 #include "OrxonoxClass.h" 40 #include "input/InputBuffer.h" 41 #include "util/OutputBuffer.h" 42 #include "ConfigFileManager.h" 42 43 43 44 namespace orxonox … … 145 146 bool bAddOutputLevel_; 146 147 148 ConfigFileType commandHistoryConfigFileType_; 149 147 150 static Shell* singletonRef_s; 148 151 }; -
code/trunk/src/core/TclBind.cc
r3196 r3280 34 34 35 35 #include "util/Debug.h" 36 #include "util/String .h"36 #include "util/StringUtils.h" 37 37 #include "CommandExecutor.h" 38 38 #include "ConsoleCommand.h" -
code/trunk/src/core/TclThreadManager.cc
r3196 r3280 94 94 boost::mutex::scoped_lock bundles_lock(TclThreadManager::getInstance().bundlesMutex_); 95 95 TclThreadManager::getInstance().threadCounter_++; 96 std::string name = getConvertedValue<unsigned int,std::string>(TclThreadManager::getInstance().threadCounter_);96 std::string name = multi_cast<std::string>(TclThreadManager::getInstance().threadCounter_); 97 97 98 98 TclInterpreterBundle* bundle = new TclInterpreterBundle; … … 192 192 { 193 193 boost::mutex::scoped_lock queue_lock(TclThreadManager::getInstance().orxonoxInterpreterBundle_.queueMutex_); 194 output += getConvertedValue<unsigned int,std::string>(TclThreadManager::getInstance().orxonoxInterpreterBundle_.queue_.size());194 output += multi_cast<std::string>(TclThreadManager::getInstance().orxonoxInterpreterBundle_.queue_.size()); 195 195 } 196 196 output += "\t\t"; … … 201 201 for (std::map<unsigned int, TclInterpreterBundle*>::const_iterator it = TclThreadManager::getInstance().interpreterBundles_.begin(); it != TclThreadManager::getInstance().interpreterBundles_.end(); ++it) 202 202 { 203 std::string output = getConvertedValue<unsigned int,std::string>((*it).first);203 std::string output = multi_cast<std::string>((*it).first); 204 204 output += "\t\t"; 205 205 { 206 206 boost::mutex::scoped_lock queue_lock((*it).second->queueMutex_); 207 output += getConvertedValue<unsigned int,std::string>((*it).second->queue_.size());207 output += multi_cast<std::string>((*it).second->queue_.size()); 208 208 } 209 209 output += "\t\t"; … … 342 342 else 343 343 { 344 this->error("Error: No Tcl-interpreter with ID " + getConvertedValue<unsigned int,std::string>(threadID) + " existing.");344 this->error("Error: No Tcl-interpreter with ID " + multi_cast<std::string>(threadID) + " existing."); 345 345 return 0; 346 346 } … … 355 355 output += " "; 356 356 357 output += getConvertedValue<unsigned int,std::string>(*it);357 output += multi_cast<std::string>(*it); 358 358 } 359 359 return output; … … 444 444 if (bundle->queue_.size() >= TCLTHREADMANAGER_MAX_QUEUE_LENGTH) 445 445 { 446 this->error("Error: Queue of Tcl-interpreter " + getConvertedValue<unsigned int,std::string>(threadID) + " is full, couldn't add command.");446 this->error("Error: Queue of Tcl-interpreter " + multi_cast<std::string>(threadID) + " is full, couldn't add command."); 447 447 return; 448 448 } … … 492 492 if (std::find(target->queriers_.begin(), target->queriers_.end(), target->id_) != target->queriers_.end()) 493 493 { 494 this->error("Error: Circular query (" + this->dumpList(target->queriers_) + " -> " + getConvertedValue<unsigned int, std::string>(target->id_) + "), couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target->id_) + " from other interpreter with ID " + getConvertedValue<unsigned int,std::string>(querier->id_) + ".");494 this->error("Error: Circular query (" + this->dumpList(target->queriers_) + " -> " + multi_cast<std::string>(target->id_) + "), couldn't query Tcl-interpreter with ID " + multi_cast<std::string>(target->id_) + " from other interpreter with ID " + multi_cast<std::string>(querier->id_) + "."); 495 495 return false; 496 496 } … … 585 585 else 586 586 { 587 this->error("Error: Couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int,std::string>(threadID) + ", interpreter is busy right now.");587 this->error("Error: Couldn't query Tcl-interpreter with ID " + multi_cast<std::string>(threadID) + ", interpreter is busy right now."); 588 588 } 589 589 } … … 665 665 catch (Tcl::tcl_error const &e) 666 666 { 667 TclThreadManager::getInstance().error("Tcl (ID " + getConvertedValue<unsigned int,std::string>(interpreterBundle->id_) + ") error: " + e.what());667 TclThreadManager::getInstance().error("Tcl (ID " + multi_cast<std::string>(interpreterBundle->id_) + ") error: " + e.what()); 668 668 } 669 669 catch (std::exception const &e) 670 670 { 671 TclThreadManager::getInstance().error("Error while executing Tcl (ID " + getConvertedValue<unsigned int,std::string>(interpreterBundle->id_) + "): " + e.what());671 TclThreadManager::getInstance().error("Error while executing Tcl (ID " + multi_cast<std::string>(interpreterBundle->id_) + "): " + e.what()); 672 672 } 673 673 -
code/trunk/src/core/input/Button.cc
r2662 r3280 37 37 #include "util/Convert.h" 38 38 #include "util/SubString.h" 39 #include "util/String .h"39 #include "util/StringUtils.h" 40 40 #include "util/Debug.h" 41 41 #include "core/ConsoleCommand.h" … … 127 127 '\\', false, '"', false, '(', ')', false, '\0'); 128 128 129 KeybindMode:: Enummode = KeybindMode::None;129 KeybindMode::Value mode = KeybindMode::None; 130 130 float paramModifier = 1.0f; 131 131 std::string commandStr = ""; -
code/trunk/src/core/input/Button.h
r2662 r3280 54 54 void parse(); 55 55 void readConfigValue(ConfigFileType configFile); 56 bool execute(KeybindMode:: Enummode, float abs = 1.0f, float rel = 1.0f);56 bool execute(KeybindMode::Value mode, float abs = 1.0f, float rel = 1.0f); 57 57 58 58 //! Container to allow for better configValue support … … 79 79 }; 80 80 81 inline bool Button::execute(KeybindMode:: Enummode, float abs, float rel)81 inline bool Button::execute(KeybindMode::Value mode, float abs, float rel) 82 82 { 83 83 // execute all the parsed commands in the string -
code/trunk/src/core/input/InputManager.cc
r3196 r3280 43 43 #include "util/Convert.h" 44 44 #include "util/Exception.h" 45 #include "util/ Debug.h"45 #include "util/ScopeGuard.h" 46 46 #include "core/Clock.h" 47 47 #include "core/CoreIncludes.h" … … 70 70 SetConsoleCommand(InputManager, ungrabMouse, true); 71 71 #endif 72 SetCommandLineSwitch(keyboard_no_grab) ;72 SetCommandLineSwitch(keyboard_no_grab).information("Whether not to exclusively grab the keyboard"); 73 73 74 74 EmptyHandler InputManager::EMPTY_HANDLER; … … 177 177 windowHndStr << (unsigned int)windowHnd_; 178 178 paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); 179 #if defined(ORXONOX_PLATFORM_WINDOWS) 179 180 //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE"))); 180 181 //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND"))); 181 #if defined ORXONOX_PLATFORM_LINUX 182 //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE"))); 183 //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND"))); 184 #elif defined(ORXONOX_PLATFORM_LINUX) 182 185 paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true"))); 183 186 paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true")); … … 191 194 #endif 192 195 193 inputSystem_ = OIS::InputManager::createInputSystem(paramList); 194 CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl; 195 196 _initialiseKeyboard(); 196 try 197 { 198 inputSystem_ = OIS::InputManager::createInputSystem(paramList); 199 // Exception-safety 200 Loki::ScopeGuard guard = Loki::MakeGuard(OIS::InputManager::destroyInputSystem, inputSystem_); 201 CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl; 202 203 _initialiseKeyboard(); 204 205 // Nothing below should throw anymore, dismiss the guard 206 guard.Dismiss(); 207 } 208 catch (OIS::Exception& ex) 209 { 210 ThrowException(InitialisationFailed, "Could not initialise the input system: " << ex.what()); 211 } 197 212 198 213 _initialiseMouse(); … … 200 215 if (joyStickSupport) 201 216 _initialiseJoySticks(); 202 // Do this anyway to also inform everythingwhen a joystick was detached.217 // Do this anyway to also inform when a joystick was detached. 203 218 _configureJoySticks(); 204 219 … … 273 288 else 274 289 { 275 ThrowException(InitialisationFailed, " No keyboard found!");290 ThrowException(InitialisationFailed, "InputManager: No keyboard found, cannot proceed!"); 276 291 } 277 292 } … … 301 316 else 302 317 { 303 CCOUT(ORX_WARNING) << "Warning: No mouse found! " << std::endl;318 CCOUT(ORX_WARNING) << "Warning: No mouse found! Proceeding without mouse support." << std::endl; 304 319 } 305 320 } … … 307 322 { 308 323 CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS mouse\n" 309 << "OIS error message: \"" << ex.eText << "\" " << std::endl;324 << "OIS error message: \"" << ex.eText << "\"\n Proceeding without mouse support." << std::endl; 310 325 mouse_ = 0; 311 326 } … … 345 360 } 346 361 } 347 else348 {349 //CCOUT(ORX_WARNING) << "Warning: Joy stick support requested, but no joy stick was found" << std::endl;350 }351 362 } 352 363 … … 528 539 if (internalState_ != Uninitialised) 529 540 { 541 CCOUT(3) << "Destroying ..." << std::endl; 542 543 // kick all active states 'nicely' 544 for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); 545 rit != activeStates_.rend(); ++rit) 546 { 547 (*rit).second->onLeave(); 548 } 549 550 // Destroy calibrator helper handler and state 551 delete keyDetector_; 552 requestDestroyState("calibrator"); 553 // Destroy KeyDetector and state 554 delete calibratorCallbackBuffer_; 555 requestDestroyState("detector"); 556 // destroy the empty InputState 557 _destroyState(this->stateEmpty_); 558 559 // destroy all user InputStates 560 while (inputStatesByName_.size() > 0) 561 _destroyState((*inputStatesByName_.rbegin()).second); 562 563 // destroy the devices 564 _destroyKeyboard(); 565 _destroyMouse(); 566 _destroyJoySticks(); 567 530 568 try 531 569 { 532 CCOUT(3) << "Destroying ..." << std::endl;533 534 // kick all active states 'nicely'535 for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();536 rit != activeStates_.rend(); ++rit)537 {538 (*rit).second->onLeave();539 }540 541 // Destroy calibrator helper handler and state542 delete keyDetector_;543 requestDestroyState("calibrator");544 // Destroy KeyDetector and state545 delete calibratorCallbackBuffer_;546 requestDestroyState("detector");547 // destroy the empty InputState548 _destroyState(this->stateEmpty_);549 550 // destroy all user InputStates551 while (inputStatesByName_.size() > 0)552 _destroyState((*inputStatesByName_.rbegin()).second);553 554 // destroy the devices555 _destroyKeyboard();556 _destroyMouse();557 _destroyJoySticks();558 559 570 OIS::InputManager::destroyInputSystem(inputSystem_); 560 561 CCOUT(3) << "Destroying done." << std::endl; 562 } 563 catch (OIS::Exception& ex) 564 { 565 CCOUT(1) << "An exception has occured while destroying:\n" << ex.what() 566 << "This could lead to a possible memory/resource leak!" << std::endl; 571 } 572 catch (...) 573 { 574 CCOUT(1) << "OIS::InputManager destruction failed! Potential resource leak!" << std::endl; 567 575 } 568 576 } … … 578 586 { 579 587 assert(inputSystem_); 580 if (keyboard_) 581 inputSystem_->destroyInputObject(keyboard_); 582 keyboard_ = 0; 583 CCOUT(4) << "Keyboard destroyed." << std::endl; 588 try 589 { 590 if (keyboard_) 591 inputSystem_->destroyInputObject(keyboard_); 592 keyboard_ = 0; 593 CCOUT(4) << "Keyboard destroyed." << std::endl; 594 } 595 catch (...) 596 { 597 CCOUT(1) << "Keyboard destruction failed! Potential resource leak!" << std::endl; 598 } 584 599 } 585 600 … … 591 606 { 592 607 assert(inputSystem_); 593 if (mouse_) 594 inputSystem_->destroyInputObject(mouse_); 595 mouse_ = 0; 596 CCOUT(4) << "Mouse destroyed." << std::endl; 608 try 609 { 610 if (mouse_) 611 inputSystem_->destroyInputObject(mouse_); 612 mouse_ = 0; 613 CCOUT(4) << "Mouse destroyed." << std::endl; 614 } 615 catch (...) 616 { 617 CCOUT(1) << "Mouse destruction failed! Potential resource leak!" << std::endl; 618 } 597 619 } 598 620 … … 607 629 assert(inputSystem_); 608 630 for (unsigned int i = 0; i < joySticksSize_; i++) 609 if (joySticks_[i] != 0) 610 inputSystem_->destroyInputObject(joySticks_[i]); 631 { 632 try 633 { 634 if (joySticks_[i] != 0) 635 inputSystem_->destroyInputObject(joySticks_[i]); 636 } 637 catch (...) 638 { 639 CCOUT(1) << "Joy stick destruction failed! Potential resource leak!" << std::endl; 640 } 641 } 611 642 612 643 joySticks_.clear(); -
code/trunk/src/core/input/KeyBinder.cc
r3196 r3280 96 96 } 97 97 98 // Get a new ConfigFileType from the ConfigFileManager99 this->configFile_ = ConfigFile Manager::getInstance().getNewConfigFileType();98 // We might not even load any bindings at all (KeyDetector for instance) 99 this->configFile_ = ConfigFileType::NoType; 100 100 101 101 // initialise joy sticks separatly to allow for reloading … … 187 187 for (unsigned int iDev = 0; iDev < numberOfJoySticks_; iDev++) 188 188 { 189 std::string deviceNumber = convertToString(iDev);189 std::string deviceNumber = multi_cast<std::string>(iDev); 190 190 // joy stick buttons 191 191 for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++) … … 249 249 if (filename.empty()) 250 250 return; 251 252 if (this->configFile_ == ConfigFileType::NoType) 253 { 254 // Get a new ConfigFileType from the ConfigFileManager 255 this->configFile_ = ConfigFileManager::getInstance().getNewConfigFileType(); 256 } 251 257 252 258 ConfigFileManager::getInstance().setFilename(this->configFile_, filename);
Note: See TracChangeset
for help on using the changeset viewer.