Changeset 394 for library/bdm/base/user_info.h
- Timestamp:
- 06/22/09 13:10:28 (15 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
library/bdm/base/user_info.h
r392 r394 17 17 using namespace libconfig; 18 18 19 namespace bdm 20 { 21 22 /*! 23 \def UIREGISTER(class_name) 24 Macro for registration of class into map of UserInfos -- registered class is scriptable 25 26 TODO napsat i to, ze UIREG musi byt v hacku.. 27 */ 19 28 #ifndef BDMLIB 20 //!Macro for registration of classes into map of UserInfos -- registered class is scriptable 21 #define UIREGISTER(class_name) template<> const Particular_UI<class_name>& Particular_UI<class_name>::ui = Particular_UI<class_name>(#class_name) 29 #define UIREGISTER(class_name) template<> const ParticularUI<class_name>& ParticularUI<class_name>::ui = ParticularUI<class_name>(#class_name) 22 30 #else 23 31 #define UIREGISTER(class_name) 24 32 #endif 25 33 26 #define ASSERT_UITYPE(S,Type) it_assert_debug(S.getType()==Setting::Type, string("Wrong setting type, see input path \"")+string(S.getPath())+string("\"")) 27 28 namespace bdm 29 { 30 31 //! exception used in UI::build if it fails it can be caught and handled - see merger_mex.h 34 //! macro assertting that the setting SET is of the SettingType TYPE 35 #define ASSERT_UITYPE(SET,TYPE) it_assert_debug(SET.getType()==Setting::TYPE, string("Wrong setting type, see input path \"")+string(SET.getPath())+string("\"")) 36 37 //! exception used in UI::build if it fails it can be caught and handled - see merger_mex.h 32 38 class UIbuildException : public std::invalid_argument { 33 39 public: 34 40 UIbuildException() : std::invalid_argument("class name") { } 35 41 }; 36 37 class UI_File : public Config38 {39 private:40 const string file_name;41 42 public:43 //! create empty object prepared to store Settings44 UI_File();45 46 //! creates object and fills it from a file47 UI_File( const string &file_name );48 49 //! save UserInfo to the file50 void save(const string &file_name);51 52 operator Setting&();53 };54 42 55 43 /*! 56 @brief This class serves to load and/or save DOMElements into/from files57 stored on a hard-disk.58 59 Firstly, you associate new RootElement instance with some filename during a time of its60 c onstrutcion. Then, you save some object into the new RootElement instance,61 and save it into the file this way: 44 @brief This class serves to load and/or save user-infos into/from 45 configuration files stored on a hard-disk. 46 47 Firstly, save some user-infos into the new UIFile instance. Then, 48 call the save method with a filename as its only argument: 49 62 50 \code 63 51 CAudi audi; 64 RootElement root("cars.xml");65 U serInfo::save( audi, root, "TT");66 root.save();52 UIFile file; 53 UI::save( audi, file, "TT"); 54 file.save("cars.cfg"); 67 55 \endcode 68 56 69 In the other way round, when loading object from a XML file, the appropriate code looks like this: 57 In the other way round, when loading object from a configuration file, 58 the appropriate code looks like this: 59 70 60 \code 71 RootElement root("cars.xml"); 72 root.load(); 73 UserInfo::build<T>(root,"TT"); 61 UIFile file("cars.cfg"); 62 CAudi *audi = UI::build<CAudi>(file,"TT"); 74 63 \endcode 75 64 */ 65 class UIFile : public Config 66 { 67 public: 68 //! create empty file instance prepared to store Settings 69 UIFile(); 70 71 //! creates instance and fills it from the configuration file file_name 72 UIFile( const string &file_name ); 73 74 //! save all the stored Settings into the configuration file file_name 75 void save(const string &file_name); 76 77 //! this operator allows the ability of substituting Setting parameter by UIFile instance 78 operator Setting&(); 79 }; 80 76 81 77 82 78 83 /*! 79 @brief UserInfo is an abstract is for internal purposes only. Use CompoundUserInfo<T> or Particular_UI<T> instead. 80 The raison d'etre of this class is to allow pointers to its templated descendants. 81 82 Also, the main functions of the whole UserInfo library are included within this class, see 83 static methods 'build' and 'save'. 84 84 @brief UI is an abstract class and it is intended for internal purposes only 85 86 This class exists mainly to allow pointers to its templated descendant ParticularUI<T>. Next, 87 it collects all the auxiliary functions useful to prepare some concret user-infos, see static 88 methods 'build', 'get' and 'save'. 85 89 */ 86 90 class UI 87 91 { 88 92 private: 89 //! static class encalupsating map of names to related UserInfos93 //! Atatic class encalupsating two maps, one mapping names to UI instances and the other mapping type_infos to class names 90 94 //! 91 //! The key property of this class is that it initilaized the internal map immediately 92 //! when it is used for a first time. 93 class Mapped_UI 95 //! The key property of this class is that it initilaize the internal map immediately 96 //! when it is used for a first time. Therefore, we do not have to care about the 97 //! order of calls to UIREGISTER macro, which operates with both these mappings. 98 class MappedUI 94 99 { 95 100 private: 96 //! Type definition of mapping which transforms type names to the related user infors 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(); 101 //! Type definition of mapping which transforms class names to the related UI instances 102 typedef map< const string, const UI* const > StringToUIMap; 103 104 //! Type definition of mapping which transforms RTTI type_infos to the related class names 105 typedef map< const type_info * const, const string > TypeInfoToStringMap; 106 107 //! immediately initialized instance of type StringToUIMap 108 static StringToUIMap& mapped_strings(); 109 110 //! immediately initialized instance of type TypeInfoToStringMap 111 static TypeInfoToStringMap& mapped_type_infos(); 112 113 //! method for reporting a error when an attempt to operate with an unregistered class occures 114 static void unregistered_class_error( const string &unregistered_class_name ); 107 115 108 116 public: … … 110 118 static void add_class( const string &class_name, const type_info * const class_type_info, const UI* const ui ); 111 119 112 //! search for an userinfo related to the passed keywithin the internal map120 //! search for an userinfo related to the passed class name within the internal map 113 121 static const UI& retrieve_ui( const string &class_name ); 114 122 115 //! search for an userinfo related to the passed keywithin the internal map123 //! search for an class name related to the passed type_info within the internal map 116 124 static const string& retrieve_class_name( const type_info* const class_type_info ); 117 125 }; 118 126 119 120 121 122 //! internal method assembling a typeless instance from components obtained by the 'AssemblyComponentsFromSetting()' method 127 //! Method assembling a typeless instance, it is implemented in descendant class ParticularUI<T> 123 128 virtual root* new_instance() const = 0; 124 129 125 //! This methods tries to save an instance of type T (or some of its descendant types) 126 //! and build DOM tree accordingly. Then, it creates a new DOMNode named according class_name 127 //! and connecti it to the passed Setting as a new child node. 130 //! Method switching from the \a element to its child Setting according the passed \a index, it also does all the necessary error-checking 128 131 static const Setting& to_child_setting( const Setting &element, const int index ); 129 132 133 //! Method switching from the \a element to its child Setting according the passed \a name, it also does all the necessary error-checking 130 134 static const Setting& to_child_setting( const Setting &element, const string &name ); 131 135 132 133 //! \name Matematical Operations TODO 134 //!@{ 135 136 //! This methods tries to build a new double matrix 136 //! This methods converts a Setting into a matrix 137 137 static void from_setting( mat& matrix, const Setting &element ); 138 //! This methods tries to build a newinteger vector138 //! This methods converts a Setting into an integer vector 139 139 static void from_setting( ivec &vector, const Setting &element ); 140 // jednak kvuli pretypovani, apak taky proto, ze na string nefunguje link_expander..140 //! This methods converts a Setting into a string 141 141 static void from_setting( string &str, const Setting &element ); 142 //! This methods tries to build a new templated array 143 142 //! This methods converts a Setting into a real vector 144 143 static void from_setting( vec &vector, const Setting &element ); 145 144 //! This methods converts a Setting into a integer scalar 145 static void from_setting( int &integer, const Setting &element ); 146 //! This methods converts a Setting into a real scalar 147 static void from_setting( double &real, const Setting &element ); 148 //! This methods converts a Setting into a class T descendant 146 149 template<class T> static void from_setting( T* &instance, const Setting &element ) 147 150 { … … 155 158 ui_error( "the obligatory ""class"" identifier is missing", link.result ); 156 159 157 // and finally we find a UserInfo related to this type158 const UI& related_UI = Mapped _UI::retrieve_ui( class_name );160 // then we find a user-info related to this type 161 const UI& related_UI = MappedUI::retrieve_ui( class_name ); 159 162 160 163 root* typeless_instance = related_UI.new_instance(); … … 168 171 // catch(...) 169 172 // { 173 // TODO pouzit ui_error? 170 174 // it_error ( "UI error: class " + class_name + " is not a descendant of the desired output class. Try to call the UI::build function with a different type parameter." ); 171 175 // } … … 177 181 catch(SettingException xcptn) 178 182 { 183 // TODO pouzit ui_error? 179 184 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." ); 180 185 } 181 186 } 182 187 183 184 //! This methods tries to build a new templated array , 185 // efektivne jen pro vect, mat a string, pro dalsi je nutne pridat from_setting metodu.. ale to asi necceme 188 //! This methods converts a Setting into a new templated array , 189 // TODO efektivne jen pro vect, mat a string, pro dalsi je nutne pridat from_setting metodu.. ale to asi necceme 186 190 template<class T> static void from_setting( Array<T> &array_to_load, const Setting &element ) 187 191 { … … 198 202 } 199 203 200 //!@} 201 202 204 //! Method for reporting user-info errors related to some concrete Setting 203 205 static void ui_error( string message, const Setting &element ); 204 206 205 207 protected: 206 //! default constructor208 //! Default constructor for internal use only, see \sa ParticularUI<T> 207 209 UI( const string& class_name, const type_info * const class_type_info ) 208 210 { 209 Mapped_UI::add_class( class_name, class_type_info, this ); 210 } 211 212 //! Virtual destructor for future use; 213 virtual ~UI(){}; 211 MappedUI::add_class( class_name, class_type_info, this ); 212 } 214 213 215 214 public: 216 //! This methods tries to build a new instance of type T (or some of its descendant types) 217 //! according to a data stored in a DOMNode named class_name within a child nodes of the passed element. 218 //! If an error occurs, it returns a NULL pointer. 219 220 // vraci true, kdyz to byl platny link, jinak false.. v pripade chyby konci it_errorem.. 221 // do elementu vrati setting prislusny po rozbaleni linku, jinak ponecha beze zmeny 215 216 /*! 217 @brief This class serves to expand links used in configuration file. 218 219 TODO - napsat co dela, a hlavne proc je to takhle implementovany.. otevreny soubor! 220 221 ABSOLUTE PATH.. 222 223 Firstly, save some user-infos into the new UIFile instance. Then, 224 call the save method with a filename as its only argument: 225 226 \code 227 CAudi audi; 228 UIFile file; 229 UI::save( audi, file, "TT"); 230 file.save("cars.cfg"); 231 \endcode 232 233 */ 222 234 class SettingResolver 223 235 { 224 236 private: 225 UI_File *file; 226 227 const Setting &initialize_reference( UI_File* &file, const Setting &potential_link); 237 //! If necessary, this pointer stores an addres of an opened UIFile, else it equals NULL 238 UIFile *file; 239 240 //! This method initialize result reference, i.e., it executes the main code of SettingResolver class 241 //! 242 //! This code could be also located directly in constructor. The only reason why we made this 243 //! method is the keyword 'const' within the declaration of result reference (TODO funguje odkaz?). Such a reference 244 //! have to be intialized before any other constructor command, exactly in the way it is implemented now. 245 const Setting &initialize_reference( UIFile* &file, const Setting &potential_link); 228 246 229 247 public: 248 //! Reference to a resolved link or to the original Setting in the case it does not contain a link 230 249 const Setting &result; 231 250 251 //! If potential_link contains a link to some other setting, it is resolved here. Anyway, the Setting reference result is prepared for use. 232 252 SettingResolver( const Setting &potential_link ); 233 253 254 //! An opened UIFile file is closed here if necessary. 234 255 ~SettingResolver(); 235 256 }; 236 257 237 238 239 //! Prototype of a UI builder. Return value is by the second argument since it type checking via \c dynamic_cast. 258 //TODO 259 //! \name Initialization of bdm::root descendant classes according the values stored in a Setting variable 260 //!@{ 261 //! Return value is by the second argument since it type checking via \c dynamic_cast. 240 262 template<class T> static T* build( const Setting &element, const int index ) 241 263 { … … 258 280 return instance; 259 281 } 260 282 //!@} 283 284 //! \name Initialization of structures according the values stored in a Setting variable - TODO VYCET?! 285 //!@{ 261 286 //! This methods tries to build a new double matrix 262 287 template<class T> static void get( T &instance, const Setting &element, const string &name ) … … 272 297 273 298 //! This methods tries to build a new double matrix 299 template<class T> static void get( T &instance, const Setting &element ) 300 { 301 from_setting( instance, element ); 302 } 303 304 //! This methods tries to build a new double matrix 274 305 template<class T> static void get( Array<T> &array_to_load, const Setting &element, const string &name ) 275 306 { … … 282 313 from_setting( array_to_load, to_child_setting( element, index ) ); 283 314 } 315 316 //! This methods tries to build a new double matrix 317 template<class T> static void get( Array<T> &array_to_load, const Setting &element ) 318 { 319 from_setting( array_to_load, element ); 320 } 321 //!@} 284 322 285 323 template< class T> static void save( const T * const instance, Setting &element, const string &name = "") … … 288 326 : element.add( name, Setting::TypeGroup ); 289 327 290 const string &class_name = Mapped _UI::retrieve_class_name( &typeid(*instance) );328 const string &class_name = MappedUI::retrieve_class_name( &typeid(*instance) ); 291 329 292 330 // add attribute "class" … … 321 359 static void save( const ivec &vec, Setting &element, const string &name = "" ); 322 360 323 static void save( const vec &vector, Setting &element, const string &name); 324 325 private: 361 static void save( const vec &vector, Setting &element, const string &name = "" ); 326 362 //! This methods tries to save a double vec 327 static void save( const string &str, Setting &element); 363 static void save( const string &str, Setting &element, const string &name = "" ); 364 365 static void save( const int &integer, Setting &element, const string &name = "" ); 366 367 static void save( const double &real, Setting &element, const string &name = "" ); 328 368 329 369 }; … … 335 375 own userinfo class prepared). 336 376 */ 337 template<typename T> class Particular _UI : private UI377 template<typename T> class ParticularUI : private UI 338 378 { 339 379 public: 340 380 341 381 //! default constructor, which is intentionally declared as private 342 Particular _UI<T>( const string &class_name) : UI( class_name, &typeid(T) )382 ParticularUI<T>( const string &class_name) : UI( class_name, &typeid(T) ) 343 383 { cout << class_name << endl; 344 384 }; … … 346 386 //! the only instance of this class (each type T has its own instance) 347 387 //! which is used as a factory for processing related UI 348 static const Particular _UI<T>& ui;388 static const ParticularUI<T>& ui; 349 389 350 390 root* new_instance() const