- Timestamp:
- 08/05/09 00:01:58 (15 years ago)
- Location:
- library
- Files:
-
- 1 added
- 25 modified
Legend:
- Unmodified
- Added
- Removed
-
library/Doxyfile
r397 r471 522 522 # by doxygen. Possible values are YES and NO. If left blank NO is used. 523 523 524 QUIET = NO524 QUIET = YES 525 525 526 526 # The WARNINGS tag can be used to turn on/off the warning messages that are … … 564 564 # to stderr. 565 565 566 WARN_LOGFILE = 566 WARN_LOGFILE = .\doxy_warnings.txt 567 567 568 568 #--------------------------------------------------------------------------- -
library/bdm/base/bdmbase.cpp
r462 r471 173 173 } 174 174 175 void mpdf::from_setting(const Setting &set){ 176 if (set.exists("rv")) { 177 RV *r = UI::build<RV>(set, "rv");178 set_rv(*r);179 delete r;175 void mpdf::from_setting(const Setting &set){ 176 RV *r = UI::build<RV>(set, "rv"); 177 if (r) { 178 set_rv(*r); 179 delete r; 180 180 } 181 181 182 if (set.exists("rvc")) { 183 RV *r = UI::build<RV>(set, "rvc");184 set_rvc(*r);185 delete r;182 r = UI::build<RV>(set, "rvc"); 183 if (r) { 184 set_rvc(*r); 185 delete r; 186 186 } 187 187 } … … 281 281 { 282 282 Array<string> A; 283 if( set.exists("names")) 284 UI::get( A, set, "names" ); 285 else 283 if( !UI::get( A, set, "names" ) ) 286 284 A.set_length(0); 287 285 288 286 ivec szs; 289 if( set.exists("sizes")) 290 UI::get(szs,set,"sizes"); 291 else 287 if( !UI::get(szs,set,"sizes") ) 292 288 szs = ones_i(A.length()); 293 289 294 290 ivec tms; 295 if( set.exists( "times") ) 296 UI::get(tms,set,"times"); 297 else 291 if( !UI::get(tms,set,"times") ) 298 292 tms = zeros_i(A.length()); 299 293 … … 302 296 } 303 297 304 /*void RV::to_setting( Setting &set ) const305 {306 Transport::to_setting( set );307 308 Setting &kilometers_setting = set.add("kilometers", Setting::TypeInt );309 kilometers_setting = kilometers;310 311 UI::save( passengers, set, "passengers" );312 }*/313 314 298 RV concat ( const RV &rv1, const RV &rv2 ) { 315 299 RV pom = rv1; … … 322 306 323 307 void mepdf::from_setting(const Setting &set) { 324 shared_ptr<epdf> e(UI::build<epdf>(set, "epdf"));308 shared_ptr<epdf> e(UI::build<epdf>(set, "epdf", UI::compulsory)); 325 309 set_ep(e); 326 310 } -
library/bdm/base/bdmbase.h
r462 r471 330 330 //!@} 331 331 void from_setting(const Setting &set){ 332 if (set.exists("rv")){333 RV* r = UI::build<RV>(set,"rv");332 RV* r = UI::build<RV>(set,"rv"); 333 if (r){ 334 334 set_rv(*r); 335 335 delete r; -
library/bdm/base/datasources.cpp
r384 r471 56 56 void ArxDS::from_setting( const Setting &set ) 57 57 { 58 RV *yrv = UI::build<RV>( set, "y" );59 RV *urv = UI::build<RV>( set, "u" );60 RV *rrv = UI::build<RV>( set, "rgr" );58 RV *yrv = UI::build<RV>( set, "y" , UI::compulsory); 59 RV *urv = UI::build<RV>( set, "u" , UI::compulsory); 60 RV *rrv = UI::build<RV>( set, "rgr" , UI::compulsory); 61 61 62 62 mat Th; 63 UI::get( Th, set, "theta" );63 UI::get( Th, set, "theta", UI::compulsory ); 64 64 65 65 vec mu0; 66 if( set.exists( "offset" )) 67 UI::get( mu0, set, "offset" ); 68 else 66 if( !UI::get( mu0, set, "offset" ) ) 69 67 mu0= zeros( yrv->_dsize() ); 70 68 71 69 mat sqR; 72 UI::get( sqR, set, "r" );70 UI::get( sqR, set, "r", UI::compulsory ); 73 71 set_parameters(Th,mu0,sqR); 74 72 set_drv(*yrv,*urv,*rrv); … … 77 75 set_options(set["opt"]); 78 76 } 79 80 /*void ArxDS::to_setting( Setting &set ) const81 {82 Transport::to_setting( set );83 84 Setting &kilometers_setting = set.add("kilometers", Setting::TypeInt );85 kilometers_setting = kilometers;86 87 UI::save( passengers, set, "passengers" );88 }*/89 90 77 91 78 CsvFileDS::CsvFileDS ( const string& fname, const string& orientation ) :FileDS() { … … 125 112 void ITppFileDS::from_setting( const Setting &set ) 126 113 { 127 RV* rvtmp = UI::build<RV>(set, "rv" );114 RV* rvtmp = UI::build<RV>(set, "rv" , UI::compulsory); 128 115 129 116 it_file it ( set["filename"] ); … … 136 123 } 137 124 138 /*void ITppFileDS::to_setting( Setting &set ) const139 {140 Transport::to_setting( set );141 142 Setting &kilometers_setting = set.add("kilometers", Setting::TypeInt );143 kilometers_setting = kilometers;144 145 UI::save( passengers, set, "passengers" );146 }*/147 148 125 void stateDS::from_setting( const Setting &set ) 149 126 { 150 IM = UI::build<mpdf>(set, "IM" );151 OM = UI::build<mpdf>(set, "OM" );127 IM = UI::build<mpdf>(set, "IM", UI::compulsory); 128 OM = UI::build<mpdf>(set, "OM", UI::compulsory); 152 129 153 130 dt.set_length( OM->dimension() ); … … 155 132 ut.set_length(0); 156 133 157 RV* rvtmp = UI::build<RV>(set["IM"], "rvu" );134 RV* rvtmp = UI::build<RV>(set["IM"], "rvu", UI::compulsory); 158 135 //set_drv(rvtmp); 159 136 } 160 161 /*void stateDS::to_setting( Setting &set ) const162 {163 Transport::to_setting( set );164 165 Setting &kilometers_setting = set.add("kilometers", Setting::TypeInt );166 kilometers_setting = kilometers;167 168 UI::save( passengers, set, "passengers" );169 }*/170 171 -
library/bdm/base/loggers.cpp
r384 r471 33 33 maxlen = set["maxlen"]; 34 34 } 35 36 /*void memlog::to_setting( Setting &set ) const37 {38 Transport::to_setting( set );39 40 Setting &kilometers_setting = set.add("kilometers", Setting::TypeInt );41 kilometers_setting = kilometers;42 43 UI::save( passengers, set, "passengers" );44 }*/45 35 46 36 void dirfilelog::init() { … … 167 157 } 168 158 169 /*void dirfilelog::to_setting( Setting &set ) const170 {171 Transport::to_setting( set );172 173 Setting &kilometers_setting = set.add("kilometers", Setting::TypeInt );174 kilometers_setting = kilometers;175 176 UI::save( passengers, set, "passengers" );177 }*/178 179 180 181 159 } -
library/bdm/base/user_info.cpp
r451 r471 176 176 throw UIException( "only TypeList elements could be indexed by integers", element ); 177 177 178 if ( element.getLength() <= index )179 throw UIException( "there is not any child with index " + index, element );180 181 178 return element[index]; 182 179 } … … 186 183 if ( !element.isGroup()) 187 184 throw UIException( "only TypeGroup elements could be indexed by strings", element ); 188 189 if ( !element.exists( name ) )190 throw UIException( "there is not any child named """ + name, element );191 185 192 186 return element[name]; -
library/bdm/base/user_info.h
r417 r471 1 1 /*! 2 2 \file 3 \brief UI (user info) class for loading/saving objects from/to configuration files. 3 \brief UI (user info) class for loading/saving objects from/to configuration files. 4 4 It is designed with use of libconfig C/C++ Configuration File Library 5 \ref ui_page 5 6 \author Vaclav Smidl. 6 7 … … 30 31 using namespace libconfig; 31 32 32 namespace bdm 33 { 34 35 /*! 36 \def UIREGISTER(class_name) 37 \brief Macro for registration of class into map of user-infos, registered class is scriptable using UI static methods 38 39 Argument \a class_name has to be a descendant of root class and also, it has to have parameterless constructor prepared. 40 This macro should be used in header file, immediately after a class declaration. 41 42 \sa TODO MODUL 43 */ 44 #ifndef BDMLIB 45 #define UIREGISTER(class_name) template<> const ParticularUI<class_name>& ParticularUI<class_name>::factory = ParticularUI<class_name>(#class_name) 46 #else 47 #define UIREGISTER(class_name) 48 #endif 33 namespace bdm { 49 34 50 35 //! Exception prepared for reporting user-info errors which are always related to some concrete Setting path 51 class UIException : public std::exception 52 { 53 private: 36 //! 37 //! \ref ui_page 38 class UIException : public std::exception { 39 40 public: 54 41 //! Error message 55 42 const string message; 56 43 57 public: 44 //! Path to the problematic setting 45 const string path; 46 58 47 //! Use this constructor when you can pass the problematical Setting as a parameter 59 UIException( const string &message, const Setting &element ) 60 : message( "UI error: " + message + ". Check path \"" + string(element.getPath()) + "\"." ) 61 { 48 UIException ( const string &message, const Setting &element ) 49 : message ( "UI error: " + message + "." ), path ( "Check path \"" + string ( element.getPath() ) + "\"." ) { 62 50 } 63 51 64 52 //! This constructor is for other occasions, when only path of problematical Setting is known 65 UIException( const string &message, const string &path ) 66 : message( "UI error: " + message + "! Check path \"" + path + "\"." ) 67 { 53 UIException ( const string &message, const string &path ) 54 : message ( "UI error: " + message + "." ), path ( "Check path \"" + path + "\"." ) { 68 55 } 69 56 70 57 //! Overriden method for reporting an error message 71 virtual const char* what() const throw() 72 { 73 return message.c_str(); 58 virtual const char* what() const throw() { 59 return ( message + " " + path ).c_str(); 74 60 } 75 61 ~UIException() throw() {}; … … 78 64 79 65 /*! 80 @brief This class serves to load and/or save user-infos into/from 66 @brief This class serves to load and/or save user-infos into/from 81 67 configuration files stored on a hard-disk. 82 68 83 Firstly, save some user-infos into the new UIFile instance. Then, 69 Firstly, save some user-infos into the new UIFile instance. Then, 84 70 call the save method with a filename as its only argument: 85 71 … … 91 77 \endcode 92 78 93 In the other way round, when loading object from a configuration file, 79 In the other way round, when loading object from a configuration file, 94 80 the appropriate code looks like this: 95 81 … … 98 84 CAudi *audi = UI::build<CAudi>(file,"TT"); 99 85 \endcode 86 87 \ref ui_page 100 88 */ 101 class UIFile : public Config 102 { 89 class UIFile : public Config { 103 90 public: 104 91 //! Create empty file instance prepared to store Settings … … 106 93 107 94 //! Creates instance and fills it from the configuration file file_name 108 UIFile ( const string &file_name );95 UIFile ( const string &file_name ); 109 96 110 97 //! Save all the stored Settings into the configuration file file_name 111 void save (const string &file_name);98 void save ( const string &file_name ); 112 99 113 100 //! This operator allows the ability of substituting Setting parameter by UIFile instance … … 116 103 117 104 /*! 118 @brief This class serves to expand links used within configuration files. 105 @brief This class serves to expand links used within configuration files. 119 106 120 107 Value of any type but string can be linked to some other value of the same type 121 108 defined elsewhere in the current configuration file or even in some different 122 configuration file. 123 124 Link have three parts, \<name\> : \<path\> \<\@filename\>. Field \<name\> contains the 109 configuration file. 110 111 Link have three parts, \<name\> : \<path\> \<\@filename\>. Field \<name\> contains the 125 112 name of the new setting, \<path\> is the relative path to the referenced setting, which 126 has to be taken from the %root Setting element. The last part \<\@filename\> is optional, 113 has to be taken from the %root Setting element. The last part \<\@filename\> is optional, 127 114 it contains filename in the case the link should refer to a variable stored in a different 128 115 file. From the previous part \<path\>, it has to be separated by '@'. … … 130 117 \code 131 118 ... 132 jardovo : 119 jardovo : 133 120 { 134 121 class = "Car"; … … 137 124 kilometers = 1555000; 138 125 }; 139 ondrejovo : 126 ondrejovo : 140 127 { 141 128 class = "Bike"; … … 145 132 matr = ( 2, 2, [ 1.0, 0.0, 0.0, 1.0 ] ); 146 133 }; 147 148 #this is the example of local link to another mean of transport 134 135 #this is the example of local link to another mean of transport 149 136 elisky = "jardovo"; 150 137 151 138 ... 152 139 153 # and this link is external link pointing tofile "other_cars.cfg" stored in the154 # same directory , in that file, it refers to the local Setting "magic_cars.skubankovo"140 # And this link is external link pointing to the file "other_cars.cfg" stored in the 141 # same directory. In that file, it refers to the local Setting "magic_cars.skubankovo". 155 142 kati = "magic_cars.skubankovo@other_cars.cfg"; 156 143 … … 172 159 \endcode 173 160 174 The whole point is that a resolved link (class member #result, i.e., "link.result" in the previous example) could point 161 The whole point is that a resolved link (class member #result, i.e., "link.result" in the previous example) could point 175 162 into a different configuration file. In that case there has to be an UIFile instance managing reading from this 176 file. As the libconfig::Config deletes all its Settings when dealocated, UIFile must not be dealocated until all 177 the necessary operation on the linked Setting are finished (otherwise, the link #result would be invalid just after 178 the UIFile dealocation). And that is exactly the mechanism implemented within SettingResolver class. It assures, 163 file. As the libconfig::Config deletes all its Settings when dealocated, UIFile must not be dealocated until all 164 the necessary operation on the linked Setting are finished (otherwise, the link #result would be invalid just after 165 the UIFile dealocation). And that is exactly the mechanism implemented within SettingResolver class. It assures, 179 166 that the #result Setting reference is valid within the scope of SettingResolver instance. 167 168 \ref ui_page 180 169 */ 181 class SettingResolver : root 182 { 170 class SettingResolver : root { 183 171 private: 184 172 //! If necessary, this pointer stores an addres of an opened UIFile, else it equals NULL … … 187 175 //! This method initialize #result reference, i.e., it executes the main code of SettingResolver class 188 176 //! 189 //! This code could be also located directly in constructor. The only reason why we made this 177 //! This code could be also located directly in constructor. The only reason why we made this 190 178 //! method is the keyword 'const' within the declaration of #result reference . Such a reference 191 179 //! have to be intialized before any other constructor command, exactly in the way it is implemented now. 192 const Setting &initialize_reference ( UIFile* &file, const Setting &potential_link);180 const Setting &initialize_reference ( UIFile* &file, const Setting &potential_link ); 193 181 194 182 public: … … 197 185 198 186 //! If potential_link contains a link to some other setting, it is resolved here. Anyway, the Setting reference #result is prepared for use. 199 SettingResolver ( const Setting &potential_link );200 187 SettingResolver ( const Setting &potential_link ); 188 201 189 //! An opened UIFile file is closed here if necessary. 202 ~SettingResolver(); 190 ~SettingResolver(); 203 191 }; 204 192 205 193 /*! 206 @brief UI is an abstract class and it is intended for internal purposes only 207 208 This class exists mainly to allow pointers to its templated descendant ParticularUI<T>. Next, 209 it collects all the auxiliary functions useful to prepare some concret user-infos, see static 210 methods 'build', 'get' and 'save'. 194 @brief UI is an abstract class which collects all the auxiliary functions useful to prepare some concrete 195 user-infos. 196 197 See static methods 'build', 'get' and 'save'. Writing user-infos with these methods is rather simple. The 198 rest of this class is intended for internal purposes only. Its meaning is to allow pointers to its templated 199 descendant ParticularUI<T>. 200 201 \ref ui_page 211 202 */ 212 class UI 213 { 203 class UI { 214 204 private: 215 205 //! Class with state shared across all its instances ("monostate"), encapsulating two maps, one mapping names to UI instances and the other mapping type_infos to class names 216 //! 206 //! 217 207 //! The key property of this class is that it initializes the internal maps on global init, 218 //! before the instance is used for a first time. Therefore, we do not have to care about initialization 208 //! before the instance is used for a first time. Therefore, we do not have to care about initialization 219 209 //! during a call of UIREGISTER macro operating with both these mappings. 220 class MappedUI 221 { 210 class MappedUI { 222 211 private: 223 212 //! Type definition of mapping which transforms class names to the related UI instances … … 234 223 235 224 //! Method for reporting a error when an attempt to operate with an unregistered class occures 236 static void unregistered_class_error ( const string &unregistered_class_name );225 static void unregistered_class_error ( const string &unregistered_class_name ); 237 226 238 227 public: 239 228 //! Add a pair key-userinfo into the internal map 240 static void add_class ( const string &class_name, const type_info * const class_type_info, const UI* const ui );229 static void add_class ( const string &class_name, const type_info * const class_type_info, const UI* const ui ); 241 230 242 231 //! Search for an userinfo related to the passed class name within the internal map 243 static const UI& retrieve_ui ( const string &class_name );232 static const UI& retrieve_ui ( const string &class_name ); 244 233 245 234 //! Search for an class name related to the passed type_info within the internal map 246 static const string& retrieve_class_name ( const type_info* const class_type_info );235 static const string& retrieve_class_name ( const type_info* const class_type_info ); 247 236 }; 248 237 249 238 //! Function assertting that the setting element is of the SettingType type 250 static void assert_type ( const Setting &element, Setting::Type type);239 static void assert_type ( const Setting &element, Setting::Type type ); 251 240 252 241 //! Method assembling a typeless instance, it is implemented in descendant class ParticularUI<T> 253 242 virtual root* new_instance() const = 0; 254 255 //! Method switching from the \a element to its child Setting according the passed \a index, it also does all the necessary error-checking 256 static const Setting& to_child_setting ( const Setting &element, const int index );257 258 //! Method switching from the \a element to its child Setting according the passed \a name, it also does all the necessary error-checking 259 static const Setting& to_child_setting ( const Setting &element, const string &name );260 261 //! This method converts a Setting into a matrix 262 static void from_setting ( mat& matrix, const Setting &element );243 244 //! Method switching from the \a element to its child Setting according the passed \a index, it also does all the necessary error-checking 245 static const Setting& to_child_setting ( const Setting &element, const int index ); 246 247 //! Method switching from the \a element to its child Setting according the passed \a name, it also does all the necessary error-checking 248 static const Setting& to_child_setting ( const Setting &element, const string &name ); 249 250 //! This method converts a Setting into a matrix 251 static void from_setting ( mat& matrix, const Setting &element ); 263 252 //! This method converts a Setting into an integer vector 264 static void from_setting ( ivec &vector, const Setting &element );253 static void from_setting ( ivec &vector, const Setting &element ); 265 254 //! This method converts a Setting into a string 266 static void from_setting ( string &str, const Setting &element );255 static void from_setting ( string &str, const Setting &element ); 267 256 //! This method converts a Setting into a real vector 268 static void from_setting ( vec &vector, const Setting &element );269 //! This method converts a Setting into a integer scalar 270 static void from_setting ( int &integer, const Setting &element );271 //! This method converts a Setting into a real scalar 272 static void from_setting ( double &real, const Setting &element );257 static void from_setting ( vec &vector, const Setting &element ); 258 //! This method converts a Setting into a integer scalar 259 static void from_setting ( int &integer, const Setting &element ); 260 //! This method converts a Setting into a real scalar 261 static void from_setting ( double &real, const Setting &element ); 273 262 //! This method converts a Setting into a class T descendant 274 template<class T> static void from_setting( T* &instance, const Setting &element ) 275 { 276 const SettingResolver link( element ); 277 assert_type(link.result,Setting::TypeGroup); 278 279 // we get a value stored in the "class" attribute 263 template<class T> static void from_setting ( T* &instance, const Setting &element ) { 264 const SettingResolver link ( element ); 265 assert_type ( link.result, Setting::TypeGroup ); 266 267 // we get a value stored in the "class" attribute 280 268 string class_name; 281 if ( !link.result.lookupValue( "class", class_name ) )282 throw UIException ( "the obligatory \"class\" identifier is missing", link.result );283 269 if ( !link.result.lookupValue ( "class", class_name ) ) 270 throw UIException ( "the obligatory \"class\" identifier is missing", link.result ); 271 284 272 // then we find a user-info related to this type 285 const UI& related_UI = MappedUI::retrieve_ui ( class_name );286 273 const UI& related_UI = MappedUI::retrieve_ui ( class_name ); 274 287 275 root* typeless_instance = related_UI.new_instance(); 288 276 289 instance = dynamic_cast<T*>(typeless_instance); 290 if (!instance) 291 throw UIException( "class " + class_name + " is not a descendant of the desired output class. Try to call the UI::build<T> function with a different type parameter.", link.result ); 292 293 try 294 { 295 instance->from_setting( link.result ); 277 instance = dynamic_cast<T*> ( typeless_instance ); 278 if ( !instance ) 279 throw UIException ( "class " + class_name + " is not a descendant of the desired output class. Try to call the UI::build<T> function with a different type parameter.", link.result ); 280 281 try { 282 instance->from_setting ( link.result ); 283 } catch ( SettingException sttng_xcptn ) { 284 string msg = "the method " + class_name + ".from_setting(Setting&) has thrown a SettingException. Try to correct this method. Check path \"" + sttng_xcptn.getPath() + "\"."; 285 throw exception ( msg.c_str() ); 286 } catch ( UIException uixcptn ) { 287 string msg = "the method " + class_name + ".from_setting(Setting&) has thrown an UIException \"" + uixcptn.message + "\" Try to correct this method. Check path \"" + uixcptn.path + "\"."; 288 throw exception ( msg.c_str() ); 289 } catch ( exception xcptn ) { 290 string msg = "the method " + class_name + ".from_setting(Setting&) has thrown a general exception \"" + xcptn.what() + "\" Try to correct this method. Check path \"" + element.getPath() + "\"."; 291 throw exception ( msg.c_str() ); 296 292 } 297 catch(SettingException xcptn) 298 { 299 throw UIException( "the method " + class_name + ".from_setting(Setting&) has thrown an SettingException. Try to correct this method", xcptn.getPath()); 300 } 301 } 293 } 302 294 303 295 //! This methods converts a Setting into a new templated array of type Array<T> 304 template<class T> static void from_setting( Array<T> &array_to_load, const Setting &element ) 305 { 306 const SettingResolver link( element ); 307 308 assert_type(link.result,Setting::TypeList); 296 template<class T> static void from_setting ( Array<T> &array_to_load, const Setting &element ) { 297 const SettingResolver link ( element ); 298 299 assert_type ( link.result, Setting::TypeList ); 309 300 310 301 int len = link.result.getLength(); 311 array_to_load.set_length( len ); 312 if( len == 0 ) return; 313 314 for( int i=0; i < len; i++ ) 315 from_setting( array_to_load(i), link.result[i] ); 316 } 302 array_to_load.set_length ( len ); 303 if ( len == 0 ) return; 304 305 for ( int i = 0; i < len; i++ ) 306 from_setting ( array_to_load ( i ), link.result[i] ); 307 } 308 309 //! This is dummy version of the from_setting method for other, unsupported types. It just throws an exception. 310 //! 311 //! At the moment, this is the only way how to compile the library without obtaining the compiler error c2665. 312 //! The exception can help to find the place where the template is misused and also to correct it. 313 template<class T> static void from_setting ( T &array_to_load, const Setting &element ) { 314 throw UIException( "from_setting is not implemented for this type", element ); 315 } 316 317 317 318 318 protected: 319 319 //! Default constructor for internal use only, see \sa ParticularUI<T> 320 UI( const string& class_name, const type_info * const class_type_info ) 321 { 322 MappedUI::add_class( class_name, class_type_info, this ); 323 } 324 325 public: 326 327 //! \name Initialization of classes 320 UI ( const string& class_name, const type_info * const class_type_info ) { 321 MappedUI::add_class ( class_name, class_type_info, this ); 322 } 323 324 public: 325 326 //! Enumerical type used to determine whether the data for concrete Settingis is compulsory or optional 327 enum SettingPresence { optional, compulsory } ; 328 329 //! \name Initialization of classes 328 330 //!@{ 329 //! The type T has to be a root descendant class331 //! The type T has to be a #bdm::root descendant class 330 332 331 333 //! The new instance of type T* is constructed and initialized with values stored in the Setting element[name] 332 template<class T> static T* build( const Setting &element, const string &name ) 333 { 334 //! 335 //! If there is not any sub-element named #name, the null pointer is returned. 336 template<class T> static T* build ( const Setting &element, const string &name, SettingPresence settingPresence = optional ) { 337 if ( !element.exists ( name ) ) 338 { 339 if( settingPresence == optional ) 340 return NULL; 341 else 342 throw UIException ( "the compulsory Setting named \"" + name + "\" is missing", element ); 343 } 344 334 345 T* instance; 335 from_setting<T> ( instance, to_child_setting( element, name ) );346 from_setting<T> ( instance, to_child_setting ( element, name ) ); 336 347 return instance; 337 348 } 349 338 350 //! The new instance of type T* is constructed and initialized with values stored in the Setting element[index] 339 template<class T> static T* build( const Setting &element, const int index ) 340 { 351 //! 352 //! If there is not any sub-element indexed by #index, the null pointer is returned. 353 template<class T> static T* build ( const Setting &element, const int index, SettingPresence settingPresence = optional ) { 354 if ( element.getLength() <= index ) 355 { 356 if( settingPresence == optional ) 357 return NULL; 358 else 359 { 360 stringstream stream; 361 stream << index; 362 throw UIException ( "the compulsory Setting with the index " + stream.str()+ " is missing", element ); 363 } 364 } 365 341 366 T* instance; 342 from_setting<T> ( instance, to_child_setting( element, index ) );367 from_setting<T> ( instance, to_child_setting ( element, index ) ); 343 368 return instance; 344 369 } 370 345 371 //! The new instance of type T* is constructed and initialized with values stored in the Setting element 346 template<class T> static T* build( const Setting &element ) 347 { 372 template<class T> static T* build ( const Setting &element ) { 348 373 T* instance; 349 from_setting<T> ( instance, element );374 from_setting<T> ( instance, element ); 350 375 return instance; 351 } 376 377 } 378 352 379 //!@} 353 380 354 //! \name Initialization of structures 381 //! \name Initialization of structures 355 382 //!@{ 356 383 //! The type T has to be int, double, string, vec, ivec or mat. 357 384 358 385 //! The existing instance of type T is initialized with values stored in the Setting element[name] 359 template<class T> static void get( T &instance, const Setting &element, const string &name ) 360 { 361 from_setting( instance, to_child_setting( element, name ) ); 362 } 363 364 //! The existing instance of type T is initialized with values stored in the Setting element[index] 365 template<class T> static void get( T &instance, const Setting &element, const int index ) 366 { 367 from_setting( instance, to_child_setting( element, index ) ); 386 //! If there is not any sub-element named #name, this method returns false. 387 template<class T> static bool get ( T &instance, const Setting &element, const string &name, SettingPresence settingPresence = optional ) { 388 if ( !element.exists ( name ) ) 389 { 390 if( settingPresence == optional ) 391 return false; 392 else 393 throw UIException ( "the compulsory Setting named \"" + name + "\" is missing", element ); 394 } 395 396 from_setting ( instance, to_child_setting ( element, name ) ); 397 return true; 398 } 399 400 //! The existing instance of type T is initialized with values stored in the Setting element[index] 401 //! If there is not any sub-element indexed by #index, this method returns false. 402 template<class T> static bool get ( T &instance, const Setting &element, const int index, SettingPresence settingPresence = optional ) { 403 if ( element.getLength() <= index ) 404 { 405 if( settingPresence == optional ) 406 return false; 407 else 408 { 409 stringstream stream; 410 stream << index; 411 throw UIException ( "the compulsory Setting with the index " + stream.str()+ " is missing", element ); 412 } 413 } 414 415 from_setting ( instance, to_child_setting ( element, index ) ); 416 return true; 368 417 } 369 418 370 419 //! The existing instance of type T is initialized with values stored in the Setting element directly 371 template<class T> static void get( T &instance, const Setting &element )372 {373 from_setting( instance, element );420 template<class T> static bool get ( T &instance, const Setting &element ) { 421 from_setting ( instance, element ); 422 return true; 374 423 } 375 424 //!@} … … 380 429 381 430 //! The existing array of type T is initialized with values stored in the Setting element[name] 382 template<class T> static void get( Array<T> &array_to_load, const Setting &element, const string &name ) 383 { 384 from_setting( array_to_load, to_child_setting( element, name ) ); 431 //! If there is not any sub-element named #name, this method returns false. 432 template<class T> static bool get ( Array<T> &array_to_load, const Setting &element, const string &name, SettingPresence settingPresence = optional ) { 433 if ( !element.exists ( name ) ) 434 return false; 435 436 from_setting ( array_to_load, to_child_setting ( element, name ) ); 437 return true; 385 438 } 386 439 387 440 //! The existing array of type T is initialized with values stored in the Setting element[index] 388 template<class T> static void get( Array<T> &array_to_load, const Setting &element, const int index ) 389 { 390 from_setting( array_to_load, to_child_setting( element, index ) ); 441 //! If there is not any sub-element indexed by #index, this method returns false. 442 template<class T> static bool get ( Array<T> &array_to_load, const Setting &element, const int index, SettingPresence settingPresence = optional ) { 443 if ( element.getLength() <= index ) 444 return false; 445 446 from_setting ( array_to_load, to_child_setting ( element, index ) ); 447 return true; 391 448 } 392 449 393 450 //! The existing array of type T is initialized with values stored in the Setting element 394 template<class T> static void get( Array<T> &array_to_load, const Setting &element )395 {396 from_setting( array_to_load, element );451 template<class T> static bool get ( Array<T> &array_to_load, const Setting &element ) { 452 from_setting ( array_to_load, element ); 453 return true; 397 454 } 398 455 //!@} 399 456 400 //! \name Serialization of objects and structures into a new Setting 457 //! \name Serialization of objects and structures into a new Setting 401 458 //!@{ 402 459 //! The new child Setting can be accessed either by its name - if some name is passed as a parameter - … … 404 461 405 462 //! A root descendant instance is stored in the new child Setting appended to the passed element 406 template< class T> static void save( const T * const instance, Setting &element, const string &name = "") 407 { 408 Setting &set = (name == "") ? element.add( Setting::TypeGroup ) 409 : element.add( name, Setting::TypeGroup ); 410 411 const string &class_name = MappedUI::retrieve_class_name( &typeid(*instance) ); 412 413 // add attribute "class" 414 Setting &type = set.add( "class", Setting::TypeString ); 463 template< class T> static void save ( const T * const instance, Setting &element, const string &name = "" ) { 464 Setting &set = ( name == "" ) ? element.add ( Setting::TypeGroup ) 465 : element.add ( name, Setting::TypeGroup ); 466 467 const string &class_name = MappedUI::retrieve_class_name ( &typeid ( *instance ) ); 468 469 // add attribute "class" 470 Setting &type = set.add ( "class", Setting::TypeString ); 415 471 type = class_name; 416 472 417 try 418 { 419 instance->to_setting( set ); 473 try { 474 instance->to_setting ( set ); 475 } catch ( SettingException sttng_xcptn ) { 476 string msg = "the method " + class_name + ".to_setting(Setting&) has thrown a SettingException. Try to correct this method. Check path \"" + sttng_xcptn.getPath() + "\"."; 477 throw exception ( msg.c_str() ); 478 } catch ( UIException uixcptn ) { 479 string msg = "the method " + class_name + ".to_setting(Setting&) has thrown an UIException \"" + uixcptn.message + "\" Try to correct this method. Check path \"" + uixcptn.path + "\"."; 480 throw exception ( msg.c_str() ); 481 } catch ( exception xcptn ) { 482 string msg = "the method " + class_name + ".to_setting(Setting&) has thrown a general exception \"" + xcptn.what() + "\" Try to correct this method. Check path \"" + element.getPath() + "\"."; 483 throw exception ( msg.c_str() ); 420 484 } 421 catch(SettingException xcptn)422 {423 throw UIException( "the method " + class_name + ".to_setting(Setting&) has thrown an SettingException. Try to correct this method", xcptn.getPath());424 }425 485 } 426 486 427 487 //! An Array<T> instance is stored in the new child Setting appended to the passed element 428 template<class T> static void save( const Array<T> &array_to_save, Setting &element, const string &name = "" ) 429 { 430 assert_type(element,Setting::TypeGroup); 431 Setting &list = (name == "") ? element.add( Setting::TypeList ) 432 : element.add( name, Setting::TypeList ); 433 for( int i=0; i<array_to_save.length(); i++ ) 434 save( array_to_save(i), list ); 488 template<class T> static void save ( const Array<T> &array_to_save, Setting &element, const string &name = "" ) { 489 assert_type ( element, Setting::TypeGroup ); 490 Setting &list = ( name == "" ) ? element.add ( Setting::TypeList ) 491 : element.add ( name, Setting::TypeList ); 492 for ( int i = 0; i < array_to_save.length(); i++ ) 493 save ( array_to_save ( i ), list ); 435 494 } 436 495 437 496 //! A matrix(of type mat) is stored in the new child Setting appended to the passed element 438 static void save ( const mat &matrix, Setting &element, const string &name = "" );497 static void save ( const mat &matrix, Setting &element, const string &name = "" ); 439 498 440 499 //! An integer vector (of type ivec) is stored in the new child Setting appended to the passed element 441 static void save ( const ivec &vec, Setting &element, const string &name = "" );442 500 static void save ( const ivec &vec, Setting &element, const string &name = "" ); 501 443 502 //! A double vector (of type vec) is stored in the new child Setting appended to the passed element 444 static void save ( const vec &vector, Setting &element, const string &name = "" );503 static void save ( const vec &vector, Setting &element, const string &name = "" ); 445 504 446 505 //! A string is stored in the new child Setting appended to the passed element 447 static void save ( const string &str, Setting &element, const string &name = "" );506 static void save ( const string &str, Setting &element, const string &name = "" ); 448 507 449 508 //! An integer is stored in the new child Setting appended to the passed element 450 static void save ( const int &integer, Setting &element, const string &name = "" );509 static void save ( const int &integer, Setting &element, const string &name = "" ); 451 510 452 511 //! A double is stored in the new child Setting appended to the passed element 453 static void save ( const double &real, Setting &element, const string &name = "" );512 static void save ( const double &real, Setting &element, const string &name = "" ); 454 513 //!@} 455 514 … … 458 517 459 518 //! The only UI descendant class which is not intended for direct use. It should be accessed within the ::UIREGISTER macro only. 460 template<typename T> class ParticularUI : private UI 461 {519 //! \ref ui_page 520 template<typename T> class ParticularUI : private UI { 462 521 private: 463 522 //! Default constructor, which is intentionally declared as private 464 ParticularUI<T>( const string &class_name) : UI( class_name, &typeid(T) ) 465 {}; 523 ParticularUI<T> ( const string &class_name ) : UI ( class_name, &typeid ( T ) ) {}; 466 524 467 525 public: 468 526 //! The only instance of this class (each type T has its own instance) which is used as a factory for processing related UI 469 static const ParticularUI<T>& factory; 527 static const ParticularUI<T>& factory; 470 528 471 529 //! A method returning a brand new instance of class T, this method is the reason why there have to be a parameterless construcotor in class T 472 root* new_instance() const 473 { 530 root* new_instance() const { 474 531 return new T(); 475 532 } … … 478 535 } 479 536 537 /*! 538 \def UIREGISTER(class_name) 539 \brief Macro for registration of class into map of user-infos, registered class is scriptable using UI static methods 540 541 Argument \a class_name has to be a descendant of root class and also, it has to have parameterless constructor prepared. 542 This macro should be used in header file, immediately after a class declaration. 543 544 \ref ui_page 545 */ 546 #ifndef BDMLIB 547 #define UIREGISTER(class_name) template<> const ParticularUI<class_name>& ParticularUI<class_name>::factory = ParticularUI<class_name>(#class_name) 548 #else 549 #define UIREGISTER(class_name) 550 #endif 551 480 552 #endif // #ifndef USER_INFO_H -
library/bdm/estim/arx.cpp
r412 r471 196 196 void ARX::from_setting( const Setting &set ) 197 197 { 198 RV *yrv = UI::build<RV>(set,"y" );199 RV *rrv = UI::build<RV>(set,"rgr" );198 RV *yrv = UI::build<RV>(set,"y", UI::compulsory); 199 RV *rrv = UI::build<RV>(set,"rgr", UI::compulsory); 200 200 int ylen = yrv->_dsize(); 201 201 int rgrlen = rrv->_dsize(); … … 204 204 mat V0; 205 205 vec dV0; 206 try { 207 UI::get( dV0, set, "dV0" ); 208 } catch(...){ 206 if( !UI::get( dV0, set, "dV0" ) ) 209 207 dV0=concat ( 1e-3*ones ( ylen ), 1e-5*ones ( rgrlen ) ); 210 }211 208 V0=diag ( dV0 ); 212 209 213 210 double nu0; 214 if ( ! set.lookupValue( "nu0", nu0) )211 if ( !UI::get( nu0, set, "nu0") ) 215 212 nu0 = rgrlen+ylen+2; 216 213 217 214 double frg; 218 if ( ! set.lookupValue( "frg", frg) )215 if ( !UI::get( frg, set, "frg") ) 219 216 frg = 1.0; 220 217 … … 230 227 } 231 228 232 /*void ARX::to_setting( Setting &set ) const 233 { 234 Transport::to_setting( set ); 235 236 Setting &kilometers_setting = set.add("kilometers", Setting::TypeInt ); 237 kilometers_setting = kilometers; 238 239 UI::save( passengers, set, "passengers" ); 240 }*/ 241 242 243 } 229 } -
library/bdm/estim/arx.h
r384 r471 142 142 void from_setting( const Setting &set ); 143 143 144 // TODO dodelat void to_setting( Setting &set ) const;145 144 }; 146 145 -
library/bdm/estim/kalman.cpp
r384 r471 251 251 252 252 void EKFCh::from_setting( const Setting &set ) 253 { 254 diffbifn* IM = UI::build<diffbifn>(set, "IM" );255 diffbifn* OM = UI::build<diffbifn>(set, "OM" );253 { 254 diffbifn* IM = UI::build<diffbifn>(set, "IM", UI::compulsory); 255 diffbifn* OM = UI::build<diffbifn>(set, "OM", UI::compulsory); 256 256 257 257 //statistics 258 258 int dim=IM->dimension(); 259 259 vec mu0; 260 if(set.exists("mu0")) 261 UI::get( mu0, set, "mu0"); 262 else 260 if(!UI::get( mu0, set, "mu0")) 263 261 mu0=zeros(dim); 264 262 265 263 mat P0; 266 if(set.exists("dP0")) 267 { 268 vec dP0; 269 UI::get( dP0, set, "dP0"); 264 vec dP0; 265 if(UI::get( dP0, set, "dP0")) 270 266 P0=diag(dP0); 271 } 272 else if ( set.exists( "P0" ) ) 273 UI::get(P0, set, "P0"); 274 else 267 else if ( !UI::get(P0, set, "P0") ) 275 268 P0=eye(dim); 276 269 … … 278 271 279 272 //parameters 280 vec dQ, dR; 281 UI::get( dQ, set, "dQ" );282 UI::get( dR, set, "dR" );273 vec dQ, dR; 274 UI::get( dQ, set, "dQ", UI::compulsory); 275 UI::get( dR, set, "dR", UI::compulsory); 283 276 set_parameters(IM, OM, diag(dQ), diag(dR)); 284 277 285 278 //connect 286 RV* drv = UI::build<RV>(set, "drv" );279 RV* drv = UI::build<RV>(set, "drv", UI::compulsory); 287 280 set_drv(*drv); 288 RV* rv = UI::build<RV>(set, "rv" );281 RV* rv = UI::build<RV>(set, "rv", UI::compulsory); 289 282 set_rv(*rv); 290 283 284 string options; 285 if( UI::get( options, set, "options" ) ) 286 set_options(options); 287 } 288 289 void MultiModel::from_setting( const Setting &set ) 290 { 291 Array<EKFCh*> A; 292 UI::get( A, set, "models", UI::compulsory); 293 294 set_parameters(A); 295 set_drv(A(0)->_drv()); 296 //set_rv(A(0)->_rv()); 297 291 298 string options; 292 299 if(set.lookupValue( "options", options )) … … 294 301 } 295 302 296 /*void EKFCh::to_setting( Setting &set ) const 297 { 298 Transport::to_setting( set ); 299 300 Setting &kilometers_setting = set.add("kilometers", Setting::TypeInt ); 301 kilometers_setting = kilometers; 302 303 UI::save( passengers, set, "passengers" ); 304 }*/ 305 306 void MultiModel::from_setting( const Setting &set ) 307 { 308 Array<EKFCh*> A; 309 UI::get( A, set, "models"); 310 311 set_parameters(A); 312 set_drv(A(0)->_drv()); 313 //set_rv(A(0)->_rv()); 314 315 string options; 316 if(set.lookupValue( "options", options )) 317 set_options(options); 318 } 319 320 /*void MultiModel::to_setting( Setting &set ) const 321 { 322 Transport::to_setting( set ); 323 324 Setting &kilometers_setting = set.add("kilometers", Setting::TypeInt ); 325 kilometers_setting = kilometers; 326 327 UI::save( passengers, set, "passengers" ); 328 }*/ 329 330 331 } 303 } -
library/bdm/math/square_mat.h
r433 r471 16 16 17 17 #include "../itpp_ext.h" 18 19 /*!20 \defgroup math Auxiliary math functions21 @{22 */23 18 24 19 using namespace itpp; … … 283 278 inline ldmat& ldmat::operator -= ( const ldmat &ldA ) {this->add ( ldA,-1.0 );return *this;} 284 279 285 /*! @} */286 287 280 #endif // DC_H -
library/bdm/mex/mex_datasource.h
r384 r471 34 34 { 35 35 Data = mxArray2mat(mexGetVariable("base",set["varname"])); 36 UI::get( rowid, set, "rids" );36 UI::get( rowid, set, "rids" , UI::compulsory); 37 37 it_assert_debug ( max ( rowid ) <=Data.rows(),"MemDS rowid is too high for given Dat." ); 38 38 39 UI::get( delays, set, "tds" );39 UI::get( delays, set, "tds", UI::compulsory ); 40 40 time = max ( delays ); 41 41 it_assert_debug ( time < Data.cols(),"MemDS delays are too high." ); 42 42 43 RV* r = UI::build<RV>(set,"rv" );43 RV* r = UI::build<RV>(set,"rv", UI::compulsory); 44 44 RV ru=RV(); 45 45 set_rvs(*r,ru); -
library/bdm/stat/emix.h
r461 r471 329 329 void from_setting(const Setting &set){ 330 330 Array<mpdf*> Atmp; //temporary Array 331 UI::get(Atmp,set, "mpdfs" );331 UI::get(Atmp,set, "mpdfs", UI::compulsory); 332 332 set_elements(Atmp,true); 333 333 } -
library/bdm/stat/exp_family.cpp
r461 r471 325 325 { 326 326 vec ref; 327 UI::get( ref, set, "ref" );327 UI::get( ref, set, "ref" , UI::compulsory); 328 328 set_parameters(set["k"],ref,set["l"]); 329 329 } 330 331 /*void migamma_ref::to_setting( Setting &set ) const332 {333 Transport::to_setting( set );334 335 Setting &kilometers_setting = set.add("kilometers", Setting::TypeInt );336 kilometers_setting = kilometers;337 338 UI::save( passengers, set, "passengers" );339 }*/340 341 330 342 331 void mlognorm::from_setting( const Setting &set ) 343 332 { 344 vec mu0; 345 UI::get( mu0, set, "mu0" );333 vec mu0; 334 UI::get( mu0, set, "mu0", UI::compulsory); 346 335 set_parameters(mu0.length(),set["k"]); 347 336 condition(mu0); 348 337 } 349 338 350 /*void mlognorm::to_setting( Setting &set ) const351 {352 Transport::to_setting( set );353 354 Setting &kilometers_setting = set.add("kilometers", Setting::TypeInt );355 kilometers_setting = kilometers;356 357 UI::save( passengers, set, "passengers" );358 }*/359 360 361 339 }; -
library/bdm/stat/exp_family.h
r461 r471 235 235 const double& _nu() const {return nu;} 236 236 void from_setting(const Setting &set){ 237 UI::get(nu,set,"nu"); 238 UI::get(dimx,set,"dimx"); 237 239 set.lookupValue("nu",nu); 238 240 set.lookupValue("dimx",dimx); 239 241 mat V; 240 UI::get(V,set,"V" );242 UI::get(V,set,"V", UI::compulsory); 241 243 set_parameters(dimx, V, nu); 242 RV* rv=UI::build<RV>(set,"rv" );244 RV* rv=UI::build<RV>(set,"rv", UI::compulsory); 243 245 set_rv(*rv); 244 246 delete rv; … … 402 404 void from_setting(const Setting &set){ 403 405 epdf::from_setting(set); // reads rv 404 UI::get(alpha,set,"alpha" );405 UI::get(beta,set,"beta" );406 UI::get(alpha,set,"alpha", UI::compulsory); 407 UI::get(beta,set,"beta", UI::compulsory); 406 408 validate(); 407 409 } … … 515 517 void from_setting(const Setting &set){ 516 518 epdf::from_setting(set); // reads rv and rvc 517 UI::get(high,set,"high"); 518 UI::get(low,set,"low"); 519 520 UI::get(high,set,"high", UI::compulsory); 521 UI::get(low,set,"low", UI::compulsory); 519 522 } 520 523 }; … … 561 564 562 565 void from_setting(const Setting &set){ 563 mpdf::from_setting(set); 564 UI::get(A,set,"A"); 565 UI::get(mu_const,set,"const"); 566 mpdf::from_setting(set); 567 568 UI::get(A,set,"A", UI::compulsory); 569 UI::get(mu_const,set,"const", UI::compulsory); 566 570 mat R0; 567 UI::get(R0,set,"R" );571 UI::get(R0,set,"R", UI::compulsory); 568 572 set_parameters(A,mu_const,R0); 569 573 }; … … 619 623 void from_setting( const Setting &set ) 620 624 { 621 fnc* g = UI::build<fnc>( set, "g" ); 622 623 mat R; 624 if ( set.exists( "dR" ) ) 625 { 626 vec dR; 627 UI::get( dR, set, "dR" ); 625 fnc* g = UI::build<fnc>( set, "g", UI::compulsory ); 626 627 mat R; 628 vec dR; 629 if ( UI::get( dR, set, "dR" ) ) 628 630 R=diag(dR); 629 }630 631 else 631 UI::get( R, set, "R" );632 UI::get( R, set, "R", UI::compulsory); 632 633 633 634 set_parameters(g,R); 634 635 } 635 636 /*void mgnorm::to_setting( Setting &set ) const637 {638 Transport::to_setting( set );639 640 Setting &kilometers_setting = set.add("kilometers", Setting::TypeInt );641 kilometers_setting = kilometers;642 643 UI::save( passengers, set, "passengers" );644 }*/645 646 636 }; 647 637 … … 738 728 mpdf::from_setting(set); // reads rv and rvc 739 729 vec betatmp; // ugly but necessary 740 UI::get(betatmp,set,"beta" );741 set.lookupValue("k",k);730 UI::get(betatmp,set,"beta", UI::compulsory); 731 UI::get(k,set,"k", UI::compulsory); 742 732 set_parameters(k,betatmp); 743 733 } … … 1214 1204 epdf::from_setting(set); //reads rv 1215 1205 1216 UI::get(mu,set,"mu" );1206 UI::get(mu,set,"mu", UI::compulsory); 1217 1207 mat Rtmp;// necessary for conversion 1218 UI::get(Rtmp,set,"R" );1208 UI::get(Rtmp,set,"R", UI::compulsory); 1219 1209 R=Rtmp; // conversion 1220 1210 validate(); -
library/bdm/stat/merger.h
r423 r471 275 275 // find which method to use 276 276 string meth_str; 277 UI::get<string> (meth_str, set, "method" );277 UI::get<string> (meth_str, set, "method", UI::compulsory); 278 278 if (!strcmp (meth_str.c_str(), "arithmetic")) 279 279 set_method (ARITHMETIC); … … 286 286 } 287 287 } 288 if (set.exists("dbg_file")){ 289 string dbg_file; 290 UI::get<string> (dbg_file, set, "dbg_file"); 288 string dbg_file; 289 if (UI::get(dbg_file, set, "dbg_file")) 291 290 set_debug_file(dbg_file); 292 }293 291 //validate() - not used 294 292 } -
library/doc/tutorial/arx_ui.dox
r272 r471 6 6 \section cmd Command Line 7 7 8 In order to use it for estimation of an ARX model, we can define the following \ref ui structure:8 In order to use it for estimation of an ARX model, we can define the following \ref ui_page structure: 9 9 \include arx_test.cfg 10 10 -
library/doc/tutorial/manual.dox
r272 r471 13 13 Basic concepts and philosophy of BDM: 14 14 - \subpage intro 15 - \subpage ui 15 - \subpage ui_page 16 16 - \subpage mexfiles 17 17 -
library/doc/tutorial/mexfiles.dox
r272 r471 5 5 6 6 A range of mexfiles is predefined in directory \c library/mex. 7 Many of these mexfile process ui files (see \ref ui ) examples of these files are in directory \c library/tutorial.7 Many of these mexfile process ui files (see \ref ui_page) examples of these files are in directory \c library/tutorial. 8 8 Note that in order to run these files you need to let matlab know where to find them: 9 9 \code -
library/doc/tutorial/ui.dox
r272 r471 1 1 /*! 2 \page ui User Infos and their use 2 \page ui_page User Infos and their use 3 4 \sa #bdm::UI 3 5 4 For easier interaction with users, experiments can be configured via structures called User Info. These structures contain information about details of the experiment that is to be performed. Since experiments involve the use of basic BDM classes and their compositions, the experiment description is also hierarchical with specific user info for each object or class. 6 \sa #UIREGISTER 5 7 6 The User Infos are designed using customized version of the libconfig library (link!). It is specialized for BDM so as to recognize basic mathematical objects, such as vectors and matrices, see ... for details. 8 \sa #bdm::UIFile 9 10 \sa <a href="http://www.hyperrealm.com/libconfig/">The web page of the libconfig library.</a> 11 12 \section ui_intro Introduction 13 14 For easier interaction with users, experiments can be configured via structures called <b>User Info</b>. These structures contain information about details of the experiment that is to be performed. Since experiments involve the use of basic BDM classes and their compositions, the experiment description is also hierarchical with specific user info for each object or class. 15 16 The User Infos are designed using customized version of the libconfig library (www.hyperrealm.com/libconfig). It is specialized for BDM so as to recognize basic mathematical objects, such as vectors and matrices, see details below. 7 17 8 (Technically it can be made compatible with matlab structures!) 18 Technically it can be made compatible with matlab structures (TODO) 19 20 \section ui_example Example 9 21 10 For example a simple experiment can be configures in afollowing way:22 For example, a simple experiment can be configures in the following way: 11 23 \code 12 24 ndat = 100; //number of data points 13 prior = { type="enorm";25 prior = { class="enorm"; 14 26 mu = [1, 2, 3]; 15 27 R = [1, 0, 0, … … 18 30 }; 19 31 \endcode 20 Exact meaning of root fields in this structure (i.e. ndat andprior) is defined by the application (or mex file) that is using this configuration file. It will look for expected fields and it will ignore any other structures. When it does not find what it is looking for, it terminates with an appropriate error message.32 The exact meaning of the root fields in this structure (i.e. \c ndat and \c prior) is defined by the application (or mex file) that is using this configuration file. It will look for expected fields and it will ignore any other structures. When it does not find what it is looking for, it terminates with an appropriate error message. 21 33 22 A structure with field \c type="identifier" is special. Such a structure will be parsed by an appropriate class bdm::UIbuilder which will construct the desired object, in this instance of an object of the class bdm::enorm. 23 For a detailed example how this mechanism works in practice see \ref arx_ui. 24 */ 34 A structure with field \c class="identifier" is special. Such a structure will be parsed by an appropriate #bdm::UI::build method which will construct the desired object, in this instance of an object of the class bdm::enorm. 35 36 For a detailed example how this mechanism works in practice see \ref arx_ui. To learn about the possinility of making <b> internal or external links</b> in configuration files, see the documentation of #bdm::SettingResolver. 37 38 \section ui_implementation Implementation of user info in a custom class 39 40 In accordance with the previous example of the configuration file, consider the class defined as follows: 41 42 \code 43 44 class newbee : public bdm::root { 45 ... 46 47 bdm::enorm prior; 48 int ndat; 49 50 ... 51 } 52 53 \endcode 54 55 There are few obligatory steps to implement user info mechanism in this class. At first, the class has to be \b inherited (directly or indirectly) from #bdm::root, as you can see in our example. What is hidden behind the scene is the use of a <b>parameterless constructor.</b> Each class using User infos has to have one. 56 57 Next, <b>two virtual methods</b> #bdm::root::from_setting and #bdm::root::to_setting defined in the #bdm::root class <b>should be overriden </b> in accordance with the content of the current class. In fact, you can override just method #bdm::root::from_setting in the case you are interested only in loading from configuration files, which is quite common. It is valid also in the other way round, i.e., in the case you are interested just in saving, override only #bdm::root::to_setting. 58 59 How should look the bodies of these methods? It is important not to forget to call their <b>implementation in the base class</b> (in our case, it is the #bdm::root class). Then, they should contain loading of all the necessary class attributes in the case of #bdm::root::from_setting method and saving of them in the other case. To implement these operation, you are encouraged to use static methods of #bdm::UI class, namely #bdm::UI::get, #bdm::UI::build and #bdm::UI::save. 60 61 It can look like this: 62 63 \code 64 65 class newbee : public bdm::root { 66 ... 67 68 bdm::enorm prior; 69 int ndat; 70 71 ... 72 73 virtual void from_setting(const Setting &set) { 74 root::from_setting(set); 75 if( !UI::get( ndat, set, "ndat" ) ) 76 ndat = 1; 77 prior = UI::build<enorm>( set, "prior", compulsory ); 78 } 79 80 virtual void to_setting(Setting &set) const { 81 root::to_setting(set); 82 UI::save(ndat, set, "ndat"); 83 UI::save(prior, set, "prior"); 84 } 85 86 ... 87 } 88 89 \endcode 90 91 As you can see, the presence of a concrete Setting in the configuration file can be tested by the return value of these methods and the code initializing the 92 default values can follow immediately. Imagine, for example, that the first attribute \c ndat is optional. Thereore, the default value is filled in the case that there is not any other in the configuration file (and so #bdm::UI::get method returs \c false). The second atribute, \c prior, is intended to be compulsory. This fact is specified by the last parameter of the templated #bdm::UI::build method. In this case, the method throws an exception if there is not proper data in the configuration file. 93 94 The only difference between #bdm::UI::build and #bdm::UI::get method is in the types of variables they are prepared to. The #bdm::UI::build<T> method is used to initialize instances of classes derived from #bdm::root. It allocates them dynamically and return just an pointer to the new instance. This way it is possible even to load instances of inherited classes without aneven knowing about it. Oppositely, all scalar values of types int, double, string, vec, ivec or mat are loaded by the #bdm::UI::get method with a static memory management. It is also capable to load arrays of templated type #itpp::Array<T>. 95 96 Saving is much more easier. For all the variable types, use the #bdm::UI::save method. 97 */ -
library/system/astylerc
r408 r471 29 29 pad=paren 30 30 unpad=paren 31 one-line=keep-blocks 31 32 #Don't want to break one-line blocks? Uncomment the following line... 33 #one-line=keep-blocks 34 #Code like: 35 # if (isFoo) 36 # { isFoo = false; cout << isFoo << endl; } 37 # then remains unchanged. -
library/tests/egiw_harness.cpp
r456 r471 8 8 9 9 void egiw_harness::from_setting(const Setting &set) { 10 epdf_harness::from_setting(set); 11 UI::get(lognc, set, "lognc" );10 epdf_harness::from_setting(set); 11 UI::get(lognc, set, "lognc", UI::compulsory); 12 12 } 13 13 -
library/tests/epdf_harness.cpp
r469 r471 29 29 30 30 void epdf_harness::from_setting(const Setting &set) { 31 hepdf = UI::build<epdf>(set, "epdf" );32 UI::get(mean, set, "mean" );33 UI::get(variance, set, "variance" );31 hepdf = UI::build<epdf>(set, "epdf", UI::compulsory); 32 UI::get(mean, set, "mean", UI::compulsory); 33 UI::get(variance, set, "variance", UI::compulsory); 34 34 35 if (set.exists("support")) {36 UI::get(support, set, "support");37 }38 35 39 if (set.exists("nbins")) { 40 UI::get(nbins, set, "nbins"); 41 } 36 UI::get(support, set, "support"); 37 UI::get(nbins, set, "nbins"); 38 UI::get(nsamples, set, "nsamples"); 39 UI::get(R, set, "R"); 42 40 43 if (set.exists("nsamples")) { 44 UI::get(nsamples, set, "nsamples");45 }41 RV* rv = UI::build<RV>(set, "marginal_rv"); 42 if (rv) 43 mrv = shared_ptr<RV>(rv); 46 44 47 if (set.exists("R")) { 48 UI::get(R, set, "R"); 49 } 50 51 if (set.exists("marginal_rv")) { 52 mrv = shared_ptr<RV>(UI::build<RV>(set, "marginal_rv")); 53 } 54 55 if (set.exists("tolerance")) { 56 UI::get(tolerance, set, "tolerance"); 57 } 45 UI::get(tolerance, set, "tolerance"); 58 46 } 59 47 -
library/tests/mpdf_harness.cpp
r456 r471 18 18 UIFile in(config_file_name); 19 19 Array<mpdf_harness *> input; 20 20 UI::get(input, in, "data"); 21 21 int sz = input.size(); 22 22 CHECK(sz > 0); … … 26 26 } 27 27 28 void mpdf_harness::from_setting(const Setting &set) { 29 hmpdf = UI::build<mpdf>(set, "mpdf");30 UI::get(cond, set, "cond" );31 UI::get(mean, set, "mean" );28 void mpdf_harness::from_setting(const Setting &set) { 29 hmpdf = UI::build<mpdf>(set, "mpdf", UI::compulsory); 30 UI::get(cond, set, "cond", UI::compulsory); 31 UI::get(mean, set, "mean", UI::compulsory); 32 32 33 if (set.exists("nsamples")) {34 UI::get(nsamples, set, "nsamples");35 }36 33 34 UI::get(nsamples, set, "nsamples"); 37 35 UI::get(R, set, "R"); 38 39 if (set.exists("tolerance")) { 40 UI::get(tolerance, set, "tolerance"); 41 } 36 UI::get(tolerance, set, "tolerance"); 42 37 } 43 38 -
library/tests/test_user_info.cpp
r425 r471 9 9 using namespace bdm; 10 10 11 class Passenger : public root 12 { 13 public: 14 15 Passenger() { 16 } 17 }; 18 19 class Human : public Passenger 20 { 21 public: 22 string name; 23 24 Human() { 25 name = "none"; 26 } 27 28 virtual void from_setting(const Setting &set) { 29 set.lookupValue("name", name); 30 } 31 32 virtual void to_setting(Setting &set) const { 33 Setting &name_setting = set.add("name", Setting::TypeString); 34 name_setting = name; 35 } 36 37 string to_string() { 38 return name; 39 } 40 }; 41 42 UIREGISTER(Human); 43 44 class Robot : public Passenger 45 { 46 public: 47 int number; 48 Array<string> software; 49 50 Robot() : software() { 51 number = -1; 52 } 53 54 virtual void from_setting(const Setting &set) { 55 set.lookupValue("number", number); 56 if( set.exists( "software" ) ) 57 UI::get(software, set, "software"); 58 } 59 60 virtual void to_setting(Setting &set) const { 61 Setting &number_setting = set.add("number", Setting::TypeInt); 62 number_setting = number; 63 64 UI::save(software, set, "software"); 65 } 66 67 string to_string() { 68 stringstream stream; 69 stream << number; 70 for (int i = 0; i < software.length(); i++) 71 stream << "_" + software(i); 72 return stream.str(); 73 } 74 }; 75 76 UIREGISTER(Robot); 77 78 class Transport : public root 79 { 80 public: 81 int year; 82 string manufacturer; 83 84 Transport() { 85 year = 1900; 86 manufacturer = "unknown"; 87 } 88 89 Transport(int year, string manufacturer) 90 : year(year), manufacturer(manufacturer) { 91 } 92 93 virtual void from_setting(const Setting &set) { 94 set.lookupValue("year", year); 95 set.lookupValue("manufacturer", manufacturer); 96 } 97 98 virtual void to_setting(Setting &set) const { 99 Setting &year_setting = set.add("year", Setting::TypeInt); 100 year_setting = year; 101 102 Setting &manufacturer_setting = set.add("manufacturer", Setting::TypeString); 103 manufacturer_setting = manufacturer; 104 } 105 }; 106 107 class Car : public Transport 108 { 109 public: 110 int kilometers; 111 Array<Passenger*> passengers; 112 113 Car() : Transport() { 114 kilometers = 0; 115 } 116 117 118 Car(int year, string manufacturer, int kilometers) 119 : Transport(year, manufacturer), kilometers(kilometers) { 120 } 121 122 virtual void from_setting(const Setting &set) { 123 Transport::from_setting(set); 124 125 set.lookupValue("kilometers", kilometers); 126 127 if( set.exists( "passengers" ) ) 128 UI::get(passengers, set, "passengers"); 129 } 130 131 virtual void to_setting(Setting &set) const { 132 Transport::to_setting(set); 133 134 Setting &kilometers_setting = set.add("kilometers", Setting::TypeInt); 135 kilometers_setting = kilometers; 136 137 UI::save(passengers, set, "passengers"); 138 } 139 140 string to_string() { 141 stringstream stream; 142 stream << "A car made in " << year << " by " << manufacturer << ", having " << kilometers << " kilometers on the clock."; 143 if (passengers.length()) { 144 stream << "The names of passengers are as follows: "; 145 for (int i = 0; i < passengers.length(); i++) 146 stream << passengers(i)->to_string() << " "; 147 } 148 return stream.str(); 149 } 150 }; 151 152 UIREGISTER(Car); 153 154 class Bike : public Transport 155 { 156 public: 157 bool electricLights; 158 mat matr; 159 160 Bike() : Transport(), matr("2,2;3,4") { 161 electricLights = false; 162 } 163 164 Bike(int year, string manufacturer, bool electricLights) 165 : Transport(year, manufacturer), electricLights(electricLights) { 166 } 167 168 ~Bike() { 169 } 170 171 void from_setting(const Setting &set) { 172 Transport::from_setting(set); 173 174 set.lookupValue("electricLights", electricLights); 175 176 UI::get(matr, set, "matr"); 177 } 178 179 void to_setting(Setting &set) const { 180 Transport::to_setting(set); 181 182 Setting &electricLights_setting = set.add("electricLights", Setting::TypeBoolean); 183 electricLights_setting = electricLights; 184 185 UI::save(matr, set, "matr"); 186 } 187 188 string to_string() { 189 stringstream stream; 190 stream << "a bike made in " << year << " by " << manufacturer; 191 if (electricLights) stream << " with electric lights included"; 192 return stream.str(); 193 } 194 }; 195 196 UIREGISTER(Bike); 197 198 TEST(test_load) 199 { 200 UIFile in("test_user_info_input.cfg"); 201 auto_ptr<Transport> pepikovo(UI::build<Transport>(in, "pepikovo")); 202 CHECK_EQUAL(string("A car made in 1998 by audi, having 25000 kilometers on the clock.The names of passengers are as follows: Karlos Novak -1_CygWin_Matlab_Aimsun Karlosik Novacek "), pepikovo->to_string()); 203 204 auto_ptr<Transport> jardovo(UI::build<Transport>(in, "jardovo")); 205 CHECK_EQUAL(string("A car made in 1992 by liaz, having 1555000 kilometers on the clock."), jardovo->to_string()); 206 207 auto_ptr<Transport> ondrejovo(UI::build<Transport>(in, "ondrejovo")); 208 CHECK_EQUAL(string("a bike made in 1996 by author with electric lights included"), ondrejovo->to_string()); 209 210 auto_ptr<Transport> elisky(UI::build<Transport>(in, "elisky")); 211 CHECK_EQUAL(string("A car made in 1992 by liaz, having 1555000 kilometers on the clock."), elisky->to_string()); 212 213 auto_ptr<Transport> kati(UI::build<Transport>(in, "kati")); 214 CHECK_EQUAL(string("A car made in 1980 by vecernicek, having 250000 kilometers on the clock."), kati->to_string()); 11 class Passenger : public root { 12 public: 13 14 Passenger() { 15 } 16 }; 17 18 class Human : public Passenger { 19 public: 20 string name; 21 22 Human() { 23 name = "none"; 24 } 25 26 virtual void from_setting ( const Setting &set ) { 27 UI::get ( name, set, "name" ); 28 } 29 30 virtual void to_setting ( Setting &set ) const { 31 Setting &name_setting = set.add ( "name", Setting::TypeString ); 32 name_setting = name; 33 } 34 35 string to_string() { 36 return name; 37 } 38 }; 39 40 UIREGISTER ( Human ); 41 42 class Robot : public Passenger { 43 public: 44 int number; 45 Array<string> software; 46 47 Robot() : software() { 48 number = -1; 49 } 50 51 virtual void from_setting ( const Setting &set ) { 52 UI::get ( number, set, "number" ); 53 UI::get ( software, set, "software" ); 54 } 55 56 virtual void to_setting ( Setting &set ) const { 57 Setting &number_setting = set.add ( "number", Setting::TypeInt ); 58 number_setting = number; 59 60 UI::save ( software, set, "software" ); 61 } 62 63 string to_string() { 64 stringstream stream; 65 stream << number; 66 for ( int i = 0; i < software.length(); i++ ) 67 stream << "_" + software ( i ); 68 return stream.str(); 69 } 70 }; 71 72 UIREGISTER ( Robot ); 73 74 class Transport : public root { 75 public: 76 int year; 77 string manufacturer; 78 79 Transport() { 80 year = 1900; 81 manufacturer = "unknown"; 82 } 83 84 Transport ( int year, string manufacturer ) 85 : year ( year ), manufacturer ( manufacturer ) { 86 } 87 88 virtual void from_setting ( const Setting &set ) { 89 UI::get ( year, set, "year" ); 90 UI::get ( manufacturer, set, "manufacturer" ); 91 } 92 93 virtual void to_setting ( Setting &set ) const { 94 Setting &year_setting = set.add ( "year", Setting::TypeInt ); 95 year_setting = year; 96 97 Setting &manufacturer_setting = set.add ( "manufacturer", Setting::TypeString ); 98 manufacturer_setting = manufacturer; 99 } 100 }; 101 102 class Car : public Transport { 103 public: 104 int kilometers; 105 Array<Passenger*> passengers; 106 107 Car() : Transport() { 108 kilometers = 0; 109 } 110 111 112 Car ( int year, string manufacturer, int kilometers ) 113 : Transport ( year, manufacturer ), kilometers ( kilometers ) { 114 } 115 116 virtual void from_setting ( const Setting &set ) { 117 Transport::from_setting ( set ); 118 119 UI::get ( kilometers, set, "kilometers" ); 120 UI::get ( passengers, set, "passengers" ); 121 } 122 123 virtual void to_setting ( Setting &set ) const { 124 Transport::to_setting ( set ); 125 126 Setting &kilometers_setting = set.add ( "kilometers", Setting::TypeInt ); 127 kilometers_setting = kilometers; 128 129 UI::save ( passengers, set, "passengers" ); 130 } 131 132 string to_string() { 133 stringstream stream; 134 stream << "A car made in " << year << " by " << manufacturer << ", having " << kilometers << " kilometers on the clock."; 135 if ( passengers.length() ) { 136 stream << "The names of passengers are as follows: "; 137 for ( int i = 0; i < passengers.length(); i++ ) 138 stream << passengers ( i )->to_string() << " "; 139 } 140 return stream.str(); 141 } 142 }; 143 144 UIREGISTER ( Car ); 145 146 class Bike : public Transport { 147 public: 148 bool electricLights; 149 mat matr; 150 151 Bike() : Transport(), matr ( "2,2;3,4" ) { 152 electricLights = false; 153 } 154 155 Bike ( int year, string manufacturer, bool electricLights ) 156 : Transport ( year, manufacturer ), electricLights ( electricLights ) { 157 } 158 159 ~Bike() { 160 } 161 162 void from_setting ( const Setting &set ) { 163 Transport::from_setting ( set ); 164 165 UI::get ( electricLights, set, "electricLights" ); 166 167 UI::get ( matr, set, "matr" ); 168 } 169 170 void to_setting ( Setting &set ) const { 171 Transport::to_setting ( set ); 172 173 Setting &electricLights_setting = set.add ( "electricLights", Setting::TypeBoolean ); 174 electricLights_setting = electricLights; 175 176 UI::save ( matr, set, "matr" ); 177 } 178 179 string to_string() { 180 stringstream stream; 181 stream << "a bike made in " << year << " by " << manufacturer; 182 if ( electricLights ) stream << " with electric lights included"; 183 return stream.str(); 184 } 185 }; 186 187 UIREGISTER ( Bike ); 188 189 TEST ( test_load ) { 190 UIFile in ( "test_user_info_input.cfg" ); 191 auto_ptr<Transport> pepikovo ( UI::build<Transport> ( in, "pepikovo" ) ); 192 CHECK_EQUAL ( string ( "A car made in 1998 by audi, having 25000 kilometers on the clock.The names of passengers are as follows: Karlos Novak -1_CygWin_Matlab_Aimsun Karlosik Novacek " ), pepikovo->to_string() ); 193 194 auto_ptr<Transport> jardovo ( UI::build<Transport> ( in, "jardovo" ) ); 195 CHECK_EQUAL ( string ( "A car made in 1992 by liaz, having 1555000 kilometers on the clock." ), jardovo->to_string() ); 196 197 auto_ptr<Transport> ondrejovo ( UI::build<Transport> ( in, "ondrejovo" ) ); 198 CHECK_EQUAL ( string ( "a bike made in 1996 by author with electric lights included" ), ondrejovo->to_string() ); 199 200 auto_ptr<Transport> elisky ( UI::build<Transport> ( in, "elisky" ) ); 201 CHECK_EQUAL ( string ( "A car made in 1992 by liaz, having 1555000 kilometers on the clock." ), elisky->to_string() ); 202 203 auto_ptr<Transport> kati ( UI::build<Transport> ( in, "kati" ) ); 204 CHECK_EQUAL ( string ( "A car made in 1980 by vecernicek, having 250000 kilometers on the clock." ), kati->to_string() ); 215 205 } 216 206 217 TEST(test_save) 218 { 219 UIFile in("test_user_info_input.cfg"); 220 auto_ptr<Transport> pepikovo(UI::build<Transport>(in, "pepikovo")); 221 222 Car audi(1968, "zyl", 200); 223 Car liaz(1989, "skoda", 1000); 224 Bike author(2001, "noname", false); 225 UIFile out; 226 227 UI::save(&audi, out, "marty"); 228 UI::save(&liaz, out, "bohousovo"); 229 UI::save(&author, out, "karlovo"); 230 UI::save(pepikovo.get(), out, "pepikovo"); 231 out.save("testUI_out.cfg"); 232 233 string expected(load_test_file("testUI_out.matrix")); 234 string actual(load_test_file("testUI_out.cfg")); 235 CHECK_EQUAL(expected, actual); 207 TEST ( test_save ) { 208 UIFile in ( "test_user_info_input.cfg" ); 209 auto_ptr<Transport> pepikovo ( UI::build<Transport> ( in, "pepikovo" ) ); 210 211 Car audi ( 1968, "zyl", 200 ); 212 Car liaz ( 1989, "skoda", 1000 ); 213 Bike author ( 2001, "noname", false ); 214 UIFile out; 215 216 UI::save ( &audi, out, "marty" ); 217 UI::save ( &liaz, out, "bohousovo" ); 218 UI::save ( &author, out, "karlovo" ); 219 UI::save ( pepikovo.get(), out, "pepikovo" ); 220 out.save ( "testUI_out.cfg" ); 221 222 string expected ( load_test_file ( "testUI_out.matrix" ) ); 223 string actual ( load_test_file ( "testUI_out.cfg" ) ); 224 CHECK_EQUAL ( expected, actual ); 236 225 }