[344] | 1 | // |
---|
[396] | 2 | // C++ Implementation: user_info.cpp |
---|
[344] | 3 | // |
---|
[396] | 4 | // Description: UI (user info) class for loading/saving objects from/to configuration files. |
---|
[344] | 5 | // |
---|
| 6 | // |
---|
[396] | 7 | // Author: smidl <smidl@utia.cas.cz>, (C) 2009 |
---|
[344] | 8 | // |
---|
| 9 | // Copyright: See COPYING file that comes with this distribution |
---|
| 10 | // |
---|
| 11 | // |
---|
| 12 | |
---|
[345] | 13 | #include "user_info.h" |
---|
[244] | 14 | |
---|
[477] | 15 | namespace bdm { |
---|
[540] | 16 | |
---|
[737] | 17 | string UIException::format_message ( const string &reason, const string &path ) { |
---|
[1064] | 18 | stringstream ss; |
---|
| 19 | ss << reason; |
---|
| 20 | ss << " Check path \"" << path << "\"."; |
---|
| 21 | return ss.str(); |
---|
[540] | 22 | } |
---|
| 23 | |
---|
[394] | 24 | ///////////////////////////// Class UIFile ///////////////////////////////////////////// |
---|
[344] | 25 | |
---|
[477] | 26 | UIFile::UIFile() { |
---|
[344] | 27 | } |
---|
| 28 | |
---|
[477] | 29 | UIFile::UIFile ( const string &file_name ) { |
---|
[1064] | 30 | try { |
---|
| 31 | readFile ( file_name.c_str() ); |
---|
| 32 | // this flag has to be set AFTER each file load, that is why it is right here |
---|
| 33 | setAutoConvert ( true ); |
---|
| 34 | } catch ( FileIOException f ) { |
---|
| 35 | string msg = "UI error: file "; |
---|
| 36 | msg += file_name; |
---|
| 37 | msg += " not found."; |
---|
| 38 | bdm_error ( msg ); |
---|
| 39 | } catch ( ParseException& P ) { |
---|
| 40 | stringstream msg; |
---|
| 41 | msg << "UI error: parsing error """ << P.getError() << """ in file " << file_name << " on line " << P.getLine() << "."; |
---|
| 42 | bdm_error ( msg.str() ); |
---|
| 43 | } |
---|
[344] | 44 | } |
---|
| 45 | |
---|
| 46 | |
---|
[477] | 47 | void UIFile::save ( const string &file_name ) { |
---|
[1064] | 48 | try { |
---|
| 49 | writeFile ( file_name.c_str() ); |
---|
| 50 | } catch ( FileIOException f ) { |
---|
| 51 | string msg = "UI error: file "; |
---|
| 52 | msg += file_name; |
---|
| 53 | msg += " is inacessible."; |
---|
| 54 | bdm_error ( msg ); |
---|
| 55 | } |
---|
[357] | 56 | } |
---|
[344] | 57 | |
---|
[477] | 58 | UIFile::operator Setting&() { |
---|
[1064] | 59 | return getRoot(); |
---|
[344] | 60 | } |
---|
| 61 | |
---|
[394] | 62 | ///////////////////////////// Class UI::MappedUI ///////////////////////////////////////////// |
---|
| 63 | |
---|
[477] | 64 | UI::MappedUI::StringToUIMap& UI::MappedUI::mapped_strings() { |
---|
[1064] | 65 | // this way it is ensured that there is only one instance of StringTpUIMap, and |
---|
| 66 | // what is more, this declaration leaves its allocation/deallocation on the compiler |
---|
| 67 | static StringToUIMap var; |
---|
| 68 | return var; |
---|
[344] | 69 | } |
---|
| 70 | |
---|
[477] | 71 | UI::MappedUI::TypeInfoToStringMap& UI::MappedUI::mapped_type_infos() { |
---|
[1064] | 72 | // this way it is ensured that there is only one instance of TypeInfoToStringMap, and |
---|
| 73 | // what is more, this declaration leaves its allocation/deallocation on the compiler |
---|
| 74 | static TypeInfoToStringMap var; |
---|
| 75 | return var; |
---|
[351] | 76 | } |
---|
| 77 | |
---|
[477] | 78 | void UI::MappedUI::add_class ( const string &class_name, const type_info * const class_type_info, const UI* const ui ) { |
---|
[1064] | 79 | pair< StringToUIMap::iterator, bool> inres = |
---|
| 80 | mapped_strings().insert ( |
---|
| 81 | StringToUIMap::value_type ( class_name, ui ) ); |
---|
| 82 | if ( inres.second ) { |
---|
| 83 | mapped_type_infos().insert ( |
---|
| 84 | TypeInfoToStringMap::value_type ( |
---|
| 85 | class_type_info, class_name ) ); |
---|
| 86 | } |
---|
[351] | 87 | } |
---|
| 88 | |
---|
[477] | 89 | void UI::MappedUI::unregistered_class_error ( const string &unregistered_class_name ) { |
---|
[1064] | 90 | stringstream msg; |
---|
| 91 | msg << "UI error: class " + unregistered_class_name + " was not properly registered. Use the macro ""UIREGISTER([class name]);"" within your code." << endl; |
---|
[394] | 92 | |
---|
[1064] | 93 | if ( mapped_strings().size() ) { |
---|
| 94 | StringToUIMap::const_iterator iter = mapped_strings().begin(); |
---|
| 95 | msg << "These classes are already registered: " << iter->first; |
---|
| 96 | for ( iter++; iter != mapped_strings().end(); iter++ ) |
---|
| 97 | msg << ", " << iter->first; |
---|
| 98 | msg << "." << endl; |
---|
| 99 | } else |
---|
| 100 | msg << "There is not any registered class yet!" << endl; |
---|
[477] | 101 | |
---|
[1064] | 102 | bdm_error ( msg.str() ); |
---|
[394] | 103 | } |
---|
| 104 | |
---|
[477] | 105 | const UI& UI::MappedUI::retrieve_ui ( const string &class_name ) { |
---|
[1064] | 106 | StringToUIMap::const_iterator iter = mapped_strings().find ( class_name ); |
---|
| 107 | if ( iter == mapped_strings().end() ) |
---|
| 108 | unregistered_class_error ( class_name ); |
---|
[477] | 109 | |
---|
[1064] | 110 | return *iter->second; |
---|
[357] | 111 | } |
---|
[351] | 112 | |
---|
[477] | 113 | const string& UI::MappedUI::retrieve_class_name ( const type_info * const class_type_info ) { |
---|
[1064] | 114 | TypeInfoToStringMap::const_iterator iter = mapped_type_infos().find ( class_type_info ); |
---|
| 115 | if ( iter == mapped_type_infos().end() ) |
---|
| 116 | unregistered_class_error ( "with RTTI name " + string ( class_type_info->name() ) ); |
---|
| 117 | return iter->second; |
---|
[357] | 118 | } |
---|
[351] | 119 | |
---|
[396] | 120 | ///////////////////////////// Class SettingResolver ///////////////////////////////////////////// |
---|
[351] | 121 | |
---|
[477] | 122 | SettingResolver::SettingResolver ( const Setting &potential_link ) |
---|
[1064] | 123 | : result ( initialize_reference ( file, potential_link ) ) { |
---|
[377] | 124 | } |
---|
[351] | 125 | |
---|
[477] | 126 | const Setting& SettingResolver::initialize_reference ( UIFile *&file, const Setting &potential_link ) { |
---|
[1064] | 127 | file = NULL; |
---|
[384] | 128 | |
---|
[1064] | 129 | if ( potential_link.getType() != Setting::TypeString ) |
---|
| 130 | return potential_link; |
---|
[377] | 131 | |
---|
[1064] | 132 | string link = ( const char* ) potential_link; |
---|
| 133 | size_t aerobase = link.find ( '@' ); |
---|
[477] | 134 | |
---|
[1064] | 135 | const Setting *result; |
---|
| 136 | if ( aerobase != string::npos ) { |
---|
| 137 | string file_name = link.substr ( aerobase + 1, link.length() ); |
---|
| 138 | file = new UIFile ( file_name ); |
---|
| 139 | result = & ( Setting& ) ( *file ); |
---|
| 140 | link = link.substr ( 0, aerobase ); |
---|
| 141 | } else { |
---|
| 142 | result = &potential_link; |
---|
| 143 | while ( !result->isRoot() ) |
---|
| 144 | result = &result->getParent(); |
---|
| 145 | } |
---|
[351] | 146 | |
---|
[1064] | 147 | if ( !result->exists ( link ) ) |
---|
| 148 | throw UISettingException ( "UIException: linked setting was not found.", string ( ( const char* ) potential_link ) ); |
---|
[351] | 149 | |
---|
[1064] | 150 | return ( *result ) [link]; |
---|
[351] | 151 | } |
---|
| 152 | |
---|
[477] | 153 | SettingResolver::~SettingResolver() { |
---|
[1064] | 154 | if ( file ) delete file; |
---|
[351] | 155 | } |
---|
| 156 | |
---|
[394] | 157 | ///////////////////////////// Class UI ///////////////////////////////////////////// |
---|
[351] | 158 | |
---|
[477] | 159 | void UI::assert_type ( const Setting &element, Setting::Type type ) { |
---|
[1064] | 160 | if ( element.getType() != type ) |
---|
| 161 | throw UISettingException ( "UIException: wrong setting type.", element ); |
---|
[357] | 162 | } |
---|
[351] | 163 | |
---|
[477] | 164 | const Setting& UI::to_child_setting ( const Setting &element, const int index ) { |
---|
[1064] | 165 | if ( !element.isList() ) |
---|
| 166 | throw UISettingException ( "UIException: only TypeList elements could be indexed by integers.", element ); |
---|
[394] | 167 | |
---|
[1064] | 168 | return element[index]; |
---|
[394] | 169 | } |
---|
| 170 | |
---|
[477] | 171 | const Setting& UI::to_child_setting ( const Setting &element, const string &name ) { |
---|
[1064] | 172 | if ( !element.isGroup() ) |
---|
| 173 | throw UISettingException ( "UIException: only TypeGroup elements could be indexed by strings.", element ); |
---|
[394] | 174 | |
---|
[1064] | 175 | return element[name]; |
---|
[394] | 176 | } |
---|
| 177 | |
---|
[942] | 178 | void UI::call_to_setting( const root &instance, Setting &set, string class_name ) { |
---|
[1064] | 179 | try { |
---|
| 180 | instance.to_setting ( set ); |
---|
| 181 | } catch ( SettingException &sttng_xcptn ) { |
---|
| 182 | string msg = "UIException: method "; |
---|
| 183 | msg += class_name; |
---|
| 184 | msg += ".to_setting(Setting&) has thrown a SettingException."; |
---|
| 185 | throw UISettingException ( msg, sttng_xcptn.getPath() ); |
---|
| 186 | } |
---|
[942] | 187 | } |
---|
| 188 | |
---|
| 189 | void UI::save ( const root &instance, Setting &element, const string &name ) { |
---|
[1064] | 190 | Setting &set = ( name == "" ) ? (element.getType()==Setting::TypeArray || element.getType()==Setting::TypeList) ? element.add ( Setting::TypeGroup ) : element |
---|
| 191 | : element.add ( name, Setting::TypeGroup ); |
---|
[942] | 192 | |
---|
[1064] | 193 | call_to_setting( instance, set ); |
---|
[942] | 194 | } |
---|
| 195 | |
---|
[959] | 196 | void UI::save ( const log_level_base &log_level, Setting &element ) { |
---|
[1064] | 197 | assert_type ( element, Setting::TypeGroup ); |
---|
| 198 | string name = "log_level"; |
---|
| 199 | |
---|
| 200 | if( element.exists( name ) ) |
---|
| 201 | assert_type ( element[name], Setting::TypeString ); |
---|
| 202 | else |
---|
| 203 | element.add ( name, Setting::TypeString ); |
---|
| 204 | |
---|
| 205 | call_to_setting( log_level, element[name] ); |
---|
[959] | 206 | } |
---|
| 207 | |
---|
[942] | 208 | void UI::save ( const root * const instance, Setting &element, const string &name ) { |
---|
[1064] | 209 | Setting &set = ( name == "" ) ? (element.getType()==Setting::TypeArray || element.getType()==Setting::TypeList) ? element.add ( Setting::TypeGroup ) : element |
---|
| 210 | : element.add ( name, Setting::TypeGroup ); |
---|
[942] | 211 | |
---|
[1064] | 212 | // add attribute "class" |
---|
| 213 | const string &class_name = MappedUI::retrieve_class_name ( &typeid ( *instance ) ); |
---|
| 214 | Setting &type = set.add ( "class", Setting::TypeString ); |
---|
| 215 | type = class_name; |
---|
[942] | 216 | |
---|
[1064] | 217 | call_to_setting( *instance, set, class_name ); |
---|
[942] | 218 | } |
---|
| 219 | |
---|
[477] | 220 | void UI::save ( const int &integer, Setting &element, const string &name ) { |
---|
[1064] | 221 | Setting &set = ( name == "" ) ? element.add ( Setting::TypeInt ) |
---|
| 222 | : element.add ( name, Setting::TypeInt ); |
---|
| 223 | set = integer; |
---|
[394] | 224 | } |
---|
| 225 | |
---|
[477] | 226 | void UI::save ( const double &real, Setting &element, const string &name ) { |
---|
[1064] | 227 | Setting &set = ( name == "" ) ? element.add ( Setting::TypeFloat ) |
---|
| 228 | : element.add ( name, Setting::TypeFloat ); |
---|
| 229 | set = real; |
---|
[394] | 230 | } |
---|
| 231 | |
---|
[477] | 232 | void UI::save ( const string &str, Setting &element, const string &name ) { |
---|
[1064] | 233 | Setting &set = ( name == "" ) ? element.add ( Setting::TypeString ) |
---|
| 234 | : element.add ( name, Setting::TypeString ); |
---|
| 235 | set = str; |
---|
[351] | 236 | } |
---|
| 237 | |
---|
[477] | 238 | void UI::save ( const mat &matrix, Setting &element, const string &name ) { |
---|
[1064] | 239 | Setting &set = ( name == "" ) ? element.add ( Setting::TypeList ) |
---|
| 240 | : element.add ( name, Setting::TypeList ); |
---|
[351] | 241 | |
---|
[1064] | 242 | Setting &tag = set.add ( Setting::TypeString ); |
---|
| 243 | tag = "matrix"; |
---|
[737] | 244 | |
---|
[1064] | 245 | Setting &rows = set.add ( Setting::TypeInt ); |
---|
| 246 | rows = matrix.rows(); |
---|
[351] | 247 | |
---|
[1064] | 248 | Setting &cols = set.add ( Setting::TypeInt ); |
---|
| 249 | cols = matrix.cols(); |
---|
[357] | 250 | |
---|
[1064] | 251 | Setting &elements = set.add ( Setting::TypeArray ); |
---|
| 252 | |
---|
| 253 | // build matrix row-wise |
---|
| 254 | for ( int i = 0; i < matrix.rows(); i++ ) |
---|
| 255 | for ( int j = 0; j < matrix.cols(); j++ ) { |
---|
| 256 | Setting &new_field = elements.add ( Setting::TypeFloat ); |
---|
| 257 | new_field = matrix ( i, j ); |
---|
| 258 | } |
---|
[351] | 259 | } |
---|
| 260 | |
---|
[1015] | 261 | void UI::save ( const ldmat &matrix, Setting &element, const string &name ) { |
---|
[1064] | 262 | Setting &set = ( name == "" ) ? element.add ( Setting::TypeGroup) |
---|
| 263 | : element.add ( name, Setting::TypeGroup ); |
---|
| 264 | |
---|
| 265 | save (matrix._L(), set, "L"); |
---|
| 266 | save (matrix._D(), set, "D"); |
---|
[1015] | 267 | } |
---|
| 268 | |
---|
[477] | 269 | void UI::save ( const ivec &vector, Setting &element, const string &name ) { |
---|
[1064] | 270 | Setting &set = ( name == "" ) ? element.add ( Setting::TypeArray ) |
---|
| 271 | : element.add ( name, Setting::TypeArray ); |
---|
| 272 | for ( int i = 0; i < vector.length(); i++ ) { |
---|
| 273 | Setting &new_field = set.add ( Setting::TypeInt ); |
---|
| 274 | new_field = vector ( i ); |
---|
| 275 | } |
---|
[351] | 276 | } |
---|
| 277 | |
---|
[477] | 278 | void UI::save ( const vec &vector, Setting &element, const string &name ) { |
---|
[1064] | 279 | Setting &set = ( name == "" ) ? element.add ( Setting::TypeArray ) |
---|
| 280 | : element.add ( name, Setting::TypeArray ); |
---|
| 281 | for ( int i = 0; i < vector.length(); i++ ) { |
---|
| 282 | Setting &new_field = set.add ( Setting::TypeFloat ); |
---|
| 283 | new_field = vector ( i ); |
---|
| 284 | } |
---|
[357] | 285 | } |
---|
| 286 | |
---|
[907] | 287 | |
---|
[942] | 288 | void UI::call_from_setting( root &instance, const Setting &set, string class_name) { |
---|
[1064] | 289 | try { |
---|
| 290 | instance.from_setting ( set ); |
---|
| 291 | } catch ( SettingException &sttng_xcptn ) { |
---|
| 292 | string msg = "UIException: method "; |
---|
| 293 | msg += class_name; |
---|
| 294 | msg += ".from_setting(Setting&) has thrown a SettingException."; |
---|
| 295 | throw UISettingException ( msg, sttng_xcptn.getPath() ); |
---|
| 296 | } catch ( std::runtime_error &e ) { |
---|
| 297 | string msg = "UIException: method "; |
---|
| 298 | msg += class_name; |
---|
| 299 | msg += " says: "; |
---|
| 300 | msg += e.what(); |
---|
| 301 | throw UISettingException ( msg, set ); |
---|
| 302 | } |
---|
[907] | 303 | |
---|
[1064] | 304 | // validate the new instance |
---|
| 305 | instance.validate(); |
---|
[942] | 306 | } |
---|
[907] | 307 | |
---|
[959] | 308 | void UI::from_setting ( log_level_base &log_level, const Setting &element ) { |
---|
[1064] | 309 | assert_type( element, Setting::TypeString ); |
---|
| 310 | call_from_setting( log_level, element ); |
---|
[959] | 311 | } |
---|
[907] | 312 | |
---|
[959] | 313 | void UI::from_setting ( root &instance, const Setting &element ) { |
---|
[1064] | 314 | const SettingResolver link ( element ); |
---|
| 315 | assert_type( link.result, Setting::TypeGroup ); |
---|
| 316 | call_from_setting( instance, link.result); |
---|
[959] | 317 | } |
---|
| 318 | |
---|
[477] | 319 | void UI::from_setting ( mat& matrix, const Setting &element ) { |
---|
[1064] | 320 | const SettingResolver link ( element ); |
---|
[351] | 321 | |
---|
[1064] | 322 | if ( link.result.isNumber() ) { |
---|
| 323 | matrix.set_size ( 1, 1 ); |
---|
| 324 | matrix ( 0, 0 ) = link.result; |
---|
| 325 | return; |
---|
| 326 | } |
---|
[351] | 327 | |
---|
[1064] | 328 | if ( link.result.isList() ) { |
---|
| 329 | int data_offset; |
---|
[351] | 330 | |
---|
[1064] | 331 | if ( link.result.getLength() == 3 ) |
---|
| 332 | data_offset = 0; |
---|
| 333 | else if ( link.result.getLength() == 4 ) { |
---|
| 334 | assert_type ( link.result[0], Setting::TypeString ); |
---|
| 335 | const char* elem1 = ( const char* ) link.result[0]; |
---|
| 336 | if ( ( strcmp ( elem1, "matrix" ) ) ) |
---|
| 337 | throw UISettingException ( "UIException: the setting supposed to represent a matrix element has wrong syntax.", link.result ); |
---|
[351] | 338 | |
---|
[1064] | 339 | data_offset = 1; |
---|
| 340 | } else |
---|
| 341 | throw UISettingException ( "UIException: the setting supposed to represent a matrix element has wrong syntax.", link.result ); |
---|
[390] | 342 | |
---|
[1064] | 343 | Setting &rows_setting = link.result[0 + data_offset]; |
---|
| 344 | Setting &cols_setting = link.result[1 + data_offset]; |
---|
| 345 | Setting &elements = link.result[2 + data_offset]; |
---|
[390] | 346 | |
---|
[1064] | 347 | // vvv ----- not working in matlab!! |
---|
| 348 | //assert_type ( cols_setting, Setting::TypeInt ); |
---|
| 349 | //assert_type ( rows_setting, Setting::TypeInt ); |
---|
| 350 | //assert_type ( elements, Setting::TypeArray ); |
---|
[351] | 351 | |
---|
[1064] | 352 | int cols = cols_setting; |
---|
| 353 | int rows = rows_setting; |
---|
| 354 | int elems = elements.getLength(); |
---|
[351] | 355 | |
---|
[1064] | 356 | if ( cols < 0 || rows < 0 ) |
---|
| 357 | throw UISettingException ( "UIException: the dimensions of a matrix has to be non-negative.", link.result ); |
---|
[351] | 358 | |
---|
[1064] | 359 | if ( elems != cols * rows ) |
---|
| 360 | throw UISettingException ( "UIException: the count of the matrix elements is incompatible with matrix dimension.", elements ); |
---|
[351] | 361 | |
---|
[1064] | 362 | matrix.set_size ( rows, cols ); |
---|
[351] | 363 | |
---|
[1064] | 364 | if ( cols == 0 || rows == 0 ) |
---|
| 365 | return; |
---|
[351] | 366 | |
---|
[1064] | 367 | if ( !elements[0].isNumber() ) |
---|
| 368 | throw UISettingException ( "UIException: matrix elements have to be numbers.", elements[0] ); |
---|
[351] | 369 | |
---|
[1064] | 370 | // build matrix row-wise |
---|
| 371 | int k = 0; |
---|
| 372 | for ( int i = 0; i < rows; i++ ) |
---|
| 373 | for ( int j = 0; j < cols; j++ ) |
---|
| 374 | matrix ( i, j ) = elements[k++]; |
---|
| 375 | return; |
---|
| 376 | } |
---|
[357] | 377 | |
---|
[1064] | 378 | throw UISettingException ( "UIException: only numeric types or TypeList are supported as matrix values.", link.result ); |
---|
[351] | 379 | } |
---|
| 380 | |
---|
[1015] | 381 | void UI::from_setting ( ldmat& matrix, const Setting &element ) { |
---|
[1064] | 382 | if(element.exists("L")) { |
---|
| 383 | UI::from_setting(matrix.__L(), element["L"]); |
---|
[1079] | 384 | } else { |
---|
| 385 | throw UISettingException ( "UIException: ldmat must contain matrix L.", element); |
---|
| 386 | } |
---|
[1064] | 387 | if(element.exists("D")) { |
---|
| 388 | UI::from_setting(matrix.__D(), element["D"]); |
---|
[1079] | 389 | } else { |
---|
| 390 | throw UISettingException ( "UIException: ldmat must contain vector D.", element); |
---|
| 391 | } |
---|
[1064] | 392 | matrix.validate(); |
---|
[1015] | 393 | } |
---|
| 394 | |
---|
[477] | 395 | void UI::from_setting ( vec &vector, const Setting &element ) { |
---|
[1064] | 396 | const SettingResolver link ( element ); |
---|
[351] | 397 | |
---|
[1064] | 398 | if ( link.result.isNumber() ) { |
---|
| 399 | vector.set_length ( 1 ); |
---|
| 400 | vector ( 0 ) = link.result; |
---|
| 401 | return; |
---|
| 402 | } |
---|
[351] | 403 | |
---|
[1064] | 404 | if ( link.result.isList() ) { |
---|
| 405 | mat matrix; |
---|
| 406 | from_setting ( matrix, link.result ); |
---|
[351] | 407 | |
---|
[1064] | 408 | if ( matrix.cols() != 1 && matrix.rows() != 1 && matrix.cols() != 0 ) |
---|
| 409 | throw UISettingException ( "UIException: the vector length is invalid, it seems to be rather a matrix.", link.result ); |
---|
[351] | 410 | |
---|
[1064] | 411 | int len = matrix.rows() * matrix.cols(); |
---|
| 412 | vector.set_length ( len ); |
---|
| 413 | if ( len == 0 ) return; |
---|
[357] | 414 | |
---|
[1064] | 415 | if ( matrix.cols() == 1 ) |
---|
| 416 | for ( int i = 0; i < len; i++ ) |
---|
| 417 | vector ( i ) = matrix ( i, 0 ); |
---|
| 418 | else |
---|
| 419 | for ( int i = 0; i < len; i++ ) |
---|
| 420 | vector ( i ) = matrix ( 0, i ); |
---|
| 421 | return; |
---|
| 422 | } |
---|
[357] | 423 | |
---|
[1064] | 424 | if ( link.result.isArray() ) { |
---|
| 425 | int len = link.result.getLength(); |
---|
| 426 | vector.set_length ( len ); |
---|
| 427 | if ( len == 0 ) return; |
---|
[357] | 428 | |
---|
[1064] | 429 | if ( !link.result[0].isNumber() ) |
---|
| 430 | throw UISettingException ( "UIException: a vector element has to be a number.", link.result[0] ); |
---|
[357] | 431 | |
---|
[1064] | 432 | for ( int i = 0; i < len; i++ ) |
---|
| 433 | vector ( i ) = link.result[i]; |
---|
[377] | 434 | |
---|
[1064] | 435 | return; |
---|
| 436 | } |
---|
[357] | 437 | |
---|
[1064] | 438 | throw UISettingException ( "UIException: only numeric types, TypeArray or TypeList are supported as vector values.", link.result ); |
---|
[351] | 439 | } |
---|
| 440 | |
---|
[477] | 441 | void UI::from_setting ( ivec &vector, const Setting &element ) { |
---|
[1064] | 442 | vec double_vector; |
---|
| 443 | from_setting ( double_vector, element ); |
---|
| 444 | int len = double_vector.length(); |
---|
| 445 | vector.set_length ( len ); |
---|
| 446 | for ( int i = 0; i < len; i++ ) |
---|
| 447 | vector ( i ) = ( int ) double_vector ( i ); |
---|
[396] | 448 | } |
---|
| 449 | |
---|
[477] | 450 | void UI::from_setting ( string &str, const Setting &element ) { |
---|
[1064] | 451 | assert_type ( element, Setting::TypeString ); |
---|
| 452 | str = ( const char* ) element; |
---|
[357] | 453 | } |
---|
[351] | 454 | |
---|
[477] | 455 | void UI::from_setting ( int &integer, const Setting &element ) { |
---|
[490] | 456 | // assert_type ( element, Setting::TypeInt ); |
---|
[1064] | 457 | integer = element; |
---|
[351] | 458 | } |
---|
| 459 | |
---|
[477] | 460 | void UI::from_setting ( double &real, const Setting &element ) { |
---|
[490] | 461 | // assert_type ( element, Setting::TypeFloat ); |
---|
[1064] | 462 | real = element; |
---|
[351] | 463 | } |
---|
| 464 | |
---|
[762] | 465 | }//namespace |
---|