root/bdm/user_info.h @ 357

Revision 357, 10.9 kB (checked in by mido, 15 years ago)

mnoho zmen:
1) presun FindXXX modulu do \system
2) zalozeni dokumentace \doc\local\library_structure.dox
3) presun obsahu \tests\UI primo do \tests
4) namisto \INSTALL zalozen \install.html, je to vhodnejsi pro uzivatele WINDOWS, a snad i obecne
5) snaha o predelani veskerych UI podle nove koncepce, soubory pmsm_ui.h, arx_ui.h, KF_ui.h, libDS_ui.h, libEF_ui.h a loggers_ui.h ponechavam
jen zdokumentacnich duvodu, nic by na nich jiz nemelo zaviset, a po zkontrolovani spravnosti provedenych uprav by mely byt smazany
6) predelani estimatoru tak, aby fungoval s novym UI konceptem
7) vytazeni tridy bdmroot do samostatneho souboru \bdm\bdmroot.h
8) pridana dokumentace pro zacleneni programu ASTYLE do Visual studia, ASTYLE pridan do instalacniho balicku pro Windows

  • Property svn:eol-style set to native
Line 
1#ifndef USER_INFO_H
2#define USER_INFO_H
3
4#include <stdio.h>
5#include <string>
6#include <typeinfo>
7#include <map>
8
9#include "libconfig/libconfig.h++"
10#include "bdmroot.h"
11#include "itpp/itbase.h"
12
13
14using std::string;
15using namespace std;
16using namespace libconfig;
17
18#define UIREGISTER(class_name) template<> Particular_UI<class_name>& Particular_UI<class_name>::ui = Particular_UI<class_name>(#class_name)
19
20#define ASSERT_UITYPE(S,Type) it_assert_debug(S.getType()==Setting::Type, string("Wrong setting type, see input path \"")+string(S.getPath())+string("\""))
21
22namespace bdm
23{
24class UI_File : public Config
25{
26private:
27        const string file_name;
28
29public:
30        //! create empty object prepared to store Settings
31        UI_File();
32
33        //! creates object and fills it from a file
34        UI_File( const string &file_name );
35
36        //! save UserInfo to the file
37        void save(const string &file_name);
38
39        operator Setting&();
40};
41
42/*!
43@brief This class serves to load and/or save DOMElements into/from files
44stored on a hard-disk.
45
46Firstly, you associate new RootElement instance with some filename during a time of its
47construtcion. Then, you save some object into the new RootElement instance,
48and save it into the file this way:
49\code
50        CAudi audi;
51        RootElement root("cars.xml");
52        UserInfo::save( audi, root, "TT");
53        root.save();
54\endcode
55
56In the other way round, when loading object from a XML file, the appropriate code looks like this:
57\code
58        RootElement root("cars.xml");
59        root.load();
60        UserInfo::build<T>(root,"TT");
61\endcode
62*/
63
64
65/*!
66@brief UserInfo is an abstract is for internal purposes only. Use CompoundUserInfo<T> or Particular_UI<T> instead.
67The raison d'etre of this class is to allow pointers to its templated descendants.
68
69Also, the main functions of the whole UserInfo library are included within this class, see
70static methods 'build' and 'save'.
71
72
73/*!\brief Builds computational object from a UserInfo structure
74
75Return value is a pointer to the created object (memory management issue?)
76/
77
78*/
79class UI
80{
81private:
82        //! static class encalupsating map of names to related UserInfos
83        //!
84        //! The key property of this class is that it initilaized the internal map immediately
85        //! when it is used for a first time.
86        class Mapped_UI
87        {
88        private:
89                //! Type definition of mapping which transforms type names to the related user infors
90                typedef map< const string, const UI* const > String_To_UI_Map;
91
92                //! Type definition of mapping which transforms type names to the related user infors
93                typedef map< const type_info * const, const string > Type_Info_To_String_Map;
94
95                //! immediately initialized instance of type String_To_UI_Map
96                static String_To_UI_Map& mapped_strings();
97
98                //! immediately initialized instance of type String_To_UI_Map
99                static Type_Info_To_String_Map& mapped_type_infos();
100
101        public:
102                //! add a pair key-userinfo into the internal map
103                static void add_class( const string &class_name, const type_info * const class_type_info, const UI* const ui );
104
105                //! search for an userinfo related to the passed key within the internal map
106                static const UI& retrieve_ui( const string &class_name );
107
108                //! search for an userinfo related to the passed key within the internal map
109                static const string& retrieve_class_name( const type_info* const class_type_info );
110        };
111
112        // vraci true, kdyz to byl platny link, jinak false.. v pripade chyby konci it_errorem..
113        // do elementu vrati setting prislusny po rozbaleni linku, jinak ponecha beze zmeny
114        class Link_Expander     
115        {
116        private:
117                UI_File *file;
118                const Setting *result;
119
120        public:
121
122                Link_Expander( const Setting &potential_link );
123               
124                ~Link_Expander();
125               
126                const Setting& root() const;
127        };
128
129
130        //! internal method assembling a typeless instance from components obtained by the 'AssemblyComponentsFromSetting()' method
131        virtual bdmroot* new_instance() const = 0;
132       
133        //! This methods tries to save an instance of type T (or some of its descendant types)
134        //! and build DOM tree accordingly. Then, it creates a new DOMNode named according class_name
135        //! and connecti it to the passed Setting as a new child node.
136        static const Setting& to_child_setting( const Setting &element, const int index );
137
138        static const Setting& to_child_setting( const Setting &element, const string &name );
139
140
141        //! This methods tries to build a new double matrix
142        static void from_setting( mat& matrix, const Setting &element );       
143        //! This methods tries to build a new integer vector
144        static void from_setting( ivec &vector, const Setting &element );
145        // jednak kvuli pretypovani, apak taky proto, ze na string nefunguje link_expander..
146        static void from_setting( string &str, const Setting &element );
147        //! This methods tries to build a new templated array
148
149        static void from_setting( vec &vector, const Setting &element );
150
151        template<class T> static void from_setting( T* &instance, const Setting &element )
152        {                       
153                const Link_Expander link_expander( element );
154                const Setting &root = link_expander.root();
155
156                ASSERT_UITYPE(root,TypeGroup);
157
158                // we get a velue stored in the "class" attribute
159                string class_name;
160                if( !root.lookupValue( "class", class_name ) )
161                        ui_error( "the obligatory ""class"" identifier is missing", root );
162       
163                // and finally we find a UserInfo related to this type
164                const UI& related_UI = Mapped_UI::retrieve_ui( class_name );
165               
166                bdmroot* typeless_instance = related_UI.new_instance();
167
168                instance = NULL;
169                try
170                {
171                        instance = (T*) typeless_instance ;
172                }
173                catch(...)
174                {
175                        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." );
176                }
177               
178                try
179                {
180                        instance->from_setting( root );
181                }
182                catch(SettingException xcptn)
183                {
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." );
185                }
186        }       
187
188
189        //! This methods tries to build a new templated array ,
190        // efektivne jen pro vect, mat a string, pro dalsi je nutne pridat from_setting metodu.. ale to asi necceme
191        template<class T> static void from_setting( Array<T> &array_to_load, const Setting &element )
192        {
193                const Link_Expander link_expander( element );
194                const Setting &root = link_expander.root();
195
196                ASSERT_UITYPE(root,TypeList);
197
198                int len = root.getLength();
199                array_to_load.set_length( len );
200                if( len == 0 ) return;
201               
202                for( int i=0; i < len; i++ ) 
203                        from_setting( array_to_load(i), root[i] ); 
204        }
205
206        static void ui_error( string message, const Setting &element );
207
208protected:
209        //! default constructor
210        UI( const string& class_name, const type_info * const class_type_info ) 
211        {       
212                Mapped_UI::add_class( class_name, class_type_info, this );
213        }
214
215        //! Virtual destructor for future use;
216        virtual ~UI(){};
217
218public: 
219        //! This methods tries to build a new instance of type T (or some of its descendant types)
220        //! according to a data stored in a DOMNode named class_name within a child nodes of the passed element.
221        //! If an error occurs, it returns a NULL pointer.
222
223        //! Prototype of a UI builder. Return value is by the second argument since it type checking via \c dynamic_cast.
224        template<class T> static T* build( const Setting &element, const int index )
225        {
226                T* instance;
227                from_setting<T>( to_child_setting( element, index ) );
228                return instance;
229        }
230
231        template<class T> static T* build( const Setting &element, const string &name )
232        {                       
233                T* instance;
234                from_setting<T>( instance, to_child_setting( element, name ) );
235                return instance;
236        }
237
238        //! This methods tries to build a new double matrix
239        template<class T> static void get( T &instance, const Setting &element, const string &name )
240        {
241                from_setting( instance, to_child_setting( element, name ) );
242        }
243
244        //! This methods tries to build a new double matrix
245        template<class T> static void get( T &instance, const Setting &element, const int index )
246        {
247                from_setting( instance, to_child_setting( element, index ) );
248        }
249
250        //! This methods tries to build a new double matrix
251        template<class T> static void get( Array<T> &array_to_load, const Setting &element, const string &name )
252        {
253                from_setting( array_to_load, to_child_setting( element, name ) );
254        }
255
256        //! This methods tries to build a new double matrix
257        template<class T> static void get( Array<T> &array_to_load, const Setting &element, const int index )
258        {
259                from_setting( array_to_load, to_child_setting( element, index ) );
260        }
261
262        template< class T> static void save( const T * const instance, Setting &element, const string &name = "")
263        {
264                Setting &root = (name == "") ? element.add( Setting::TypeGroup )                                                       
265                                                                         : element.add( name, Setting::TypeGroup );             
266
267                const string &class_name = Mapped_UI::retrieve_class_name( &typeid(*instance) );
268                       
269                // add attribute "class"
270                Setting &type = root.add( "class", Setting::TypeString );
271                type = class_name;
272
273                try
274                {
275                        instance->to_setting( root );
276                }
277                catch(SettingException xcptn)
278                {
279                        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." );
280                }       
281        }
282
283        //! This methods tries to save a double vec
284        template<class T> static void save( const Array<T> &array_to_save, Setting &element, const string &name = "" )
285        {
286                ASSERT_UITYPE(element,TypeGroup);
287                Setting &list = (name == "") ? element.add( Setting::TypeList )                                                 
288                                                                         : element.add( name, Setting::TypeList );             
289                for( int i=0; i<array_to_save.length(); i++ ) 
290                        save( array_to_save(i), list );
291        }
292
293
294        //! This methods tries to save a double matrix
295        static void save( const mat &matrix, Setting &element, const string &name = "" );
296
297        //! This methods tries to save a double vec
298        static void save( const ivec &vec, Setting &element, const string &name = "" );
299       
300        static void save( const vec &vector, Setting &element, const string &name);
301
302        private: 
303        //! This methods tries to save a double vec
304        static void save( const string &str, Setting &element); 
305
306};
307
308
309/*!
310@brief The main userinfo template class. You should derive this class whenever you need
311a new userinfo of a class which is compound from smaller elements (all having its
312own userinfo class prepared).
313*/
314template<typename T> class Particular_UI : private UI
315{
316        // to permit acces to the Particular_UI<T>::ui to the UI class
317        friend UI;
318
319        //! default constructor, which is intentionally declared as private
320        Particular_UI<T>( const string &class_name) : UI( class_name, &typeid(T) ) 
321        {       
322        };
323
324        //! the only instance of this class (each type T has its own instance)
325        //! which is used as a factory for processing related UI
326        static Particular_UI<T>& ui;   
327
328        bdmroot* new_instance() const
329        {
330                return new T();
331        }
332};
333
334
335
336
337}
338
339/*! Recursive build of objects defined in the same file
340
341\code
342{type="internal";
343path="system.profile.[0]";    // Path from the root
344};
345\endcode
346 */
347
348
349
350/*! Recursive build of objects defined in external file
351
352\code
353{type="external";
354filename="my_file.cfg";       // name of file from which to read
355path="system.profile.[0]";    // Path in the external file
356};
357\endcode
358/
359
360*/
361
362#endif // #ifndef USER_INFO_H
Note: See TracBrowser for help on using the browser.