Changeset 344
- Timestamp:
- 05/20/09 14:42:05 (16 years ago)
- Files:
-
- 6 modified
Legend:
- Unmodified
- Added
- Removed
-
bdm/stat/libBM.h
r342 r344 16 16 17 17 #include "../itpp_ext.h" 18 #include " libconfig/libconfig.h++"18 #include "../libconfig/libconfig.h++" 19 19 #include <map> 20 20 … … 35 35 } 36 36 37 //! This method returns a basic info about the current instance 37 38 virtual string ToString() 38 39 { … … 41 42 42 43 //! This method arrange instance properties according the data stored in the Setting structure 43 virtual void FromSetting( Setting &root )44 virtual void FromSetting( const Setting &root ) 44 45 { 45 46 } -
bdm/uibuilder.cpp
r281 r344 1 // 2 // C++ Implementation: itpp_ext 3 // 4 // Description: 5 // 6 // 7 // Author: smidl <smidl@utia.cas.cz>, (C) 2008 8 // 9 // Copyright: See COPYING file that comes with this distribution 10 // 11 // 12 13 #include "uibuilder.h" 14 15 namespace bdm { 16 17 UI::StringToUIMap::MappedString2UI& UI::StringToUIMap::privateMap() 18 { 19 static MappedString2UI var; 20 return var; 21 } 22 23 void UI::StringToUIMap::Add( const string &className, pUI pInstance ) 24 { 25 privateMap().insert( make_pair( className, pInstance ) ); 26 } 27 28 UI::pUI UI::StringToUIMap::Retrieve( const string &className ) 29 { 30 MappedString2UI::const_iterator iter = privateMap().find( className ); 31 if( iter == privateMap().end()) return NULL; 32 else return iter->second; 33 } 34 35 ////////////////////////////////////////////////////////////////////// 36 37 38 UIFile::UIFile ( const string &file_name ) : fileName( file_name ) 39 { 40 Config::setAutoConvert( true ); 41 } 42 43 //! loads root element from a file 44 void UIFile::Load() 45 { 46 try 47 { 48 Config::readFile( fileName.c_str() ); 49 } 50 catch ( FileIOException f ) 51 { 52 it_error ( "UI: file " + fileName + " not found." ); 53 } 54 catch ( ParseException& P ) 55 { 56 stringstream msg; 57 msg << "UI: parsing error """ << P.getError() << """ in file " << fileName << " on line " << P.getLine() << "."; 58 it_error ( msg.str() ); 59 } 60 } 61 62 63 //! Save UserInfo to the file (typically with an XML extension) 64 void UIFile::Save() 65 { 66 try 67 { 68 Config::writeFile ( fileName.c_str() ); 69 } 70 catch ( FileIOException f ) 71 { 72 it_error( "UI: file " + fileName + " is inacessible." ); 73 } 74 } 75 76 UIFile::operator Setting&() 77 { 78 return getRoot(); 79 } 80 81 } 82 /* 1 83 #include "uibuilder.h" 2 84 … … 4 86 5 87 //! global map of UIbulder names to instances of UIbuilders. Created by UIREGISTER macro 6 UI map__uimap__;88 UIbuilder::UImap UIbuilder::__uimap__; 7 89 8 90 bdmroot* UIexternal::build ( Setting &S ) const { … … 17 99 try { 18 100 Setting& remS=C.lookup ( ( const char* ) S["path"] ); 19 UIbuild 101 UIbuilder::build( remS,tmp ); 20 102 } 21 103 catch ( ... ) { … … 33 115 while ( !Stmp->isRoot() ); 34 116 Setting& intS=Stmp->lookup ( ( const char* ) S["path"] ); 35 UIbuild 117 UIbuilder::build( intS,tmp ); 36 118 } 37 119 catch ( ... ) { … … 81 163 } 82 164 //UIexternal* UIexternal_instance =new UIexternal(); 165 */ -
bdm/uibuilder.h
r334 r344 6 6 #include "libconfig/libconfig.h++" 7 7 8 namespace bdm { 9 8 #include <sstream> 9 #include <iostream> 10 #include <stdio.h> 11 #include <string> 12 #include <typeinfo> 13 #include <map> 14 #include <utility> 15 #include <vector> 16 #include <iostream> 17 18 using std::string; 19 using namespace std; 10 20 using namespace libconfig; 11 using namespace std; 12 13 #define CHECK_UITYPE(S,Type) it_assert_debug(S.getType()==Setting::Type, string("Wrong input path \"")+string(S.getPath())+string("\"")); 14 #define UIREGISTER(UI) UI* UI##_global_instance = new UI(); 15 16 //!Standard catches for UIs, use as: catch UICATCH 17 #define UICATCH ( SettingTypeException e ) {it_error ( "Setting " +string ( e.getPath() ) +" is of incorrect Type" );} catch ( SettingNotFoundException e ) {it_error ( "Setting " + string ( e.getPath() ) +" was not found" );} 18 19 ////////// GLOBAL VAriables 20 21 class UIbuilder; 22 //! Internal structure mapping strings to UIBuilder objects 23 typedef map<const string, const UIbuilder*> UImap; 24 extern UImap __uimap__; 25 26 class UIFile : public Config { 21 22 #define UIREGISTER(className) template<> ParticularUI<className>& ParticularUI<className>::ui = ParticularUI<className>(#className) 23 24 #define ASSERT_UITYPE(S,Type) it_assert_debug(S.getType()==Setting::Type, string("Wrong setting type, see input path \"")+string(S.getPath())+string("\"")) 25 26 namespace bdm 27 { 28 29 /*! 30 @brief This class serves to load and/or save DOMElements into/from files 31 stored on a hard-disk. 32 33 Firstly, you associate new RootElement instance with some filename during a time of its 34 construtcion. Then, you save some object into the new RootElement instance, 35 and save it into the file this way: 36 \code 37 CAudi audi; 38 RootElement root("cars.xml"); 39 UserInfo::Save( audi, root, "TT"); 40 root.Save(); 41 \endcode 42 43 In the other way round, when loading object from a XML file, the appropriate code looks like this: 44 \code 45 RootElement root("cars.xml"); 46 root.Load(); 47 UserInfo::Build<T>(root,"TT"); 48 \endcode 49 */ 50 51 class UIFile : public Config 52 { 53 private: 54 const string fileName; 55 27 56 public: 28 UIFile ( const char * fname ) :Config() { 29 try{Config::readFile ( fname );} 30 catch ( FileIOException f ) {it_error ( "File " + string ( fname ) + " not found" );} 31 catch ( ParseException& P ) { 32 char msg[200]; 33 sprintf ( msg,"Error in file %s on line %d.", fname, P.getLine() ); 57 //! attach new RootElement instance to a file (typically with an XML extension) 58 UIFile( const string &file_name ); 59 60 //! loads root element from a file 61 void Load(); 62 63 //! Save UserInfo to the file (typically with an XML extension) 64 void Save (); 65 66 operator Setting&(); 67 }; 68 69 70 /*! 71 @brief UserInfo is an abstract is for internal purposes only. Use CompoundUserInfo<T> or ParticularUI<T> instead. 72 The raison d'etre of this class is to allow pointers to its templated descendants. 73 74 Also, the main functions of the whole UserInfo library are included within this class, see 75 static methods 'Build' and 'Save'. 76 77 78 /*!\brief Builds computational object from a UserInfo structure 79 80 Return value is a pointer to the created object (memory management issue?) 81 / 82 83 */ 84 class UI 85 { 86 private: 87 //! just a typedef shortuct for a constant pointer to UI 88 typedef UI* pUI; 89 90 //! static class encalupsating map of names to related UserInfos 91 //! 92 //! The key property of this class is that it initilaized the internal map immediately 93 //! when it is used for a first time. 94 class StringToUIMap 95 { 96 private: 97 //! Type definition of mapping which transforms type names to the related user infors 98 typedef map< const string, pUI > MappedString2UI; 99 100 //! immediately initialized instance of type MappedString2UI 101 static MappedString2UI& privateMap(); 102 103 public: 104 //! add a pair key-userinfo into the internal map 105 static void Add( const string &className, pUI pInstance ); 106 107 //! search for an userinfo related to the passed key within the internal map 108 static pUI Retrieve( const string &className ); 109 }; 110 111 //! internal method assembling a typeless instance from components obtained by the 'AssemblyComponentsFromSetting()' method 112 virtual bdmroot* New() = 0; 113 114 //! type name defined by user 115 const string className; 116 117 protected: 118 119 //! default constructor 120 UI( const string& className ) : className ( className ) 121 { 122 StringToUIMap::Add( className, this ); 123 } 124 125 //! Virtual destructor for future use; 126 virtual ~UI(){}; 127 128 private: 129 130 //! This methods tries to save an instance of type T (or some of its descendant types) 131 //! and build DOM tree accordingly. Then, it creates a new DOMNode named according className 132 //! and connecti it to the passed Setting as a new child node. 133 template<class T> static void ToSetting( T &instance, Setting &element ) 134 { 135 string &className = ParticularUI<T>::ui.className; 136 137 // add attribute "class" 138 Setting &type = root.add( "class", Setting::TypeString ); 139 type = className; 140 141 try 142 { 143 // instance disassembling 144 instance.ToSetting( root ); 145 } 146 catch(SettingException xcptn) 147 { 148 it_error ( "UI: the method " + className + ".ToSetting(Setting&) has thrown an exception when filling the setting " + xcptn.getPath() + ". Try to correct this method." ); 149 } 150 } 151 152 template<class T> static T* FromSetting( const Setting &element ) 153 { 154 RevealIfLinked revealed_link( element ); 155 const Setting &root = revealed_link.root(); 156 157 ASSERT_UITYPE(root,TypeGroup); 158 159 // we get a velue stored in the "class" attribute 160 string className; 161 if( !root.lookupValue( "class", className ) ) 162 { 163 stringstream msg; 164 msg << "UI: the class identifier is missing within the setting """ << root.getPath() << """. Check line " 165 << root.getSourceLine() << "."; 166 it_error ( msg.str() ); 167 } 168 169 170 // and finally we find a UserInfo related to this type 171 pUI pRelatedUI = StringToUIMap::Retrieve( className ); 172 if( !pRelatedUI) 173 it_error ( "UI: class " + className + " was not properly registered. Use the macro ""UIREGISTER([class name]);"" within your code." ); 174 175 bdmroot* pTypelessInstance = pRelatedUI->New(); 176 177 T* pInstance = NULL; 178 try 179 { 180 pInstance = (T*) pTypelessInstance ; 181 } 182 catch(...) 183 { 184 it_error ( "UI: class " + className + " is not a descendant of the desired output class. Try to call the UI::Build function with a different type parameter." ); 185 } 186 187 try 188 { 189 // instance assembling 190 pInstance->FromSetting( root ); 191 } 192 catch(SettingException xcptn) 193 { 194 string msg = "UI: the method " + className + ".FromSetting(Setting&) has thrown an exception when parsing the setting " + xcptn.getPath() + ". Try to correct this method."; 34 195 it_error ( msg ); 35 196 } 36 } 197 return pInstance; 198 } 199 200 201 202 public: 203 204 // vraci true, kdyz to byl platny link, jinak false.. v pripade chyby konci it_errorem.. 205 // do elementu vrati setting prislusny po rozbaleni linku, jinak ponecha beze zmeny 206 class RevealIfLinked 207 { 208 private: 209 UIFile *file; 210 const Setting * result; 211 212 public: 213 214 RevealIfLinked( const Setting &element ) 215 { 216 file = NULL; 217 result = &element; 218 219 if( element.getType() != Setting::TypeString ) 220 return; 221 222 string link = (string) element; 223 size_t aerobase = link.find('@'); 224 if( aerobase != string::npos ) 225 { 226 string file_name = link.substr( aerobase + 1, link.length() ); 227 file = new UIFile( file_name ); 228 file->Load(); 229 // TODO OSETRIT FALSE, vyhodit iterr 230 231 result = &(Setting&)(*file); 232 233 link = link.substr( 0, aerobase ); 234 } 235 else 236 while ( !result->isRoot() ) 237 result = &result->getParent(); 238 239 if( !result->exists( link ) ) 240 { 241 // vyhodi chybu v pripade chyby 242 printf(""); 243 } 244 result = &(*result)[link]; 245 return; 246 } 247 248 ~RevealIfLinked() 249 { 250 if( file ) delete file; 251 } 252 253 254 const Setting& root() 255 { 256 return *result; 257 } 258 }; 259 260 private: 261 static const Setting* ToChildSetting( const Setting &element, const int index ) 262 { 263 if( !element.isAggregate()) 264 return NULL; 265 266 if( element.getLength() <= index ) 267 return NULL; 268 269 return &element[index]; 270 } 271 272 static const Setting* ToChildSetting( const Setting &element, const string &name ) 273 { 274 if( !element.isGroup() ) 275 return NULL; 276 277 if( !element.exists( name ) ) 278 return NULL; 279 280 return &element[name]; 281 } 282 283 static Setting& ToChildSetting( Setting &element, const int index ) 284 { 285 if( !element.isAggregate()) 286 { 287 // TODO CO ZA TYP? ASI NE GROUP, COZ.. 288 } 289 if( element.getLength() <= index ) 290 { 291 stringstream msg; 292 msg << "UI: there is not any child with index " << index << " in the parsed setting " 293 << element.getPath() << ", check line " << element.getSourceLine() << "."; 294 295 it_error ( msg.str() ); 296 } 297 return element[index]; 298 } 299 300 static Setting& ToChildSetting( Setting &element, const string &name ) 301 { 302 ASSERT_UITYPE(element,TypeGroup); 303 if( !element.exists( name ) ) 304 { 305 stringstream msg; 306 msg << "UI: there is not any child named """ << name << """ in the parsed setting " 307 << element.getPath() << ", check line " << element.getSourceLine() << "."; 308 309 it_error ( msg.str() ); 310 } 311 return element[name]; 312 } 313 314 //! This methods tries to build a new double matrix 315 static bool FromSetting( mat& matrix, const Setting &root ) 316 { 317 ASSERT_UITYPE(root,TypeList); 318 if( root.getLength() != 3 ) 319 { 320 stringstream msg; 321 msg << "UI: the setting " << root.getPath() << """ supposed to represent a matrix element has wrong syntax"". Check line " 322 << root.getSourceLine() << "."; 323 it_error ( msg.str() ); 324 } 325 326 Setting &cols_setting = root[0]; 327 Setting &rows_setting = root[1]; 328 Setting &values = root[2]; 329 330 ASSERT_UITYPE(cols_setting,TypeInt); 331 ASSERT_UITYPE(rows_setting,TypeInt); 332 ASSERT_UITYPE(values,TypeArray); 333 334 int cols = cols_setting; 335 int rows = rows_setting; 336 337 if( values.getLength() != cols * rows ) 338 { 339 stringstream msg; 340 msg << "UI: the lenght of array containing matrix values within setting " << root.getPath() << """ is improper, check line " 341 << root.getSourceLine() << "."; 342 it_error ( msg.str() ); 343 } 344 345 matrix.set_size( rows, cols ); 346 347 if( cols == 0 || rows == 0 ) 348 return true; 349 350 if( !values[0].isNumber() ) 351 { 352 stringstream msg; 353 msg << "UI: the array containing matrix values within setting " << root.getPath() << """ has to contain numeric values only! Check line " 354 << root.getSourceLine() << "."; 355 it_error ( msg.str() ); 356 } 357 358 // Build matrix row-wise 359 int k = 0; 360 for( int i=0;i<rows;i++ ) 361 for( int j=0; j<cols; j++) 362 matrix(i,j) = values[k++]; 363 364 return true; 365 } 366 367 //! This methods tries to save a double matrix 368 static void ToSetting( mat &matrix, Setting &root ) 369 { 370 Setting &cols = root.add( Setting::TypeInt ); 371 cols = matrix.cols(); 372 373 Setting &rows = root.add( Setting::TypeInt ); 374 rows = matrix.rows(); 375 376 Setting &values = root.add( Setting::TypeArray ); 377 378 // Build matrix row-wise 379 for( int i=0; i<matrix.rows(); i++ ) 380 for( int j=0; j<matrix.cols(); j++) 381 { 382 Setting &newField = values.add(Setting::TypeFloat); 383 newField = matrix(i,j); 384 } 385 } 386 387 //! This methods tries to build a new integer vector 388 static bool FromSetting( ivec &vec, const Setting &root ) 389 { 390 ASSERT_UITYPE(root,TypeArray); 391 392 int len = root.getLength(); 393 vec.set_length( len ); 394 if( len == 0 ) return true; 395 ASSERT_UITYPE(root[0],TypeInt); 396 397 for( int i=0; i < len; i++ ) 398 vec(i) = root[i]; 399 400 return true; 401 } 402 403 //! This methods tries to save an integer vector 404 static void ToSetting( ivec &vec, Setting &root ) 405 { 406 for( int i=0; i<vec.length(); i++ ) 407 { 408 Setting &newField = root.add(Setting::TypeInt); 409 newField = vec(i); 410 } 411 } 412 413 //! This methods tries to build a new array of strings 414 static bool FromSetting( Array<string> &string_array, const Setting &root) 415 { 416 ASSERT_UITYPE(root,TypeArray); 417 418 int len = root.getLength(); 419 string_array.set_length( len ); 420 if( len == 0 ) return true; 421 ASSERT_UITYPE(root[0],TypeString); 422 423 for( int i=0; i < len; i++ ) 424 string_array(i) = (string)root[i]; 425 426 return true; 427 } 428 429 //! This methods tries to save an array of strings 430 static void ToSetting( Array<string> &string_array, Setting &root ) 431 { 432 for( int i=0; i<string_array.length(); i++ ) 433 { 434 Setting &newField = root.add(Setting::TypeString); 435 newField = string_array(i); 436 } 437 } 438 439 public: 440 441 //! This methods tries to build a new instance of type T (or some of its descendant types) 442 //! according to a data stored in a DOMNode named className within a child nodes of the passed element. 443 //! If an error occurs, it returns a NULL pointer. 444 445 //! Prototype of a UI builder. Return value is by the second argument since it type checking via \c dynamic_cast. 446 template<class T> static T* Build( Setting &element, const int index ) 447 { 448 return FromSetting<T>( ToChildSetting( element, index ) ); 449 } 450 451 template<class T> static T* Build( Setting &element, const string &name ) 452 { 453 return FromSetting<T>( ToChildSetting( element, name ) ); 454 } 455 456 //! This methods tries to save an instance of type T (or some of its descendant types) 457 //! and build DOM tree accordingly. Then, it creates a new DOMNode named according className 458 //! and connecti it to the passed Setting as a new child node. 459 template<class T> static void Save( T &instance, Setting &element ) 460 { 461 Setting &root = element.add( Setting::TypeGroup ); 462 ToSetting( instance, root ); 463 } 464 465 //! This methods tries to save an instance of type T (or some of its descendant types) 466 //! and build DOM tree accordingly. Then, it creates a new DOMNode named according className 467 //! and connecti it to the passed Setting as a new child node. 468 template<class T> static void Save( T &instance, Setting &element, const string &name ) 469 { 470 Setting &root = element.add( name, Setting::TypeGroup ); 471 ToSetting( instance, root ); 472 } 473 474 //! This methods tries to build a new double matrix 475 static bool Get( mat& matrix, const Setting &element, const string &name ) 476 { 477 const Setting *root = ToChildSetting( element, name ); 478 if( !root ) return false; 479 return FromSetting( matrix, *root ); 480 } 481 482 //! This methods tries to build a new double matrix 483 static bool Get( mat& matrix, const Setting &element, const int index ) 484 { 485 const Setting *root = ToChildSetting( element, index ); 486 if( !root ) return false; 487 return FromSetting( matrix, *root ); 488 } 489 490 //! This methods tries to save a double matrix 491 static void Save( mat &matrix, Setting &element, const string &name ) 492 { 493 Setting &root = element.add( name, Setting::TypeList ); 494 ToSetting( matrix, root ); 495 } 496 497 //! This methods tries to save a double matrix 498 static void Save( mat &matrix, Setting &element ) 499 { 500 Setting &root = element.add( Setting::TypeList ); 501 ToSetting( matrix, root ); 502 } 503 504 505 //! This methods tries to build a new double vec 506 static bool Get( ivec& vec, const Setting &element, const string &name ) 507 { 508 const Setting *root = ToChildSetting( element, name ); 509 if( !root ) return false; 510 return FromSetting( vec, *root ); 511 } 512 513 //! This methods tries to build a new double vec 514 static bool Get( ivec& vec, const Setting &element, const int index ) 515 { 516 const Setting *root = ToChildSetting( element, index ); 517 if( !root ) return false; 518 return FromSetting( vec, *root ); 519 } 520 521 //! This methods tries to save a double vec 522 static void Save( ivec &vec, Setting &element, const string &name ) 523 { 524 Setting &root = element.add( name, Setting::TypeArray ); 525 ToSetting( vec, root ); 526 } 527 528 //! This methods tries to save a double vec 529 static void Save( ivec &vec, Setting &element) 530 { 531 Setting &root = element.add( Setting::TypeArray ); 532 ToSetting( vec, root ); 533 } 534 535 536 //! This methods tries to build a new double string_array 537 static bool Get( Array<string> &string_array, const Setting &element, const string &name ) 538 { 539 const Setting *root = ToChildSetting( element, name ); 540 if( !root ) return false; 541 return FromSetting( string_array, *root ); 542 } 543 544 //! This methods tries to build a new double string_array 545 static bool Get( Array<string> &string_array, const Setting &element, const int index ) 546 { 547 const Setting *root = ToChildSetting( element, index ); 548 if( !root ) return false; 549 return FromSetting( string_array, *root ); 550 } 551 552 //! This methods tries to save a double string_array 553 static void Save( Array<string> &string_array, Setting &element, const string &name ) 554 { 555 Setting &root = element.add( name, Setting::TypeArray ); 556 ToSetting( string_array, root ); 557 } 558 559 //! This methods tries to save a double string_array 560 static void Save( Array<string> &string_array, Setting &element ) 561 { 562 Setting &root = element.add( Setting::TypeArray ); 563 ToSetting( string_array, root ); 564 } 565 566 37 567 }; 38 568 39 //! \name elem Elementary build functions 40 //!@{ 41 42 //! construct itpp::vec from Setting of type Array 43 inline vec getvec ( Setting& S ) { 44 vec vector; 45 if (S.getType() == Setting::TypeArray) { 46 vector.set_size ( S.getLength() ); 47 for ( int i=0;i<S.getLength();i++ ) { 48 switch ( S[i].getType() ) { 49 case Setting::TypeFloat : 50 vector[i]=double ( S[i] );break; 51 case Setting::TypeInt : 52 vector[i]=int ( S[i] );break; 53 case Setting::TypeBoolean : 54 vector[i]=bool ( S[i] );break; 55 default: it_error ( "libconfig error?" ); 56 } 57 } 58 } else if (S.getType() == Setting::TypeGroup) { 59 vector = getvec(S["elements"]); 60 int cols = S["cols"]; 61 if (vector.length() != cols) { 62 it_error("requested vector is a matrix"); 63 } 64 } else { 65 it_error("requested vector has invalid type"); 66 } 67 return vector; 569 570 /*! 571 @brief The main userinfo template class. You should derive this class whenever you need 572 a new userinfo of a class which is compound from smaller elements (all having its 573 own userinfo class prepared). 574 */ 575 template<typename T> class ParticularUI : private UI 576 { 577 // to permit acces to the ParticularUI<T>::ui to the UI class 578 friend UI; 579 580 //! default constructor, which is intentionally declared as private 581 ParticularUI<T>( const string &className) : UI( className ) 582 { 583 }; 584 585 //! the only instance of this class (each type T has its own instance) 586 //! which is used as a factory for processing related UI 587 static ParticularUI<T>& ui; 588 589 bdmroot* New() 590 { 591 return new T(); 592 } 68 593 }; 69 594 70 //! construct itpp::mat from Setting of type Array, number of columns must be given 71 inline mat getmat ( Setting& S , int ncols ) { 72 CHECK_UITYPE ( S,TypeArray ); 73 mat tmp; 74 int nrows=S.getLength() /ncols; 75 int r=0,c=0; 76 tmp.set_size ( nrows, ncols ); 77 // Build matrix row-wise 78 for ( int i=0;i<S.getLength();i++ ) { 79 switch ( S[i].getType() ) { 80 case Setting::TypeFloat : 81 tmp ( r,c ) =double ( S[i] );break; 82 case Setting::TypeInt : 83 tmp ( r,c ) =int ( S[i] );break; 84 case Setting::TypeBoolean : 85 tmp ( r,c ) =bool ( S[i] );break; 86 default: it_error ( "libconfig error?" ); 87 } 88 c++; if ( c==ncols ) {c=0;r++;} 89 } 90 return tmp; 595 596 } 597 598 /*! Recursive build of objects defined in the same file 599 600 \code 601 {type="internal"; 602 path="system.profile.[0]"; // Path from the root 91 603 }; 92 93 //! construct itpp::mat from Setting of type Group containing settings 94 //! "elements" and "cols" 95 inline mat getmat (Setting & S) { 96 CHECK_UITYPE (S, TypeGroup); 97 return getmat(S["elements"], S["cols"]); 98 } 99 100 //! construct itpp::ivec from Setting of type Array 101 102 inline ivec getivec ( Setting& S ) { 103 CHECK_UITYPE ( S,TypeArray ); 104 ivec tmp; 105 tmp.set_size ( S.getLength() ); 106 for ( int i=0;i<S.getLength();i++ ) { 107 switch ( S[i].getType() ) { 108 case Setting::TypeFloat : 109 tmp[i]=double ( S[i] );break; 110 case Setting::TypeInt : 111 tmp[i]=int ( S[i] );break; 112 case Setting::TypeBoolean : 113 tmp[i]=bool ( S[i] );break; 114 default: it_error ( "libconfig error?" ); 115 } 116 } 117 return tmp; 118 }; 119 120 //! construct itpp::Array<string> from Setting of type Array 121 122 inline Array<string> get_as ( Setting& S ) { 123 CHECK_UITYPE ( S,TypeArray ); 124 Array<string> tmp; 125 tmp.set_size ( S.getLength() ); 126 for ( int i=0;i<S.getLength();i++ ) {tmp ( i ) = ( const char* ) S[i];} 127 return tmp; 128 }; 129 130 //!@} 131 132 /*!\brief Builds computational object from a UserInfo structure 133 134 Return value is a pointer to the created object (memory management issue?) 135 */ 136 class UIbuilder { 137 protected: 138 public: 139 //!Constructor needs to be run only once macro UIREGISTER 140 UIbuilder ( const string &typ ) {__uimap__.insert ( make_pair ( typ,this ) );} 141 //! Function building the computational object 142 virtual bdmroot* build ( Setting &S ) const =0; 143 //! Virtual destructor for future use; 144 virtual ~UIbuilder(){}; 145 }; 604 \endcode 605 */ 606 607 146 608 147 609 /*! Recursive build of objects defined in external file … … 153 615 }; 154 616 \endcode 155 */ 156 class UIexternal:public UIbuilder { 157 public: 158 UIexternal() :UIbuilder ( "external" ) {} 159 bdmroot* build ( Setting &S ) const; 160 }; 161 162 /*! Recursive build of objects defined in the same file 163 164 \code 165 {type="internal"; 166 path="system.profile.[0]"; // Path from the root 167 }; 168 \endcode 169 */ 170 class UIinternal:public UIbuilder { 171 public: 172 UIinternal() :UIbuilder ( "internal" ) {} 173 bdmroot* build ( Setting &S ) const; 174 }; 617 / 618 175 619 176 620 //! [Debugging] Print values in current S to cout 177 621 void UI_DBG ( Setting &S, const string &spc ); 178 622 179 //! Prototype of a UI builder. Return value is by the second argument since it type checking via \c dynamic_cast. 180 template<class T> 181 void UIbuild ( Setting &S, T* &ret ) { 182 CHECK_UITYPE ( S,TypeGroup ); 183 // Check if field "type" is present, if not it is not a valid UI 184 it_assert_debug ( S.exists ( "type" ), string ( S.getPath() ) +" is not a valid UI!" ); 185 186 const string typ=S["type"]; 187 // Find "type" in list of registred UI builders 188 UImap::const_iterator iter = __uimap__.find ( typ ); 189 if ( iter == __uimap__.end() ) { 190 it_error ( "UI of type \"" + typ + "\" is not registered!" ); 191 } 192 193 //BUILD the result 194 try { 195 ret = dynamic_cast<T*> ( iter->second->build ( S ) ); 196 } 197 catch UICATCH 198 }; 199 623 624 /* 200 625 //! Auxiliary function allowing recursivity in S (too complex, remove?) 201 626 template<class T> 202 627 void UIcall ( Setting &S, void ( *func ) ( Setting&, T ), T Tmp ) { 203 CHECK_UITYPE ( S,TypeGroup );204 // Check if field " type" is present, if not it is not a valid UI205 it_assert_debug ( S.exists ( " type" ), string ( S.getPath() ) +" is not a valid UI!" );206 207 const string typ=S[" type"];628 ASSERT_UITYPE ( S,TypeGroup ); 629 // Check if field "class" is present, if not it is not a valid UI 630 it_assert_debug ( S.exists ( "class" ), string ( S.getPath() ) +" is not a valid UI!" ); 631 632 const string typ=S["class"]; 208 633 if ( typ=="internal" ) { 209 634 try { … … 235 660 236 661 } 237 #endif //UIBUILD 662 663 */ 664 665 #endif // #ifndef UIBUILD -
tests/UI/UIbuilder_test.cfg
r278 r344 1 1 //test 2 test: 2 pepikovo : 3 3 { 4 type= "test"; 5 a= 1; 6 S= "hello!!!"; 4 class = "Car"; 5 year = 1998; 6 manufacturer = "audi"; 7 kilometers = 25000; 7 8 }; 8 test2: 9 jardovo : 9 10 { 10 type= "internal"; 11 path="int"; 11 class = "Car"; 12 year = 1992; 13 manufacturer = "liaz"; 14 kilometers = 1555000; 12 15 }; 13 test3: 16 ondrejovo : 14 17 { 15 type= "external"; 16 filename = "UIbuilder_test_ex.cfg"; 17 path="test2"; 18 class = "Bike"; 19 year = 1996; 20 manufacturer = "author"; 21 electricLights = true; 22 matr = ( 2, 2, [ 1.0, 0.0, 0.0, 1.0 ] ); 18 23 }; 19 int: 20 { 21 type= "test2"; 22 a= 1; 23 S= "yeah!!!"; 24 }; 24 elisky : "jardovo"; 25 kati : "skubankovo@UIbuilder_test_ex.cfg"; -
tests/UI/UIbuilder_test.cpp
r278 r344 1 1 #include <uibuilder.h> 2 #include <string> 2 3 3 using namespace libconfig;4 using std::string; 4 5 using namespace std; 5 6 using namespace bdm; 6 7 7 class cls :public bdmroot{ 8 public: 9 int a; 10 string S; 11 cls(int a0, string S0):a(a0),S(S0){}; 12 virtual void print(){cout << a << " and "<< S << endl;} 13 }; 14 class cls2: public cls{ 15 public: 16 cls2(int a0, string S0):cls(a0,S0){}; 17 void print(){cout << a << " or "<< S << endl;} 8 class Transport : public bdmroot 9 { 10 public: 11 int year; 12 string manufacturer; 13 14 Transport() 15 { 16 year = 1900; 17 manufacturer = "unknown"; 18 } 19 20 Transport( int year, string manufacturer ) 21 : year( year ), manufacturer( manufacturer ) 22 { 23 } 24 25 virtual void FromSetting( const Setting &root ) 26 { 27 root.lookupValue( "year", year ); 28 root.lookupValue( "manufacturer", manufacturer ); 29 } 30 31 virtual void ToSetting( Setting &root ) 32 { 33 Setting &year_setting = root.add("year", Setting::TypeInt ); 34 year_setting = year; 35 36 Setting &manufacturer_setting = root.add("manufacturer", Setting::TypeString ); 37 manufacturer_setting = manufacturer; 38 } 18 39 }; 19 40 20 class UItest : public UIbuilder{ 21 public: 22 UItest():UIbuilder("test"){} 23 bdmroot* build(Setting &S) const{ 24 int a=S["a"]; 25 string St; 26 S.lookupValue("S",St); 27 cls* tmp = new cls(a,St); 28 return tmp; 29 } 41 class Car : public Transport 42 { 43 public: 44 int kilometers; 45 46 Car() : Transport() 47 { 48 kilometers = 0; 49 } 50 51 52 Car( int year, string manufacturer, int kilometers ) 53 : Transport( year, manufacturer ), kilometers( kilometers ) 54 { 55 } 56 57 virtual void FromSetting( const Setting &root ) 58 { 59 Transport::FromSetting( root ); 60 61 root.lookupValue( "kilometers", kilometers ); 62 } 63 64 virtual void ToSetting( Setting &root ) 65 { 66 Transport::ToSetting( root ); 67 68 Setting &kilometers_setting = root.add("kilometers", Setting::TypeInt ); 69 kilometers_setting = kilometers; 70 } 71 72 string ToString() 73 { 74 stringstream stream; 75 stream << "a car made in " << year << " by " << manufacturer << ", having " << kilometers << " kilometers on the clock."; 76 return stream.str(); 77 } 30 78 }; 31 79 32 class UItest2 : public UIbuilder{ 33 public: 34 UItest2():UIbuilder("test2"){} 35 bdmroot* build(Setting &S) const{ 36 int a=S["a"]; 37 string St; 38 S.lookupValue("S",St); 39 return new cls2(a,St); 40 } 41 int no(){return 2;} 80 UIREGISTER(Car); 81 82 class Bike : public Transport 83 { 84 public: 85 bool electricLights; 86 mat matr; 87 88 Bike() : Transport(), matr("2,2;3,4") 89 { 90 electricLights = false; 91 } 92 93 Bike( int year, string manufacturer, bool electricLights ) 94 : Transport( year, manufacturer ), electricLights( electricLights ) 95 { 96 } 97 98 ~Bike() 99 { 100 } 101 102 void FromSetting( const Setting &root ) 103 { 104 Transport::FromSetting( root ); 105 106 root.lookupValue( "electricLights", electricLights ); 107 108 UI::Get( matr, root, "matr" ); 109 } 110 111 void ToSetting( Setting &root ) 112 { 113 Transport::ToSetting( root ); 114 115 Setting &electricLights_setting = root.add("electricLights", Setting::TypeBoolean ); 116 electricLights_setting = electricLights; 117 118 UI::Save( matr, root, "matr" ); 119 } 120 121 string ToString() 122 { 123 stringstream stream; 124 stream << "a bike made in " << year << " by " << manufacturer; 125 if( electricLights ) stream << " with electric lights included"; 126 return stream.str(); 127 } 42 128 }; 43 129 44 UIREGISTER(UItest); 45 UIREGISTER(UItest2); 46 //UItest* UItest_instance = new UItest(); 47 //UItest2* UItest2_instance = new UItest2(); 130 UIREGISTER(Bike); 48 131 49 int main(){ 50 UIFile UI("UIbuilder_test.cfg"); 132 int main() 133 { 134 /////////////////////////////////// SAVING ////////////////////////// 135 /* 136 Car audi( 1998, "audi", 25000); 137 Car liaz( 1992, "liaz", 1555000); 138 Bike author( 1996, "author", true ); 51 139 52 cls* Cls; 53 UIbuild(UI.lookup("test"),Cls); 54 cls* Cls2; 55 UIbuild(UI.lookup("test2"),Cls2); 56 cls* Cls3; 57 UIbuild(UI.lookup("test3"),Cls3); 140 UIFile root("UIbuilder_test.cfg"); 141 UI::Save( audi, root, "pepikovo"); 142 UI::Save( liaz, root, "jardovo"); 143 UI::Save( author, root, "ondrejovo"); 144 root.Save(); 58 145 59 Cls->print(); 60 Cls2->print(); 61 Cls3->print(); 62 63 delete Cls; 64 delete Cls2; 65 delete Cls3; 146 cout << "all the transport means were saved correctly" << endl; 147 getchar(); 148 */ 149 150 //////////////////////////////////// LOADING //////////////////////////////// 151 UIFile root("UIbuilder_test.cfg"); 152 root.Load(); 153 Transport *pepikovo = UI::Build<Transport>( root, "pepikovo"); 154 cout << "pepikovo: " << pepikovo->ToString() << endl; 155 Transport *jardovo = UI::Build<Transport>( root, "jardovo"); 156 cout << "jardovo: " << jardovo->ToString() << endl; 157 Transport *ondrejovo = UI::Build<Transport>( root, "ondrejovo"); 158 cout << "ondrejovo: " << ondrejovo->ToString() << endl; 159 Transport *elisky = UI::Build<Transport>( root, "elisky"); 160 cout << "elisky: " << elisky->ToString() << endl; 161 Transport *kati = UI::Build<Transport>( root, "kati"); 162 cout << "kati: " << kati->ToString() << endl; 163 getchar(); 164 return 0; 66 165 } -
tests/UI/UIbuilder_test_ex.cfg
r278 r344 1 test2: 1 skubankovo : 2 2 { 3 type= "test2"; 4 a= 1; 5 S= "distant hello!!!"; 3 class = "Car"; 4 year = 1980; 5 manufacturer = "vecernicek"; 6 kilometers = 250000; 6 7 };