Changeset 1052 for code/trunk/src/orxonox/core/ConfigValueContainer.cc
- Timestamp:
- Apr 14, 2008, 3:42:49 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk/src/orxonox/core/ConfigValueContainer.cc
r871 r1052 34 34 35 35 #include "ConfigValueContainer.h" 36 #include "util/Tokenizer.h" 36 #include "Language.h" 37 #include "Identifier.h" 38 #include "util/SubString.h" 37 39 #include "util/Convert.h" 38 #include "Language.h" 39 40 #define CONFIGFILEPATH "orxonox.ini" 40 41 #define MAX_VECTOR_INDEX 255 // to avoid up to 4*10^9 vector entries in the config file after accidentally using a wrong argument 42 41 43 42 44 namespace orxonox … … 44 46 /** 45 47 @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable. 46 @param value This is only needed to determine the right type.47 @param classname The nameof the class the variable belongs to48 @param type The type of the corresponding config-file 49 @param identifier The identifier of the class the variable belongs to 48 50 @param varname The name of the variable 49 51 @param defvalue The default-value 50 52 */ 51 ConfigValueContainer::ConfigValueContainer(const std::string& classname, const std::string& varname, MultiTypeMath defvalue) 52 { 53 ConfigValueContainer::ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& varname, const MultiTypeMath& defvalue) 54 { 55 this->type_ = type; 56 this->identifier_ = identifier; 57 this->sectionname_ = identifier->getName(); 58 this->varname_ = varname; 59 60 this->value_ = defvalue; 53 61 this->bAddedDescription_ = false; 54 this->classname_ = classname; 62 this->bIsVector_ = false; 63 64 this->defvalueString_ = defvalue.toString(); 65 this->update(); 66 } 67 68 /** 69 @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable. 70 @param type The type of the corresponding config-file 71 @param identifier The identifier of the class the variable belongs to 72 @param varname The name of the variable 73 @param defvalue The default-value 74 */ 75 ConfigValueContainer::ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& varname, const std::vector<MultiTypeMath>& defvalue) 76 { 77 this->type_ = type; 78 this->identifier_ = identifier; 79 this->sectionname_ = identifier->getName(); 55 80 this->varname_ = varname; 56 81 57 this->valueToString(&this->defvalueString_, defvalue); // Try to convert the default-value to a string 58 this->searchConfigFileLine(); // Search the entry in the config-file 59 60 std::string valueString = this->parseValueString(!(defvalue.isA(MT_string) || defvalue.isA(MT_constchar))); // Parses the value string from the config-file-entry 61 if (!this->parseString(valueString, defvalue)) // Try to convert the string to a value 62 this->resetConfigFileEntry(); // The conversion failed 63 } 64 65 /** 66 @brief Converts a value to a string. 67 @param output The string to write to 68 @param input The value to convert 69 @return True if the converson was successful 70 */ 71 bool ConfigValueContainer::valueToString(std::string* output, MultiTypeMath& input) 72 { 73 if (input.getType() == MT_int) 74 return ConvertValue(output, input.getInt(), std::string("0")); 75 else if (input.getType() == MT_uint) 76 return ConvertValue(output, input.getUnsignedInt(), std::string("0")); 77 else if (input.getType() == MT_char) 78 return ConvertValue(output, (int)input.getChar(), std::string("0")); 79 else if (input.getType() == MT_uchar) 80 return ConvertValue(output, (unsigned int)input.getUnsignedChar(), std::string("0")); 81 else if (input.getType() == MT_short) 82 return ConvertValue(output, input.getShort(), std::string("0")); 83 else if (input.getType() == MT_ushort) 84 return ConvertValue(output, input.getUnsignedShort(), std::string("0")); 85 else if (input.getType() == MT_long) 86 return ConvertValue(output, input.getLong(), std::string("0")); 87 else if (input.getType() == MT_ulong) 88 return ConvertValue(output, input.getUnsignedLong(), std::string("0")); 89 else if (input.getType() == MT_float) 90 return ConvertValue(output, input.getFloat(), std::string("0.000000")); 91 else if (input.getType() == MT_double) 92 return ConvertValue(output, input.getDouble(), std::string("0.000000")); 93 else if (input.getType() == MT_longdouble) 94 return ConvertValue(output, input.getChar(), std::string("0.000000")); 95 else if (input.getType() == MT_bool) 96 { 97 if (input.getBool()) 98 (*output) = "true"; 82 this->valueVector_ = defvalue; 83 this->bAddedDescription_ = false; 84 this->bIsVector_ = true; 85 86 if (defvalue.size() > 0) 87 this->value_ = defvalue[0]; 88 89 for (unsigned int i = 0; i < defvalue.size(); i++) 90 ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, i, defvalue[i].toString(), this->value_.isA(MT_string)); 91 92 for (unsigned int i = 0; i < defvalue.size(); i++) 93 this->defvalueStringVector_.push_back(defvalue[i].toString()); 94 95 this->update(); 96 } 97 98 /** 99 @brief Adds a new entry to the end of the vector. 100 @param input The new entry 101 @return True if the new entry was successfully added 102 */ 103 bool ConfigValueContainer::add(const std::string& input) 104 { 105 if (this->bIsVector_) 106 return this->set(this->valueVector_.size(), input); 107 108 COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl; 109 return false; 110 } 111 112 /** 113 @brief Removes an existing entry from the vector. 114 @param index The index of the entry 115 @return True if the entry was removed 116 */ 117 bool ConfigValueContainer::remove(unsigned int index) 118 { 119 if (this->bIsVector_) 120 { 121 if (index < this->valueVector_.size()) 122 { 123 this->valueVector_.erase(this->valueVector_.begin() + index); 124 for (unsigned int i = index; i < this->valueVector_.size(); i++) 125 ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isA(MT_string)); 126 ConfigFileManager::getSingleton()->deleteVectorEntries(this->type_, this->sectionname_, this->varname_, this->valueVector_.size()); 127 128 return true; 129 } 130 COUT(1) << "Error: Invalid vector-index." << std::endl; 131 } 132 133 COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl; 134 return false; 135 } 136 137 /** 138 @brief Assigns a new value to the config-value of all objects and writes the change into the config-file. 139 @param input The new value 140 @return True if the new value was successfully assigned 141 */ 142 bool ConfigValueContainer::set(const std::string& input) 143 { 144 if (this->bIsVector_) 145 { 146 SubString token(input, " ", "", true, '"', false, '(', ')', false, '\0'); 147 int index = -1; 148 bool success = false; 149 150 if (token.size() > 0) 151 success = ConvertValue(&index, token[0]); 152 153 if (!success || index < 0 || index > MAX_VECTOR_INDEX) 154 { 155 if (!success) 156 { 157 COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is a vector." << std::endl; 158 } 159 else 160 { 161 COUT(1) << "Error: Invalid vector-index." << std::endl; 162 } 163 return false; 164 } 165 166 if (token.size() >= 2) 167 return this->set(index, token.subSet(1).join()); 99 168 else 100 (*output) = "false"; 101 102 return true; 103 } 104 else if (input.getType() == MT_constchar) 105 { 106 (*output) = "\"" + input.getString() + "\""; 107 return true; 108 } 109 else if (input.getType() == MT_string) 110 { 111 (*output) = "\"" + input.getString() + "\""; 112 return true; 113 } 114 else if (input.getType() == MT_vector2) 115 { 116 std::ostringstream ostream; 117 if (ostream << "(" << input.getVector2().x << "," << input.getVector2().y << ")") 118 { 119 (*output) = ostream.str(); 120 return true; 121 } 122 else 123 { 124 (*output) = "(0,0)"; 125 return false; 126 } 127 } 128 else if (input.getType() == MT_vector3) 129 { 130 std::ostringstream ostream; 131 if (ostream << "(" << input.getVector3().x << "," << input.getVector3().y << "," << input.getVector3().z << ")") 132 { 133 (*output) = ostream.str(); 134 return true; 135 } 136 else 137 { 138 (*output) = "(0,0,0)"; 139 return false; 140 } 141 } 142 else if (input.getType() == MT_colourvalue) 143 { 144 std::ostringstream ostream; 145 if (ostream << "(" << input.getColourValue().r << "," << input.getColourValue().g << "," << input.getColourValue().b << "," << input.getColourValue().a << ")") 146 { 147 (*output) = ostream.str(); 148 return true; 149 } 150 else 151 { 152 (*output) = "(0,0,0,0)"; 153 return false; 154 } 155 } 156 else if (input.getType() == MT_quaternion) 157 { 158 std::ostringstream ostream; 159 if (ostream << "(" << input.getQuaternion().w << "," << input.getQuaternion().x << "," << input.getQuaternion().y << "," << input.getQuaternion().z << ")") 160 { 161 (*output) = ostream.str(); 162 return true; 163 } 164 else 165 { 166 (*output) = "(0,0,0,0)"; 167 return false; 168 } 169 } 170 else if (input.getType() == MT_radian) 171 return ConvertValue(output, input.getRadian(), std::string("0.000000")); 172 else if (input.getType() == MT_degree) 173 return ConvertValue(output, input.getDegree(), std::string("0.000000")); 174 175 return false; 169 return this->set(index, ""); 170 } 171 172 bool success = this->tset(input); 173 ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, input, this->value_.isA(MT_string)); 174 return success; 175 } 176 177 /** 178 @brief Assigns a new value to the config-value of all objects and writes the change into the config-file. 179 @param index The index in the vector 180 @param input The new value 181 @return True if the new value was successfully assigned 182 */ 183 bool ConfigValueContainer::set(unsigned int index, const std::string& input) 184 { 185 if (this->bIsVector_) 186 { 187 bool success = this->tset(index, input); 188 ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, index, input, this->value_.isA(MT_string)); 189 return success; 190 } 191 192 COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl; 193 return false; 194 } 195 196 /** 197 @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary). 198 @param input The new value 199 @return True if the new value was successfully assigned 200 */ 201 bool ConfigValueContainer::tset(const std::string& input) 202 { 203 bool success = this->parse(input); 204 if (this->identifier_) 205 this->identifier_->updateConfigValues(); 206 return success; 207 } 208 209 /** 210 @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary). 211 @param index The index in the vector 212 @param input The new value 213 @return True if the new value was successfully assigned 214 */ 215 bool ConfigValueContainer::tset(unsigned int index, const std::string& input) 216 { 217 if (this->bIsVector_) 218 { 219 bool success = this->parse(index, input); 220 if (this->identifier_) 221 this->identifier_->updateConfigValues(); 222 return success; 223 } 224 225 COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl; 226 return false; 227 } 228 229 /** 230 @brief Sets the value of the variable back to the default value and resets the config-file entry. 231 */ 232 bool ConfigValueContainer::reset() 233 { 234 if (!this->bIsVector_) 235 return this->set(this->defvalueString_); 236 else 237 { 238 bool success = true; 239 for (unsigned int i = 0; i < this->defvalueStringVector_.size(); i++) 240 if (!this->set(i, this->defvalueStringVector_[i])) 241 success = false; 242 ConfigFileManager::getSingleton()->deleteVectorEntries(this->type_, this->sectionname_, this->varname_, this->defvalueStringVector_.size()); 243 return success; 244 } 245 } 246 247 /** 248 @brief Retrieves the configured value from the currently loaded config-file. 249 */ 250 void ConfigValueContainer::update() 251 { 252 if (!this->bIsVector_) 253 this->value_.fromString(ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, this->defvalueString_, this->value_.isA(MT_string))); 254 else 255 { 256 this->valueVector_.clear(); 257 for (unsigned int i = 0; i < ConfigFileManager::getSingleton()->getVectorSize(this->type_, this->sectionname_, this->varname_); i++) 258 { 259 this->value_.fromString(ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, i, this->defvalueStringVector_[i], this->value_.isA(MT_string))); 260 this->valueVector_.push_back(this->value_); 261 } 262 } 176 263 } 177 264 … … 181 268 @return True if the string was successfully parsed 182 269 */ 183 bool ConfigValueContainer::parseString(const std::string& input, MultiTypeMath& defvalue) 184 { 185 if (defvalue.getType() == MT_int) 186 return this->parseString(input, defvalue.getInt()); 187 else if (defvalue.getType() == MT_uint) 188 return this->parseString(input, defvalue.getUnsignedInt()); 189 else if (defvalue.getType() == MT_char) 190 return this->parseString(input, defvalue.getChar()); 191 else if (defvalue.getType() == MT_uchar) 192 return this->parseString(input, defvalue.getUnsignedChar()); 193 else if (defvalue.getType() == MT_short) 194 return this->parseString(input, defvalue.getShort()); 195 else if (defvalue.getType() == MT_ushort) 196 return this->parseString(input, defvalue.getUnsignedShort()); 197 else if (defvalue.getType() == MT_long) 198 return this->parseString(input, defvalue.getLong()); 199 else if (defvalue.getType() == MT_ulong) 200 return this->parseString(input, defvalue.getUnsignedLong()); 201 else if (defvalue.getType() == MT_float) 202 return this->parseString(input, defvalue.getFloat()); 203 else if (defvalue.getType() == MT_double) 204 return this->parseString(input, defvalue.getDouble()); 205 else if (defvalue.getType() == MT_longdouble) 206 return this->parseString(input, defvalue.getLongDouble()); 207 else if (defvalue.getType() == MT_bool) 208 return this->parseString(input, defvalue.getBool()); 209 else if (defvalue.getType() == MT_constchar) 210 return this->parseString(input, defvalue.getString()); 211 else if (defvalue.getType() == MT_string) 212 return this->parseString(input, defvalue.getString()); 213 else if (defvalue.getType() == MT_vector2) 214 return this->parseString(input, defvalue.getVector2()); 215 else if (defvalue.getType() == MT_vector3) 216 return this->parseString(input, defvalue.getVector3()); 217 else if (defvalue.getType() == MT_colourvalue) 218 return this->parseString(input, defvalue.getColourValue()); 219 else if (defvalue.getType() == MT_quaternion) 220 return this->parseString(input, defvalue.getQuaternion()); 221 else if (defvalue.getType() == MT_radian) 222 return this->parseString(input, defvalue.getRadian()); 223 else if (defvalue.getType() == MT_degree) 224 return this->parseString(input, defvalue.getDegree()); 225 226 return false; 227 } 228 229 /** 230 @brief Parses a given std::string into a value of the type int and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 231 @param input The string to convert 232 @param defvalue The default-value 233 @return True if the string was successfully parsed 234 */ 235 bool ConfigValueContainer::parseString(const std::string& input, int defvalue) 236 { 237 int temp; 238 bool success = ConvertValue(&temp, input, defvalue); 239 this->value_.setValue(temp); 240 return success; 241 } 242 243 /** 244 @brief Parses a given std::string into a value of the type unsigned int and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 245 @param input The string to convert 246 @param defvalue The default-value 247 @return True if the string was successfully parsed 248 */ 249 bool ConfigValueContainer::parseString(const std::string& input, unsigned int defvalue) 250 { 251 unsigned int temp; 252 bool success = ConvertValue(&temp, input, defvalue); 253 this->value_.setValue(temp); 254 return success; 255 } 256 257 /** 258 @brief Parses a given std::string into a value of the type char and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 259 @param input The string to convert 260 @param defvalue The default-value 261 @return True if the string was successfully parsed 262 */ 263 bool ConfigValueContainer::parseString(const std::string& input, char defvalue) 264 { 265 // I used value_int_ instead of value_char_ to avoid number <-> char confusion in the config-file 266 int temp; 267 bool success = ConvertValue(&temp, input, (int)defvalue); 268 this->value_.setValue((char)temp); 269 return success; 270 } 271 272 /** 273 @brief Parses a given std::string into a value of the type unsigned char and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 274 @param input The string to convert 275 @param defvalue The default-value 276 @return True if the string was successfully parsed 277 */ 278 bool ConfigValueContainer::parseString(const std::string& input, unsigned char defvalue) 279 { 280 // I used value_uint_ instead of value_uchar_ to avoid number <-> char confusion in the config-file 281 unsigned int temp; 282 bool success = ConvertValue(&temp, input, (unsigned int)defvalue); 283 this->value_.setValue((unsigned char)temp); 284 return success; 285 } 286 287 /** 288 @brief Parses a given std::string into a value of the type short and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 289 @param input The string to convert 290 @param defvalue The default-value 291 @return True if the string was successfully parsed 292 */ 293 bool ConfigValueContainer::parseString(const std::string& input, short defvalue) 294 { 295 short temp; 296 bool success = ConvertValue(&temp, input, defvalue); 297 this->value_.setValue(temp); 298 return success; 299 } 300 301 /** 302 @brief Parses a given std::string into a value of the type unsigned short and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 303 @param input The string to convert 304 @param defvalue The default-value 305 @return True if the string was successfully parsed 306 */ 307 bool ConfigValueContainer::parseString(const std::string& input, unsigned short defvalue) 308 { 309 unsigned short temp; 310 bool success = ConvertValue(&temp, input, defvalue); 311 this->value_.setValue(temp); 312 return success; 313 } 314 315 /** 316 @brief Parses a given std::string into a value of the type long and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 317 @param input The string to convert 318 @param defvalue The default-value 319 @return True if the string was successfully parsed 320 */ 321 bool ConfigValueContainer::parseString(const std::string& input, long defvalue) 322 { 323 long temp; 324 bool success = ConvertValue(&temp, input, defvalue); 325 this->value_.setValue(temp); 326 return success; 327 } 328 329 /** 330 @brief Parses a given std::string into a value of the type unsigned long and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 331 @param input The string to convert 332 @param defvalue The default-value 333 @return True if the string was successfully parsed 334 */ 335 bool ConfigValueContainer::parseString(const std::string& input, unsigned long defvalue) 336 { 337 unsigned long temp; 338 bool success = ConvertValue(&temp, input, defvalue); 339 this->value_.setValue(temp); 340 return success; 341 } 342 343 /** 344 @brief Parses a given std::string into a value of the type float and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 345 @param input The string to convert 346 @param defvalue The default-value 347 @return True if the string was successfully parsed 348 */ 349 bool ConfigValueContainer::parseString(const std::string& input, float defvalue) 350 { 351 float temp; 352 bool success = ConvertValue(&temp, input, defvalue); 353 this->value_.setValue(temp); 354 return success; 355 } 356 357 /** 358 @brief Parses a given std::string into a value of the type double and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 359 @param input The string to convert 360 @param defvalue The default-value 361 @return True if the string was successfully parsed 362 */ 363 bool ConfigValueContainer::parseString(const std::string& input, double defvalue) 364 { 365 double temp; 366 bool success = ConvertValue(&temp, input, defvalue); 367 this->value_.setValue(temp); 368 return success; 369 } 370 371 /** 372 @brief Parses a given std::string into a value of the type long double and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 373 @param input The string to convert 374 @param defvalue The default-value 375 @return True if the string was successfully parsed 376 */ 377 bool ConfigValueContainer::parseString(const std::string& input, long double defvalue) 378 { 379 long double temp; 380 bool success = ConvertValue(&temp, input, defvalue); 381 this->value_.setValue(temp); 382 return success; 383 } 384 385 /** 386 @brief Parses a given std::string into a value of the type bool and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 387 @param input The string to convert 388 @param defvalue The default-value 389 @return True if the string was successfully parsed 390 */ 391 bool ConfigValueContainer::parseString(const std::string& input, bool defvalue) 392 { 393 // Try to parse the value-string - is it a word? 394 if (input.find("true") < input.size() 395 || input.find("True") < input.size() 396 || input.find("yes") < input.size() 397 || input.find("Yes") < input.size()) 398 this->value_.setValue(true); 399 else if (input.find("false") < input.size() 400 || input.find("False") < input.size() 401 || input.find("no") < input.size() 402 || input.find("No") < input.size()) 403 this->value_.setValue(false); 404 else 405 { 406 // Its not a known word - is it a number? 407 bool temp; 408 bool success = ConvertValue(&temp, input, defvalue); 409 this->value_.setValue(temp); 410 return success; 411 } 412 413 return true; 414 } 415 416 /** 417 @brief Parses a given std::string into a value of the type std::string and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 418 @param input The string to convert 419 @param defvalue The default-value 420 @return True if the string was successfully parsed 421 */ 422 bool ConfigValueContainer::parseString(const std::string& input, const std::string& defvalue) 423 { 424 // Strip the quotes 425 unsigned int pos1 = input.find("\"") + 1; 426 unsigned int pos2 = input.find("\"", pos1); 427 428 // Check if the entry was correctly quoted 429 if (pos1 < input.length() && pos2 < input.length() && !(input.find("\"", pos2 + 1) < input.length())) 430 { 431 // It was - get the string between the quotes 432 this->value_.setValue(input.substr(pos1, pos2 - pos1)); 433 return true; 434 } 435 436 // It wasn't - use the default-value and restore the entry in the config-file. 437 this->value_.setValue(defvalue); 438 return false; 439 } 440 441 /** 442 @brief Parses a given std::string into a value of the type const char* and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 443 @param input The string to convert 444 @param defvalue The default-value 445 @return True if the string was successfully parsed 446 */ 447 bool ConfigValueContainer::parseString(const std::string& input, const char* defvalue) 448 { 449 // Strip the quotes 450 unsigned int pos1 = input.find("\"") + 1; 451 unsigned int pos2 = input.find("\"", pos1); 452 453 // Check if the entry was correctly quoted 454 if (pos1 < input.length() && pos2 < input.length() && !(input.find("\"", pos2 + 1) < input.length())) 455 { 456 // It was - get the string between the quotes 457 this->value_.setValue(input.substr(pos1, pos2 - pos1)); 458 return true; 459 } 460 461 // It wasn't - use the default-value and restore the entry in the config-file. 462 this->value_.setValue(defvalue); 463 return false; 464 } 465 466 /** 467 @brief Parses a given std::string into a value of the type _Vector2 and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 468 @param input The string to convert 469 @param defvalue The default-value 470 @return True if the string was successfully parsed 471 */ 472 bool ConfigValueContainer::parseString(const std::string& input, const Vector2& defvalue) 473 { 474 // Strip the value-string 475 unsigned int pos1 = input.find("(") + 1; 476 unsigned int pos2 = input.find(")", pos1); 477 478 // Try to convert the stripped value-string to Vector2 479 if (pos1 < input.length() && pos2 < input.length() && pos1 < pos2) 480 { 481 std::vector<std::string> tokens = tokenize(input.substr(pos1, pos2 - pos1), ","); 482 if (!ConvertValue(&this->value_.getVector2().x, tokens[0])) 483 { 484 this->value_.setValue(defvalue); 485 return false; 486 } 487 if (!ConvertValue(&this->value_.getVector2().y, tokens[1])) 488 { 489 this->value_.setValue(defvalue); 490 return false; 491 } 492 493 return true; 494 } 495 496 this->value_.setValue(defvalue); 497 return false; 498 } 499 500 /** 501 @brief Parses a given std::string into a value of the type Vector3 and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 502 @param input The string to convert 503 @param defvalue The default-value 504 @return True if the string was successfully parsed 505 */ 506 bool ConfigValueContainer::parseString(const std::string& input, const Vector3& defvalue) 507 { 508 // Strip the value-string 509 unsigned int pos1 = input.find("(") + 1; 510 unsigned int pos2 = input.find(")", pos1); 511 512 // Try to convert the stripped value-string to Vector3 513 if (pos1 < input.length() && pos2 < input.length() && pos1 < pos2) 514 { 515 std::vector<std::string> tokens = tokenize(input.substr(pos1, pos2 - pos1), ","); 516 if (!ConvertValue(&this->value_.getVector3().x, tokens[0])) 517 { 518 this->value_.setValue(defvalue); 519 return false; 520 } 521 if (!ConvertValue(&this->value_.getVector3().y, tokens[1])) 522 { 523 this->value_.setValue(defvalue); 524 return false; 525 } 526 if (!ConvertValue(&this->value_.getVector3().z, tokens[2])) 527 { 528 this->value_.setValue(defvalue); 529 return false; 530 } 531 532 return true; 533 } 534 535 this->value_.setValue(defvalue); 536 return false; 537 } 538 539 /** 540 @brief Parses a given std::string into a value of the type ColourValue and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 541 @param input The string to convert 542 @param defvalue The default-value 543 @return True if the string was successfully parsed 544 */ 545 bool ConfigValueContainer::parseString(const std::string& input, const ColourValue& defvalue) 546 { 547 // Strip the value-string 548 unsigned int pos1 = input.find("(") + 1; 549 unsigned int pos2 = input.find(")", pos1); 550 551 // Try to convert the stripped value-string to Vector3 552 if (pos1 < input.length() && pos2 < input.length() && pos1 < pos2) 553 { 554 std::vector<std::string> tokens = tokenize(input.substr(pos1, pos2 - pos1), ","); 555 if (!ConvertValue(&this->value_.getColourValue().r, tokens[0])) 556 { 557 this->value_.setValue(defvalue); 558 return false; 559 } 560 if (!ConvertValue(&this->value_.getColourValue().g, tokens[1])) 561 { 562 this->value_.setValue(defvalue); 563 return false; 564 } 565 if (!ConvertValue(&this->value_.getColourValue().b, tokens[2])) 566 { 567 this->value_.setValue(defvalue); 568 return false; 569 } 570 if (!ConvertValue(&this->value_.getColourValue().a, tokens[3])) 571 { 572 this->value_.setValue(defvalue); 573 return false; 574 } 575 576 return true; 577 } 578 579 this->value_.setValue(defvalue); 580 return false; 581 } 582 583 /** 584 @brief Parses a given std::string into a value of the type Quaternion and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 585 @param input The string to convert 586 @param defvalue The default-value 587 @return True if the string was successfully parsed 588 */ 589 bool ConfigValueContainer::parseString(const std::string& input, const Quaternion& defvalue) 590 { 591 // Strip the value-string 592 unsigned int pos1 = input.find("(") + 1; 593 unsigned int pos2 = input.find(")", pos1); 594 595 // Try to convert the stripped value-string to Vector3 596 if (pos1 < input.length() && pos2 < input.length() && pos1 < pos2) 597 { 598 std::vector<std::string> tokens = tokenize(input.substr(pos1, pos2 - pos1), ","); 599 if (!ConvertValue(&this->value_.getQuaternion().w, tokens[0])) 600 { 601 this->value_.setValue(defvalue); 602 return false; 603 } 604 if (!ConvertValue(&this->value_.getQuaternion().x, tokens[1])) 605 { 606 this->value_.setValue(defvalue); 607 return false; 608 } 609 if (!ConvertValue(&this->value_.getQuaternion().y, tokens[2])) 610 { 611 this->value_.setValue(defvalue); 612 return false; 613 } 614 if (!ConvertValue(&this->value_.getQuaternion().z, tokens[3])) 615 { 616 this->value_.setValue(defvalue); 617 return false; 618 } 619 620 return true; 621 } 622 623 this->value_.setValue(defvalue); 624 return false; 625 } 626 627 /** 628 @brief Parses a given std::string into a value of the type long double and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 629 @param input The string to convert 630 @param defvalue The default-value 631 @return True if the string was successfully parsed 632 */ 633 bool ConfigValueContainer::parseString(const std::string& input, const Radian& defvalue) 634 { 635 return ConvertValue(&this->value_.getRadian(), input, defvalue); 636 } 637 638 /** 639 @brief Parses a given std::string into a value of the type long double and assigns it to the right variable. If the conversion failed, the default-value gets assigned. 640 @param input The string to convert 641 @param defvalue The default-value 642 @return True if the string was successfully parsed 643 */ 644 bool ConfigValueContainer::parseString(const std::string& input, const Degree& defvalue) 645 { 646 return ConvertValue(&this->value_.getDegree(), input, defvalue); 647 } 648 649 /** 650 @brief Sets the corresponding entry in the config-file back to the default value. 651 */ 652 void ConfigValueContainer::resetConfigFileEntry() 653 { 654 (*this->configFileLine_) = this->varname_ + "=" + this->defvalueString_; 655 ConfigValueContainer::writeConfigFile(CONFIGFILEPATH); 656 } 657 658 /** 659 @brief Sets the value of the variable back to the default value and resets the config-file entry. 660 */ 661 void ConfigValueContainer::resetConfigValue() 662 { 663 this->parseString(this->defvalueString_, this->value_); 664 this->resetConfigFileEntry(); 665 } 666 667 /** 668 @brief Searches the corresponding entry in the config-file and creates it, if there is no entry. 669 */ 670 void ConfigValueContainer::searchConfigFileLine() 671 { 672 // Read the file if needed 673 if (!ConfigValueContainer::finishedReadingConfigFile()) 674 ConfigValueContainer::readConfigFile(CONFIGFILEPATH); 675 676 // The string of the section we're searching 677 std::string section = ""; 678 section.append("["); 679 section.append(this->classname_); 680 section.append("]"); 681 682 // Iterate through all config-file-lines 683 bool success = false; 684 std::list<std::string>::iterator it1; 685 for(it1 = ConfigValueContainer::getConfigFileLines().begin(); it1 != ConfigValueContainer::getConfigFileLines().end(); ++it1) 686 { 687 // Don't try to parse comments 688 if (this->isComment(*it1)) 689 continue; 690 691 if ((*it1).find(section) < (*it1).length()) 692 { 693 // We found the right section 694 bool bLineIsEmpty = false; 695 std::list<std::string>::iterator positionToPutNewLineAt; 696 697 // Iterate through all lines in the section 698 std::list<std::string>::iterator it2; 699 for(it2 = ++it1; it2 != ConfigValueContainer::getConfigFileLines().end(); ++it2) 700 { 701 // Don't try to parse comments 702 if (this->isComment(*it2)) 703 continue; 704 705 // This if-else block is used to write a new line right after the last line of the 706 // section but in front of the following empty lines before the next section. 707 // (So this helps to keep a nice formatting with empty-lines between sections in the config-file) 708 if (this->isEmpty(*it2)) 709 { 710 if (!bLineIsEmpty) 711 { 712 bLineIsEmpty = true; 713 positionToPutNewLineAt = it2; 714 } 715 } 716 else 717 { 718 if (!bLineIsEmpty) 719 positionToPutNewLineAt = it2; 720 721 bLineIsEmpty = false; 722 } 723 724 // Look out for the beginning of the next section 725 unsigned int open = (*it2).find("["); 726 unsigned int close = (*it2).find("]"); 727 if ((open < (*it2).length()) && (close < (*it2).length()) && (open < close)) 728 { 729 // The next section startet, so our line isn't yet in the file - now we add it and safe the file 730 this->configFileLine_ = this->getConfigFileLines().insert(positionToPutNewLineAt, this->varname_ + "=" + this->defvalueString_); 731 ConfigValueContainer::writeConfigFile(CONFIGFILEPATH); 732 success = true; 733 break; 734 } 735 736 // Look out for the variable-name 737 if ((*it2).find(this->varname_) < (*it2).length()) 738 { 739 // We found the right line - safe it and return 740 this->configFileLine_ = it2; 741 success = true; 742 break; 743 } 744 } 745 746 // Check if we succeeded 270 bool ConfigValueContainer::parse(const std::string& input) 271 { 272 if (this->bIsVector_) 273 { 274 SubString token(input, " ", "", true, '"', false, '(', ')', false, '\0'); 275 int index = -1; 276 bool success = false; 277 278 if (token.size() > 0) 279 success = ConvertValue(&index, token[0]); 280 281 if (!success || index < 0 || index > MAX_VECTOR_INDEX) 282 { 747 283 if (!success) 748 284 { 749 // Looks like we found the right section, but the file ended without containing our variable - so we add it and safe the file 750 this->configFileLine_ = this->getConfigFileLines().insert(positionToPutNewLineAt, this->varname_ + "=" + this->defvalueString_); 751 ConfigValueContainer::writeConfigFile(CONFIGFILEPATH); 752 success = true; 285 COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is a vector." << std::endl; 753 286 } 754 break; 755 } 756 } 757 758 // Check if we succeeded 759 if (!success) 760 { 761 // We obviously didn't found the right section, so we'll create it 762 this->getConfigFileLines().push_back("[" + this->classname_ + "]"); // Create the section 763 this->getConfigFileLines().push_back(this->varname_ + "=" + this->defvalueString_); // Create the line 764 this->configFileLine_ = --this->getConfigFileLines().end(); // Set the pointer to the last element 765 success = true; 766 this->getConfigFileLines().push_back(""); // Add an empty line - this is needed for the algorithm in the searchConfigFileLine-function 767 ConfigValueContainer::writeConfigFile(CONFIGFILEPATH); // Save the changed config-file 768 } 769 } 770 771 /** 772 @brief Determines if a line in the config-file is a comment. 773 @param line The line to check 774 @return True = it's a comment 775 */ 776 bool ConfigValueContainer::isComment(const std::string& line) 777 { 778 // Strip the line, whitespaces are disturbing 779 std::string teststring = getStrippedLine(line); 780 781 // There are four possible comment-symbols: 782 // 1) #comment in script-language style 783 // 2) %comment in matlab style 784 // 3) ;comment in unreal tournament config-file style 785 // 4) //comment in code style 786 if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';' || (teststring[0] == '/' && teststring[0] == '/')) 287 else 288 { 289 COUT(1) << "Error: Invalid vector-index." << std::endl; 290 } 291 return false; 292 } 293 294 if (token.size() >= 2) 295 return this->parse(index, token.subSet(1).join()); 296 else 297 return this->parse(index, ""); 298 } 299 300 MultiTypeMath temp = this->value_; 301 if (temp.fromString(input)) 302 { 303 this->value_ = temp; 787 304 return true; 788 789 return false; 790 } 791 792 /** 793 @brief Determines if a line in the config-file is empty (contains only whitespaces). 794 @param line The line to check 795 @return True = it's empty 796 */ 797 bool ConfigValueContainer::isEmpty(const std::string& line) 798 { 799 return getStrippedLine(line) == ""; 800 } 801 802 /** 803 @brief Removes all whitespaces from a line. 804 @param line The line to strip 805 @return The stripped line 806 */ 807 std::string ConfigValueContainer::getStrippedLine(const std::string& line) 808 { 809 std::string output = line; 810 unsigned int pos; 811 while ((pos = output.find(" ")) < output.length()) 812 output.erase(pos, 1); 813 while ((pos = output.find("\t")) < output.length()) 814 output.erase(pos, 1); 815 816 return output; 817 } 818 819 /** 820 @brief Returns the part in the corresponding config-file-entry of the container that defines the value. 821 @param bStripped True = strip the value-string 822 @return The value-string 823 */ 824 std::string ConfigValueContainer::parseValueString(bool bStripped) 825 { 826 std::string output; 827 if (bStripped) 828 output = this->getStrippedLine(*this->configFileLine_); 829 else 830 output = *this->configFileLine_; 831 832 return output.substr(output.find("=") + 1); 833 } 834 835 /** 836 @brief Rreturns a list, containing all entrys in the config-file. 837 @return The list 838 */ 839 std::list<std::string>& ConfigValueContainer::getConfigFileLines() 840 { 841 // This is done to avoid problems while executing this code before main() 842 static std::list<std::string> configFileLinesStaticReference = std::list<std::string>(); 843 return configFileLinesStaticReference; 844 } 845 846 /** 847 @brief Returns true if the ConfigFile is read and stored into the ConfigFile-lines-list. 848 @param finished This is used to change the state 849 @return True if the ConfigFile is read and stored into the ConfigFile-lines-list 850 */ 851 bool ConfigValueContainer::finishedReadingConfigFile(bool finished) 852 { 853 // This is done to avoid problems while executing this code before main() 854 static bool finishedReadingConfigFileStaticVariable = false; 855 856 if (finished) 857 finishedReadingConfigFileStaticVariable = true; 858 859 return finishedReadingConfigFileStaticVariable; 860 } 861 862 /** 863 @brief Reads the config-file and stores the lines in a list. 864 @param filename The name of the config-file 865 */ 866 void ConfigValueContainer::readConfigFile(const std::string& filename) 867 { 868 // This creates the file if it's not existing 869 std::ofstream createFile; 870 createFile.open(filename.c_str(), std::fstream::app); 871 createFile.close(); 872 873 // Open the file 874 std::ifstream file; 875 file.open(filename.c_str(), std::fstream::in); 876 877 if (!file.is_open()) 878 { 879 COUT(1) << "An error occurred in ConfigValueContainer.cc:" << std::endl; 880 COUT(1) << "Error: Couldn't open config-file " << filename << " to read the config values!" << std::endl; 881 return; 882 } 883 884 char line[1024]; 885 886 // Iterate through the file and add the lines into the list 887 while (file.good() && !file.eof()) 888 { 889 file.getline(line, 1024); 890 ConfigValueContainer::getConfigFileLines().push_back(line); 891 // std::cout << "### ->" << line << "<- : empty: " << isEmpty(line) << " comment: " << isComment(line) << std::endl; 892 } 893 894 // The last line is useless 895 ConfigValueContainer::getConfigFileLines().pop_back(); 896 897 // Add an empty line to the end of the file if needed 898 // this is needed for the algorithm in the searchConfigFileLine-function 899 if ((ConfigValueContainer::getConfigFileLines().size() > 0) && !isEmpty(*ConfigValueContainer::getConfigFileLines().rbegin())) 900 { 901 // std::cout << "### newline added" << std::endl; 902 ConfigValueContainer::getConfigFileLines().push_back(""); 903 } 904 905 file.close(); 906 907 ConfigValueContainer::finishedReadingConfigFile(true); 908 } 909 910 /** 911 @brief Writes the content of the list, containing all lines of the config-file, into the config-file. 912 @param filename The name of the config-file 913 */ 914 void ConfigValueContainer::writeConfigFile(const std::string& filename) 915 { 916 // Make sure we stored the config-file in the list 917 if (!ConfigValueContainer::finishedReadingConfigFile()) 918 ConfigValueContainer::readConfigFile(filename); 919 920 // Open the file 921 std::ofstream file; 922 file.open(filename.c_str(), std::fstream::out); 923 924 if (!file.is_open()) 925 { 926 COUT(1) << "An error occurred in ConfigValueContainer.cc:" << std::endl; 927 COUT(1) << "Error: Couldn't open config-file " << filename << " to write the config values!" << std::endl; 928 return; 929 } 930 931 // Iterate through the list an write the lines into the file 932 std::list<std::string>::iterator it; 933 for (it = ConfigValueContainer::getConfigFileLines().begin(); it != ConfigValueContainer::getConfigFileLines().end(); ++it) 934 { 935 file << (*it) << std::endl; 936 } 937 938 file.close(); 305 } 306 return false; 307 } 308 309 /** 310 @brief Parses a given std::string into a value of the type of the associated variable and assigns it. 311 @param index The index in the vector 312 @param input The string to convert 313 @return True if the string was successfully parsed 314 */ 315 bool ConfigValueContainer::parse(unsigned int index, const std::string& input) 316 { 317 if (this->bIsVector_) 318 { 319 if (index >= this->valueVector_.size()) 320 { 321 for (unsigned int i = this->valueVector_.size(); i <= index; i++) 322 { 323 this->valueVector_.push_back(MultiTypeMath()); 324 ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isA(MT_string)); 325 } 326 } 327 328 MultiTypeMath temp = this->value_; 329 if (temp.fromString(input)) 330 { 331 this->valueVector_[index] = temp; 332 return true; 333 } 334 return false; 335 } 336 337 COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl; 338 return false; 339 } 340 341 /** 342 @brief Parses a given std::string into a value of the type of the associated variable and assigns it. 343 @param input The string to convert 344 @param defvalue The default value to assign if the parsing fails 345 @return True if the string was successfully parsed 346 */ 347 bool ConfigValueContainer::parse(const std::string& input, const MultiTypeMath& defvalue) 348 { 349 if (this->parse(input)) 350 return true; 351 352 this->value_ = defvalue; 353 return false; 354 } 355 356 /** 357 @brief Parses a given std::string into a value of the type of the associated variable and assigns it. 358 @param index The index in the vector 359 @param input The string to convert 360 @param defvalue The default value to assign if the parsing fails 361 @return True if the string was successfully parsed 362 */ 363 bool ConfigValueContainer::parse(unsigned int index, const std::string& input, const MultiTypeMath& defvalue) 364 { 365 if (this->bIsVector_) 366 { 367 if (this->parse(index, input)) 368 return true; 369 370 this->valueVector_[index] = defvalue; 371 return false; 372 } 373 374 COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl; 375 return false; 939 376 } 940 377 … … 947 384 if (!this->bAddedDescription_) 948 385 { 949 this->description_ = std::string("ConfigValueDescription::" + this-> classname_+ "::" + this->varname_);386 this->description_ = std::string("ConfigValueDescription::" + this->identifier_->getName() + "::" + this->varname_); 950 387 AddLanguageEntry(this->description_, description); 951 388 this->bAddedDescription_ = true;
Note: See TracChangeset
for help on using the changeset viewer.