Changeset 351
- Timestamp:
- 06/01/09 02:08:50 (16 years ago)
- Files:
-
- 1 added
- 1 removed
- 4 modified
Legend:
- Unmodified
- Added
- Removed
-
bdm/stat/libBM.h
r347 r351 14 14 #define BM_H 15 15 16 #include <map> 16 17 17 18 #include "../itpp_ext.h" 18 19 #include "../libconfig/libconfig.h++" 19 #include <map> 20 20 21 21 22 using namespace libconfig; … … 47 48 48 49 //! This method save all the instance properties into the Setting structure 49 virtual void to_setting( Setting &root ) 50 virtual void to_setting( Setting &root ) const 50 51 { 51 52 } -
bdm/user_info.cpp
r345 r351 15 15 namespace bdm { 16 16 17 UI::Class_To_UI::Class_To_UI_Map& UI::Class_To_UI::private_map() 18 { 19 static Class_To_UI_Map var; 20 return var; 21 } 22 23 void UI::Class_To_UI::add_class( const string &class_name, UI* ui ) 24 { 25 private_map().insert( make_pair( class_name, ui ) ); 26 } 27 28 UI* UI::Class_To_UI::retrieve_ui( const string &class_name ) 29 { 30 Class_To_UI_Map::const_iterator iter = private_map().find( class_name ); 31 if( iter == private_map().end()) return NULL; 32 else return iter->second; 33 } 34 35 ////////////////////////////////////////////////////////////////////// 17 18 ///////////////////////// UI FILE ///////////////////////////////////////////// 36 19 37 20 … … 78 61 return getRoot(); 79 62 } 80 81 } 82 63 ///////////////////////// INTERNAL MAPPED_UI ///////////////////////////////////////////// 64 65 UI::Mapped_UI::String_To_UI_Map& UI::Mapped_UI::mapped_strings() 66 { 67 static String_To_UI_Map var; 68 return var; 69 } 70 71 UI::Mapped_UI::Type_Info_To_String_Map& UI::Mapped_UI::mapped_type_infos() 72 { 73 static Type_Info_To_String_Map var; 74 return var; 75 } 76 77 void UI::Mapped_UI::add_class( const string &class_name, const type_info * const class_type_info, const UI* const ui ) 78 { 79 pair< const string, const UI* const > new_pair = make_pair( class_name, ui ); 80 mapped_strings().insert( new_pair ); 81 mapped_type_infos().insert( make_pair( class_type_info, new_pair.first ) ); 82 } 83 84 const UI& UI::Mapped_UI::retrieve_ui( const string &class_name ) 85 { 86 String_To_UI_Map::const_iterator iter = mapped_strings().find( class_name ); 87 if( iter == mapped_strings().end()) 88 it_error ( "UI error: class " + class_name + " was not properly registered. Use the macro ""UIREGISTER([class name]);"" within your code." ); 89 return *iter->second; 90 } 91 92 const string& UI::Mapped_UI::retrieve_class_name( const type_info * const class_type_info ) 93 { 94 Type_Info_To_String_Map::const_iterator iter = mapped_type_infos().find( class_type_info ); 95 if( iter == mapped_type_infos().end()) 96 it_error ( "UI error: class with RTTI name " + string(class_type_info->name()) + " was not properly registered. Use the macro ""UIREGISTER([class name]);"" within your code." ); 97 return iter->second; 98 } 99 100 ///////////////////////// INTERNAL LINK EXPANDER ///////////////////////////////////////////// 101 102 UI::Link_Expander::Link_Expander( const Setting &potential_link ) 103 { 104 file = NULL; 105 result = &potential_link; 106 107 if( potential_link.getType() != Setting::TypeString ) 108 return; 109 110 string link = (string) potential_link; 111 size_t aerobase = link.find('@'); 112 if( aerobase != string::npos ) 113 { 114 string file_name = link.substr( aerobase + 1, link.length() ); 115 file = new UI_File( file_name ); 116 file->load(); 117 result = &(Setting&)(*file); 118 link = link.substr( 0, aerobase ); 119 } 120 else 121 while ( !result->isRoot() ) 122 result = &result->getParent(); 123 124 if( !result->exists( link ) ) 125 ui_error( "linked Setting was not found", potential_link ); 126 127 result = &(*result)[link]; 128 } 129 130 UI::Link_Expander::~Link_Expander() 131 { 132 if( file ) delete file; 133 } 134 135 const Setting& UI::Link_Expander::root() const 136 { 137 return *result; 138 } 139 140 ///////////////////////// UI ///////////////////////////////////////////// 141 142 143 144 //! This methods - kvuli ukladani pole stringu, dat jen privatne? 145 void UI::save( const string &str, Setting &element ) 146 { 147 Setting &root = element.add( Setting::TypeString ); 148 root = str; 149 } 150 151 void UI::save( const mat &matrix, Setting &element, const string &name) 152 { 153 154 Setting &root = (name == "") ? element.add( Setting::TypeList ) 155 : element.add( name, Setting::TypeList ); 156 157 Setting &cols = root.add( Setting::TypeInt ); 158 cols = matrix.cols(); 159 160 Setting &rows = root.add( Setting::TypeInt ); 161 rows = matrix.rows(); 162 163 Setting &elements = root.add( Setting::TypeArray ); 164 165 // build matrix row-wise 166 for( int i=0; i<matrix.rows(); i++ ) 167 for( int j=0; j<matrix.cols(); j++) 168 { 169 Setting &new_field = elements.add(Setting::TypeFloat); 170 new_field = matrix(i,j); 171 } 172 } 173 174 175 //! This methods tries to save a double vec 176 void UI::save( const ivec &vec, Setting &element, const string &name) 177 { 178 179 Setting &root = (name == "") ? element.add( Setting::TypeArray ) 180 : element.add( name, Setting::TypeArray ); 181 for( int i=0; i<vec.length(); i++ ) 182 { 183 Setting &new_field = root.add(Setting::TypeInt); 184 new_field = vec(i); 185 } 186 } 187 188 189 //! This methods tries to build a new double matrix 190 191 void UI::from_setting( mat& matrix, const Setting &element ) 192 { 193 const Link_Expander link_expander( element ); 194 const Setting &root = link_expander.root(); 195 196 if( root.isNumber() ) 197 { 198 matrix.set_size( 1, 1 ); 199 matrix(0,0) = root; 200 return; 201 } 202 203 if( root.isList() ) 204 { 205 if( root.getLength() != 3 ) 206 ui_error( "the setting supposed to represent a matrix element has wrong syntax", root ); 207 208 Setting &cols_setting = root[0]; 209 Setting &rows_setting = root[1]; 210 Setting &elements = root[2]; 211 212 ASSERT_UITYPE(cols_setting,TypeInt); 213 ASSERT_UITYPE(rows_setting,TypeInt); 214 ASSERT_UITYPE(elements,TypeArray); 215 216 int cols = cols_setting; 217 int rows = rows_setting; 218 219 if( cols < 0 | rows < 0 ) 220 ui_error( "the dimensions of a matrix has to be non-negative", root ); 221 222 if( elements.getLength() != cols * rows ) 223 ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements ); 224 225 matrix.set_size( rows, cols ); 226 227 if( cols == 0 || rows == 0 ) 228 return; 229 230 if( !elements[0].isNumber() ) 231 ui_error( "matrix elements have to be numbers", elements[0] ); 232 233 // build matrix row-wise 234 int k = 0; 235 for( int i=0;i<rows;i++ ) 236 for( int j=0; j<cols; j++) 237 matrix(i,j) = elements[k++]; 238 return; 239 } 240 241 ui_error( "only numeric types or TypeList are supported as matrix values", root ); 242 } 243 244 //! This methods tries to build a new integer vector 245 void UI::from_setting( ivec &vec, const Setting &element ) 246 { 247 const Link_Expander link_expander( element ); 248 const Setting &root = link_expander.root(); 249 250 if( root.isNumber() ) 251 { 252 ASSERT_UITYPE(root,TypeInt); 253 vec.set_length( 1 ); 254 vec(0) = root; 255 return; 256 } 257 258 if( root.isList() ) 259 { 260 if( root.getLength() != 3 ) 261 ui_error( "the setting supposed to represent a matrix element has wrong syntax", root ); 262 263 Setting &cols_setting = root[0]; 264 Setting &rows_setting = root[1]; 265 Setting &elements = root[2]; 266 267 ASSERT_UITYPE(cols_setting,TypeInt); 268 ASSERT_UITYPE(rows_setting,TypeInt); 269 ASSERT_UITYPE(elements,TypeArray); 270 271 int cols = cols_setting; 272 int rows = rows_setting; 273 274 if( cols < 0 | rows < 0) 275 ui_error( "the dimensions of a matrix has to be non-negative", root ); 276 277 if( elements.getLength() != cols * rows ) 278 ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements ); 279 280 if( cols != 1 & rows !=1) 281 ui_error( "the vector length is invalid, it seems to be rather a matrix", elements ); 282 283 int len = rows * cols; 284 vec.set_length ( len ); 285 if( len == 0 ) return; 286 287 ASSERT_UITYPE(elements[0],TypeInt); 288 for( int i=0; i<len; i++ ) 289 vec(i) = elements[i]; 290 return; 291 } 292 293 if( root.isArray() ) 294 { 295 int len = root.getLength(); 296 vec.set_length( len ); 297 if( len == 0 ) return; 298 299 ASSERT_UITYPE(root[0],TypeInt); 300 for( int i=0; i < len; i++ ) 301 vec(i) = root[i]; 302 return; 303 } 304 305 ui_error( "only numeric types, TypeArray or TypeList are supported as vector values", root ); 306 } 307 308 309 void UI::from_setting( string &str, const Setting &element ) 310 { 311 ASSERT_UITYPE(element,TypeString); 312 str = (string) element; 313 } 314 315 316 ///////////////////////// UI FILE ///////////////////////////////////////////// 317 //! This methods tries to save an instance of type T (or some of its descendant types) 318 //! and build DOM tree accordingly. Then, it creates a new DOMNode named according class_name 319 //! and connecti it to the passed Setting as a new child node. 320 const Setting* UI::pointer_to_child_setting( const Setting &element, const int index ) 321 { 322 if( !element.isList()) 323 return NULL; 324 325 if( element.getLength() <= index ) 326 return NULL; 327 328 return &element[index]; 329 } 330 331 const Setting* UI::pointer_to_child_setting( const Setting &element, const string &name ) 332 { 333 if( !element.isGroup() ) 334 return NULL; 335 336 if( !element.exists( name ) ) 337 return NULL; 338 339 return &element[name]; 340 } 341 342 const Setting& UI::reference_to_child_setting( const Setting &element, const int index ) 343 { 344 if( !element.isList()) 345 ui_error( "only TypeList elements could be indexed by integers", element ); 346 347 if( element.getLength() <= index ) 348 ui_error( "there is not any child with index " + index, element ); 349 350 return element[index]; 351 } 352 353 const Setting& UI::reference_to_child_setting( const Setting &element, const string &name ) 354 { 355 ASSERT_UITYPE(element,TypeGroup); 356 if( !element.exists( name ) ) 357 ui_error( "there is not any child named """ + name, element ); 358 return element[name]; 359 } 360 361 362 } 363 -
bdm/user_info.h
r345 r351 2 2 #define UIBUILD 3 3 4 #include <itpp/itbase.h>5 #include "stat/libBM.h"6 #include "libconfig/libconfig.h++"7 4 8 5 #include <sstream> … … 16 13 #include <iostream> 17 14 15 #include "libconfig/libconfig.h++" 16 17 #include <itpp/itbase.h> 18 19 #include "stat/libBM.h" 20 18 21 using std::string; 19 22 using namespace std; … … 26 29 namespace bdm 27 30 { 31 class UI_File : public Config 32 { 33 private: 34 const string file_name; 35 36 public: 37 //! attach new RootElement instance to a file (typically with an XML extension) 38 UI_File( const string &file_name ); 39 40 //! loads root element from a file 41 void load(); 42 43 //! save UserInfo to the file (typically with an XML extension) 44 void save(); 45 46 operator Setting&(); 47 }; 28 48 29 49 /*! … … 49 69 */ 50 70 51 class UI_File : public Config52 {53 private:54 const string file_name;55 56 public:57 //! attach new RootElement instance to a file (typically with an XML extension)58 UI_File( const string &file_name );59 60 //! loads root element from a file61 void load();62 63 //! save UserInfo to the file (typically with an XML extension)64 void save();65 66 operator Setting&();67 };68 69 71 70 72 /*! … … 89 91 //! The key property of this class is that it initilaized the internal map immediately 90 92 //! when it is used for a first time. 91 class Class_To_UI93 class Mapped_UI 92 94 { 93 95 private: 94 96 //! Type definition of mapping which transforms type names to the related user infors 95 typedef map< const string, UI* > Class_To_UI_Map; 96 97 //! immediately initialized instance of type Class_To_UI_Map 98 static Class_To_UI_Map& private_map(); 97 typedef map< const string, const UI* const > String_To_UI_Map; 98 99 //! Type definition of mapping which transforms type names to the related user infors 100 typedef map< const type_info * const, const string > Type_Info_To_String_Map; 101 102 //! immediately initialized instance of type String_To_UI_Map 103 static String_To_UI_Map& mapped_strings(); 104 105 //! immediately initialized instance of type String_To_UI_Map 106 static Type_Info_To_String_Map& mapped_type_infos(); 99 107 100 108 public: 101 109 //! add a pair key-userinfo into the internal map 102 static void add_class( const string &class_name, UI*ui );110 static void add_class( const string &class_name, const type_info * const class_type_info, const UI* const ui ); 103 111 104 112 //! search for an userinfo related to the passed key within the internal map 105 static UI* retrieve_ui( const string &class_name ); 113 static const UI& retrieve_ui( const string &class_name ); 114 115 //! search for an userinfo related to the passed key within the internal map 116 static const string& retrieve_class_name( const type_info* const class_type_info ); 106 117 }; 107 118 119 // vraci true, kdyz to byl platny link, jinak false.. v pripade chyby konci it_errorem.. 120 // do elementu vrati setting prislusny po rozbaleni linku, jinak ponecha beze zmeny 121 class Link_Expander 122 { 123 private: 124 UI_File *file; 125 const Setting *result; 126 127 public: 128 129 Link_Expander( const Setting &potential_link ); 130 131 ~Link_Expander(); 132 133 const Setting& root() const; 134 }; 135 136 108 137 //! internal method assembling a typeless instance from components obtained by the 'AssemblyComponentsFromSetting()' method 109 virtual bdmroot* new_instance() = 0;138 virtual bdmroot* new_instance() const = 0; 110 139 111 //! type name defined by user112 const string class_name;113 114 140 //! This methods tries to save an instance of type T (or some of its descendant types) 115 141 //! and build DOM tree accordingly. Then, it creates a new DOMNode named according class_name 116 142 //! and connecti it to the passed Setting as a new child node. 117 template<class T> static void to_setting( const T &instance, Setting &root ) 118 { 119 const string &class_name = Particular_UI<T>::ui.class_name; 120 121 // add attribute "class" 122 Setting &type = root.add( "class", Setting::TypeString ); 123 type = class_name; 124 125 try 126 { 127 // instance disassembling 128 instance.to_setting( root ); 129 } 130 catch(SettingException xcptn) 131 { 132 it_error ( "UI error: the method " + class_name + ".to_setting(Setting&) has thrown an exception when filling the setting " + xcptn.getPath() + ". Try to correct this method." ); 133 } 134 } 135 136 template<class T> static T* from_setting( const Setting &element ) 143 static const Setting* pointer_to_child_setting( const Setting &element, const int index ); 144 145 static const Setting* pointer_to_child_setting( const Setting &element, const string &name ); 146 147 static const Setting& reference_to_child_setting( const Setting &element, const int index ); 148 149 static const Setting& reference_to_child_setting( const Setting &element, const string &name ); 150 151 152 //! This methods tries to build a new double matrix 153 static void from_setting( mat& matrix, const Setting &element ); 154 //! This methods tries to build a new integer vector 155 static void from_setting( ivec &vec, const Setting &element ); 156 // jednak kvuli pretypovani, apak taky proto, ze na string nefunguje link_expander.. 157 static void from_setting( string &str, const Setting &element ); 158 //! This methods tries to build a new templated array 159 160 template<class T> static void from_setting( T* &instance, const Setting &element ) 137 161 { 138 162 const Link_Expander link_expander( element ); … … 147 171 148 172 // and finally we find a UserInfo related to this type 149 UI* related_UI = Class_To_UI::retrieve_ui( class_name ); 150 if( !related_UI) 151 it_error ( "UI error: class " + class_name + " was not properly registered. Use the macro ""UIREGISTER([class name]);"" within your code." ); 152 153 bdmroot* typeless_instance = related_UI->new_instance(); 154 155 T* ui = NULL; 173 const UI& related_UI = Mapped_UI::retrieve_ui( class_name ); 174 175 bdmroot* typeless_instance = related_UI.new_instance(); 176 177 instance = NULL; 156 178 try 157 179 { 158 ui= (T*) typeless_instance ;180 instance = (T*) typeless_instance ; 159 181 } 160 182 catch(...) … … 165 187 try 166 188 { 167 // instance assembling 168 ui->from_setting( root ); 189 instance->from_setting( root ); 169 190 } 170 191 catch(SettingException xcptn) … … 172 193 it_error ( "UI error: the method " + class_name + ".from_setting(Setting&) has thrown an exception when parsing the setting " + xcptn.getPath() + ". Try to correct this method." ); 173 194 } 174 return ui;175 195 } 176 196 177 197 178 // vraci true, kdyz to byl platny link, jinak false.. v pripade chyby konci it_errorem.. 179 // do elementu vrati setting prislusny po rozbaleni linku, jinak ponecha beze zmeny 180 class Link_Expander 181 { 182 private: 183 UI_File *file; 184 const Setting *result; 185 186 public: 187 188 Link_Expander( const Setting &potential_link ) 189 { 190 file = NULL; 191 result = &potential_link; 192 193 if( potential_link.getType() != Setting::TypeString ) 194 return; 195 196 string link = (string) potential_link; 197 size_t aerobase = link.find('@'); 198 if( aerobase != string::npos ) 199 { 200 string file_name = link.substr( aerobase + 1, link.length() ); 201 file = new UI_File( file_name ); 202 file->load(); 203 result = &(Setting&)(*file); 204 link = link.substr( 0, aerobase ); 205 } 206 else 207 while ( !result->isRoot() ) 208 result = &result->getParent(); 209 210 if( !result->exists( link ) ) 211 ui_error( "linked Setting was not found", potential_link ); 212 213 result = &(*result)[link]; 214 } 215 216 ~Link_Expander() 217 { 218 if( file ) delete file; 219 } 220 221 const Setting& root() const 222 { 223 return *result; 224 } 225 }; 226 227 static const Setting* to_child_setting( const Setting &element, const int index ) 228 { 229 if( !element.isAggregate()) 230 return NULL; 231 232 if( element.getLength() <= index ) 233 return NULL; 234 235 return &element[index]; 236 } 237 238 static const Setting* to_child_setting( const Setting &element, const string &name ) 239 { 240 if( !element.isGroup() ) 241 return NULL; 242 243 if( !element.exists( name ) ) 244 return NULL; 245 246 return &element[name]; 247 } 248 249 static Setting& to_child_setting( Setting &element, const int index ) 250 { 251 if( !element.isAggregate()) 252 ui_error( "it is not possible to index non-agregate element by integers", element ); 253 254 if( element.getLength() <= index ) 255 ui_error( "there is not any child with index " + index, element ); 256 257 return element[index]; 258 } 259 260 static Setting& to_child_setting( Setting &element, const string &name ) 261 { 262 ASSERT_UITYPE(element,TypeGroup); 263 if( !element.exists( name ) ) 264 ui_error( "there is not any child named """ + name, element ); 265 return element[name]; 266 } 267 268 //! This methods tries to build a new double matrix 269 static void from_setting( mat& matrix, const Setting &element ) 198 //! This methods tries to build a new templated array , 199 // efektivne jen pro vect, mat a string, pro dalsi je nutne pridat from_setting metodu.. ale to asi necceme 200 template<class T> static void from_setting( Array<T> &array_to_load, const Setting &element ) 270 201 { 271 202 const Link_Expander link_expander( element ); 272 203 const Setting &root = link_expander.root(); 273 204 274 if( root.isNumber() ) 275 { 276 matrix.set_size( 1, 1 ); 277 matrix(0,0) = root; 278 return; 279 } 280 281 if( root.isList() ) 282 { 283 if( root.getLength() != 3 ) 284 ui_error( "the setting supposed to represent a matrix element has wrong syntax", root ); 285 286 Setting &cols_setting = root[0]; 287 Setting &rows_setting = root[1]; 288 Setting &elements = root[2]; 289 290 ASSERT_UITYPE(cols_setting,TypeInt); 291 ASSERT_UITYPE(rows_setting,TypeInt); 292 ASSERT_UITYPE(elements,TypeArray); 293 294 int cols = cols_setting; 295 int rows = rows_setting; 296 297 if( cols < 0 | rows < 0 ) 298 ui_error( "the dimensions of a matrix has to be non-negative", root ); 299 300 if( elements.getLength() != cols * rows ) 301 ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements ); 302 303 matrix.set_size( rows, cols ); 304 305 if( cols == 0 || rows == 0 ) 306 return; 307 308 if( !elements[0].isNumber() ) 309 ui_error( "matrix elements have to be numbers", elements[0] ); 310 311 // build matrix row-wise 312 int k = 0; 313 for( int i=0;i<rows;i++ ) 314 for( int j=0; j<cols; j++) 315 matrix(i,j) = elements[k++]; 316 return; 317 } 318 319 ui_error( "only numeric types or TypeList are supported as matrix values", root ); 320 } 321 322 //! This methods tries to save a double matrix 323 static void to_setting( const mat &matrix, Setting &root ) 324 { 325 Setting &cols = root.add( Setting::TypeInt ); 326 cols = matrix.cols(); 327 328 Setting &rows = root.add( Setting::TypeInt ); 329 rows = matrix.rows(); 330 331 Setting &elements = root.add( Setting::TypeArray ); 332 333 // build matrix row-wise 334 for( int i=0; i<matrix.rows(); i++ ) 335 for( int j=0; j<matrix.cols(); j++) 336 { 337 Setting &newField = elements.add(Setting::TypeFloat); 338 newField = matrix(i,j); 339 } 340 } 341 342 //! This methods tries to build a new integer vector 343 static void from_setting( ivec &vec, const Setting &element ) 344 { 345 const Link_Expander link_expander( element ); 346 const Setting &root = link_expander.root(); 347 348 if( root.isNumber() ) 349 { 350 ASSERT_UITYPE(root,TypeInt); 351 vec.set_length( 1 ); 352 vec(0) = root; 353 return; 354 } 355 356 if( root.isList() ) 357 { 358 if( root.getLength() != 3 ) 359 ui_error( "the setting supposed to represent a matrix element has wrong syntax", root ); 360 361 Setting &cols_setting = root[0]; 362 Setting &rows_setting = root[1]; 363 Setting &elements = root[2]; 364 365 ASSERT_UITYPE(cols_setting,TypeInt); 366 ASSERT_UITYPE(rows_setting,TypeInt); 367 ASSERT_UITYPE(elements,TypeArray); 368 369 int cols = cols_setting; 370 int rows = rows_setting; 371 372 if( cols < 0 | rows < 0) 373 ui_error( "the dimensions of a matrix has to be non-negative", root ); 374 375 if( elements.getLength() != cols * rows ) 376 ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements ); 377 378 if( cols != 1 & rows !=1) 379 ui_error( "the vector length is invalid, it seems to be rather a matrix", elements ); 380 381 int len = rows * cols; 382 vec.set_length ( len ); 383 if( len == 0 ) return; 384 385 ASSERT_UITYPE(elements[0],TypeInt); 386 for( int i=0; i<len; i++ ) 387 vec(i) = elements[i]; 388 return; 389 } 390 391 if( root.isArray() ) 392 { 393 int len = root.getLength(); 394 vec.set_length( len ); 395 if( len == 0 ) return; 396 397 ASSERT_UITYPE(root[0],TypeInt); 398 for( int i=0; i < len; i++ ) 399 vec(i) = root[i]; 400 return; 401 } 402 403 ui_error( "only numeric types, TypeArray or TypeList are supported as vector values", root ); 404 } 405 406 //! This methods tries to save an integer vector 407 static void to_setting( const ivec &vec, Setting &root ) 408 { 409 for( int i=0; i<vec.length(); i++ ) 410 { 411 Setting &newField = root.add(Setting::TypeInt); 412 newField = vec(i); 413 } 414 } 415 416 //! This methods tries to build a new array of strings 417 static void from_setting( Array<string> &string_array, const Setting &element ) 418 { 419 const Link_Expander link_expander( element ); 420 const Setting &root = link_expander.root(); 421 422 if( root.getType() == Setting::TypeString ) 423 { 424 string_array.set_length( 1 ); 425 string_array(0) = (string)root; 426 return; 427 } 428 429 if( root.isArray() ) 430 { 431 int len = root.getLength(); 432 string_array.set_length( len ); 433 if( len == 0 ) return; 434 435 ASSERT_UITYPE(root[0],TypeString); 436 for( int i=0; i < len; i++ ) 437 string_array(i) = (string)root[i]; 438 return; 439 } 440 441 ui_error( "only TypeString or TypeArray are supported as vector of string values", root ); 442 } 443 444 //! This methods tries to save an array of strings 445 static void to_setting( const Array<string> &string_array, Setting &root ) 446 { 447 for( int i=0; i<string_array.length(); i++ ) 448 { 449 Setting &newField = root.add(Setting::TypeString); 450 newField = string_array(i); 451 } 205 ASSERT_UITYPE(root,TypeList); 206 207 int len = root.getLength(); 208 array_to_load.set_length( len ); 209 if( len == 0 ) return; 210 211 for( int i=0; i < len; i++ ) 212 from_setting( array_to_load(i), root[i] ); 452 213 } 453 214 454 215 protected: 455 456 216 //! default constructor 457 UI( const string& class_name ) : class_name ( class_name )217 UI( const string& class_name, const type_info * const class_type_info ) 458 218 { 459 Class_To_UI::add_class( class_name, this );219 Mapped_UI::add_class( class_name, class_type_info, this ); 460 220 } 461 221 … … 463 223 virtual ~UI(){}; 464 224 225 465 226 public: 466 467 227 static void ui_error( string message, const Setting &element ) 468 228 { … … 477 237 478 238 //! Prototype of a UI builder. Return value is by the second argument since it type checking via \c dynamic_cast. 479 template<class T> static T* build( Setting &element, const int index ) 480 { 481 return from_setting<T>( to_child_setting( element, index ) ); 482 } 483 484 template<class T> static T* build( Setting &element, const string &name ) 239 template<class T> static T* build( const Setting &element, const int index ) 240 { 241 T* instance; 242 from_setting<T>( reference_to_child_setting( element, index ) ); 243 return instance; 244 } 245 246 template<class T> static T* build( const Setting &element, const string &name ) 485 247 { 486 return from_setting<T>( to_child_setting( element, name ) ); 487 } 488 489 //! This methods tries to save an instance of type T (or some of its descendant types) 490 //! and build DOM tree accordingly. Then, it creates a new DOMNode named according class_name 491 //! and connecti it to the passed Setting as a new child node. 492 template<class T> static void save( T &instance, Setting &element, const string &name = "") 248 T* instance; 249 from_setting<T>( instance, reference_to_child_setting( element, name ) ); 250 return instance; 251 } 252 253 //! This methods tries to build a new double matrix 254 template<class T> static bool get( T &instance, const Setting &element, const string &name ) 255 { 256 const Setting *root = pointer_to_child_setting( element, name ); 257 if( !root ) return false; 258 from_setting( instance, *root ); 259 return true; 260 } 261 262 //! This methods tries to build a new double matrix 263 template<class T> static bool get( T &instance, const Setting &element, const int index ) 264 { 265 const Setting *root = pointer_to_child_setting( element, index ); 266 if( !root ) return false; 267 from_setting( instance, *root ); 268 return true; 269 } 270 271 //! This methods tries to build a new double matrix 272 template<class T> static bool get( Array<T> &array_to_load, const Setting &element, const string &name ) 273 { 274 const Setting *root = pointer_to_child_setting( element, name ); 275 if( !root ) return false; 276 from_setting( array_to_load, *root ); 277 return true; 278 } 279 280 //! This methods tries to build a new double matrix 281 template<class T> static bool get( Array<T> &array_to_load, const Setting &element, const int index ) 282 { 283 const Setting *root = pointer_to_child_setting( element, index ); 284 if( !root ) return false; 285 from_setting( array_to_load, *root ); 286 return true; 287 } 288 289 template< class T> static void save( const T * const instance, Setting &element, const string &name = "") 493 290 { 494 291 Setting &root = (name == "") ? element.add( Setting::TypeGroup ) 495 292 : element.add( name, Setting::TypeGroup ); 496 to_setting( instance, root ); 497 } 498 499 //! This methods tries to build a new double matrix 500 static bool get( mat& matrix, const Setting &element, const string &name ) 501 { 502 const Setting *root = to_child_setting( element, name ); 503 if( !root ) return false; 504 from_setting( matrix, *root ); 505 return true; 506 } 507 508 //! This methods tries to build a new double matrix 509 static bool get( mat& matrix, const Setting &element, const int index ) 510 { 511 const Setting *root = to_child_setting( element, index ); 512 if( !root ) return false; 513 from_setting( matrix, *root ); 514 return true; 515 } 293 294 const string &class_name = Mapped_UI::retrieve_class_name( &typeid(*instance) ); 295 296 // add attribute "class" 297 Setting &type = root.add( "class", Setting::TypeString ); 298 type = class_name; 299 300 try 301 { 302 instance->to_setting( root ); 303 } 304 catch(SettingException xcptn) 305 { 306 it_error ( "UI error: the method " + class_name + ".to_setting(Setting&) has thrown an exception when filling the setting " + xcptn.getPath() + ". Try to correct this method." ); 307 } 308 } 309 310 //! This methods tries to save a double vec 311 template<class T> static void save( const Array<T> &array_to_save, Setting &element, const string &name = "" ) 312 { 313 ASSERT_UITYPE(element,TypeGroup); 314 Setting &list = (name == "") ? element.add( Setting::TypeList ) 315 : element.add( name, Setting::TypeList ); 316 for( int i=0; i<array_to_save.length(); i++ ) 317 save( array_to_save(i), list ); 318 } 319 516 320 517 321 //! This methods tries to save a double matrix 518 static void save( mat &matrix, Setting &element, const string &name = "" ) 519 { 520 Setting &root = (name == "") ? element.add( Setting::TypeList ) 521 : element.add( name, Setting::TypeList ); 522 to_setting( matrix, root ); 523 } 524 525 //! This methods tries to build a new double vec 526 static bool get( ivec& vec, const Setting &element, const string &name ) 527 { 528 const Setting *root = to_child_setting( element, name ); 529 if( !root ) return false; 530 from_setting( vec, *root ); 531 return true; 532 } 533 534 //! This methods tries to build a new double vec 535 static bool get( ivec& vec, const Setting &element, const int index ) 536 { 537 const Setting *root = to_child_setting( element, index ); 538 if( !root ) return false; 539 from_setting( vec, *root ); 540 return true; 541 } 322 static void save( const mat &matrix, Setting &element, const string &name = "" ); 542 323 543 324 //! This methods tries to save a double vec 544 static void save( ivec &vec, Setting &element, const string &name = "" ) 545 { 546 Setting &root = (name == "") ? element.add( Setting::TypeArray ) 547 : element.add( name, Setting::TypeArray ); 548 to_setting( vec, root ); 549 } 550 551 //! This methods tries to build a new double string_array 552 static bool get( Array<string> &string_array, const Setting &element, const string &name ) 553 { 554 const Setting *root = to_child_setting( element, name ); 555 if( !root ) return false; 556 from_setting( string_array, *root ); 557 return true; 558 } 559 560 //! This methods tries to build a new double string_array 561 static bool get( Array<string> &string_array, const Setting &element, const int index ) 562 { 563 const Setting *root = to_child_setting( element, index ); 564 if( !root ) return false; 565 from_setting( string_array, *root ); 566 return true; 567 } 568 569 //! This methods tries to save a double string_array 570 static void save( Array<string> &string_array, Setting &element, const string &name = "" ) 571 { 572 Setting &root = (name == "") ? element.add( Setting::TypeArray ) 573 : element.add( name, Setting::TypeArray ); 574 to_setting( string_array, root ); 575 } 325 static void save( const ivec &vec, Setting &element, const string &name = "" ); 326 327 private: 328 //! This methods tries to save a double vec 329 static void save( const string &str, Setting &element); 330 576 331 }; 577 332 … … 588 343 589 344 //! default constructor, which is intentionally declared as private 590 Particular_UI<T>( const string &class_name) : UI( class_name )345 Particular_UI<T>( const string &class_name) : UI( class_name, &typeid(T) ) 591 346 { 592 347 }; … … 596 351 static Particular_UI<T>& ui; 597 352 598 bdmroot* new_instance() 353 bdmroot* new_instance() const 599 354 { 600 355 return new T(); 601 356 } 602 357 }; 358 359 603 360 604 361 -
tests/UI/testUI.cpp
r345 r351 1 2 #include <string> 3 1 4 #include <user_info.h> 2 #include <string>3 5 4 6 using std::string; … … 6 8 using namespace bdm; 7 9 10 class Passenger : public bdmroot 11 { 12 public: 13 14 Passenger() 15 { 16 } 17 }; 18 19 class Human : public Passenger 20 { 21 public: 22 string name; 23 24 Human() 25 { 26 name = "none"; 27 } 28 29 virtual void from_setting( const Setting &root ) 30 { 31 root.lookupValue( "name", name ); 32 } 33 34 virtual void to_setting( Setting &root ) const 35 { 36 Setting &name_setting = root.add("name", Setting::TypeString ); 37 name_setting = name; 38 } 39 40 string ToString() 41 { 42 return name; 43 } 44 }; 45 46 UIREGISTER(Human); 47 48 class Robot : public Passenger 49 { 50 public: 51 int number; 52 Array<string> software; 53 54 Robot() : software() 55 { 56 number = -1; 57 } 58 59 virtual void from_setting( const Setting &root ) 60 { 61 root.lookupValue( "number", number ); 62 63 UI::get( software, root, "software" ); 64 } 65 66 virtual void to_setting( Setting &root ) const 67 { 68 Setting &number_setting = root.add("number", Setting::TypeInt ); 69 number_setting = number; 70 71 UI::save( software, root, "software" ); 72 } 73 74 string ToString() 75 { 76 stringstream stream; 77 stream << number; 78 for( int i = 0; i<software.length(); i++) 79 stream << "_" + software(i); 80 return stream.str(); 81 } 82 }; 83 84 UIREGISTER(Robot); 85 8 86 class Transport : public bdmroot 9 87 { … … 29 107 } 30 108 31 virtual void to_setting( Setting &root ) 109 virtual void to_setting( Setting &root ) const 32 110 { 33 111 Setting &year_setting = root.add("year", Setting::TypeInt ); … … 43 121 public: 44 122 int kilometers; 123 Array<Passenger*> passengers; 45 124 46 125 Car() : Transport() … … 60 139 61 140 root.lookupValue( "kilometers", kilometers ); 62 } 63 64 virtual void to_setting( Setting &root ) 141 142 UI::get( passengers, root, "passengers" ); 143 } 144 145 virtual void to_setting( Setting &root ) const 65 146 { 66 147 Transport::to_setting( root ); … … 68 149 Setting &kilometers_setting = root.add("kilometers", Setting::TypeInt ); 69 150 kilometers_setting = kilometers; 151 152 UI::save( passengers, root, "passengers" ); 70 153 } 71 154 … … 73 156 { 74 157 stringstream stream; 75 stream << "a car made in " << year << " by " << manufacturer << ", having " << kilometers << " kilometers on the clock."; 158 stream << "A car made in " << year << " by " << manufacturer << ", having " << kilometers << " kilometers on the clock."; 159 if( passengers.length() ) 160 { 161 stream << "The names of passengers are as follows: "; 162 for( int i=0; i<passengers.length(); i++) 163 stream << passengers(i)->ToString() << " "; 164 } 76 165 return stream.str(); 77 166 } … … 109 198 } 110 199 111 void to_setting( Setting &root ) 200 void to_setting( Setting &root ) const 112 201 { 113 202 Transport::to_setting( root ); … … 132 221 int main() 133 222 { 223 //////////////////////////////////// LOADING //////////////////////////////// 224 UI_File in("testUI_in.cfg"); 225 in.load(); 226 Transport *pepikovo = UI::build<Transport>( in, "pepikovo"); 227 cout << "pepikovo: " << pepikovo->ToString() << endl; 228 Transport *jardovo = UI::build<Transport>( in, "jardovo"); 229 cout << "jardovo: " << jardovo->ToString() << endl; 230 Transport *ondrejovo = UI::build<Transport>( in, "ondrejovo"); 231 cout << "ondrejovo: " << ondrejovo->ToString() << endl; 232 Transport *elisky = UI::build<Transport>( in, "elisky"); 233 cout << "elisky: " << elisky->ToString() << endl; 234 Transport *kati = UI::build<Transport>( in, "kati"); 235 cout << "kati: " << kati->ToString() << endl; 236 getchar(); 237 134 238 /////////////////////////////////// SAVING ////////////////////////// 135 /* 136 Car audi( 1998, "audi", 25000); 137 Car liaz( 1992, "liaz", 1555000); 138 Bike author( 1996, "author", true ); 139 140 UI_File root("testUI.cfg"); 141 UI::save( audi, root, "pepikovo"); 142 UI::save( liaz, root, "jardovo"); 143 UI::save( author, root, "ondrejovo"); 144 root.save(); 239 240 Car audi( 1968, "zyl", 200); 241 Car liaz( 1989, "skoda", 1000); 242 Bike author( 2001, "noname", false ); 243 UI_File out("testUI_out.cfg"); 244 245 UI::save( &audi, out, "marty"); 246 UI::save( &liaz, out, "bohousovo"); 247 UI::save( &author, out, "karlovo"); 248 UI::save( pepikovo, out, "pepikovo"); 249 out.save(); 145 250 146 251 cout << "all the transport means were saved correctly" << endl; 147 252 getchar(); 148 */149 150 //////////////////////////////////// LOADING ////////////////////////////////151 UI_File root("testUI.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 253 return 0; 165 254 }