Changeset 351

Show
Ignore:
Timestamp:
06/01/09 02:08:50 (15 years ago)
Author:
mido
Message:

par uprav v UI, nikoli finalni verze, presto je zahodno ji ulozit jako zalohu - uz behaji vsechny podstatne funkce vcetne nacitani Array<T>

Files:
1 added
1 removed
4 modified

Legend:

Unmodified
Added
Removed
  • bdm/stat/libBM.h

    r347 r351  
    1414#define BM_H 
    1515 
     16#include <map> 
    1617 
    1718#include "../itpp_ext.h" 
    1819#include "../libconfig/libconfig.h++" 
    19 #include <map> 
     20 
    2021 
    2122using namespace libconfig; 
     
    4748 
    4849        //! This method save all the instance properties into the Setting structure  
    49         virtual void to_setting( Setting &root )  
     50        virtual void to_setting( Setting &root ) const 
    5051        {        
    5152        } 
  • bdm/user_info.cpp

    r345 r351  
    1515namespace bdm { 
    1616 
    17 UI::Class_To_UI::Class_To_UI_Map& UI::Class_To_UI::private_map() 
    18 { 
    19         static Class_To_UI_Map var; 
    20         return var; 
    21 } 
    22  
    23 void UI::Class_To_UI::add_class( const string &class_name, UI* ui ) 
    24 { 
    25         private_map().insert( make_pair( class_name, ui ) ); 
    26 } 
    27  
    28 UI* UI::Class_To_UI::retrieve_ui( const string &class_name ) 
    29 { 
    30         Class_To_UI_Map::const_iterator iter = private_map().find( class_name ); 
    31         if( iter == private_map().end()) return NULL; 
    32         else return iter->second; 
    33 }        
    34  
    35 ////////////////////////////////////////////////////////////////////// 
     17 
     18///////////////////////// UI FILE ///////////////////////////////////////////// 
    3619 
    3720 
     
    7861        return getRoot(); 
    7962} 
    80  
    81 } 
    82  
     63///////////////////////// INTERNAL MAPPED_UI ///////////////////////////////////////////// 
     64 
     65UI::Mapped_UI::String_To_UI_Map& UI::Mapped_UI::mapped_strings() 
     66{ 
     67        static String_To_UI_Map var; 
     68        return var; 
     69} 
     70 
     71UI::Mapped_UI::Type_Info_To_String_Map& UI::Mapped_UI::mapped_type_infos() 
     72{ 
     73        static Type_Info_To_String_Map var; 
     74        return var; 
     75} 
     76 
     77void UI::Mapped_UI::add_class( const string &class_name, const type_info * const class_type_info, const UI* const ui ) 
     78{ 
     79        pair< const string, const UI* const > new_pair = make_pair( class_name, ui ); 
     80        mapped_strings().insert( new_pair ); 
     81        mapped_type_infos().insert( make_pair( class_type_info, new_pair.first ) ); 
     82} 
     83 
     84const UI& UI::Mapped_UI::retrieve_ui( const string &class_name ) 
     85{ 
     86        String_To_UI_Map::const_iterator iter = mapped_strings().find( class_name ); 
     87        if( iter == mapped_strings().end())  
     88                it_error ( "UI error: class " + class_name + " was not properly registered. Use the macro ""UIREGISTER([class name]);"" within your code." ); 
     89        return *iter->second; 
     90}        
     91 
     92const string& UI::Mapped_UI::retrieve_class_name( const type_info * const class_type_info ) 
     93{ 
     94        Type_Info_To_String_Map::const_iterator iter = mapped_type_infos().find( class_type_info ); 
     95        if( iter == mapped_type_infos().end())  
     96                it_error ( "UI error: class with RTTI name " + string(class_type_info->name()) + " was not properly registered. Use the macro ""UIREGISTER([class name]);"" within your code." ); 
     97        return iter->second; 
     98}        
     99 
     100///////////////////////// INTERNAL LINK EXPANDER ///////////////////////////////////////////// 
     101 
     102UI::Link_Expander::Link_Expander( const Setting &potential_link ) 
     103{ 
     104        file = NULL; 
     105        result = &potential_link; 
     106 
     107        if( potential_link.getType() !=  Setting::TypeString ) 
     108                return; 
     109 
     110        string link = (string) potential_link; 
     111        size_t aerobase = link.find('@'); 
     112        if( aerobase != string::npos ) 
     113        { 
     114                string file_name = link.substr( aerobase + 1, link.length() ); 
     115                file = new UI_File( file_name ); 
     116                file->load(); 
     117                result = &(Setting&)(*file); 
     118                link = link.substr( 0, aerobase ); 
     119        } 
     120        else 
     121                while ( !result->isRoot() )  
     122                        result = &result->getParent(); 
     123 
     124        if( !result->exists( link ) ) 
     125                ui_error( "linked Setting was not found", potential_link ); 
     126 
     127        result = &(*result)[link]; 
     128} 
     129 
     130UI::Link_Expander::~Link_Expander() 
     131{ 
     132        if( file ) delete file; 
     133} 
     134 
     135const Setting& UI::Link_Expander::root() const 
     136{ 
     137        return *result; 
     138} 
     139 
     140///////////////////////// UI ///////////////////////////////////////////// 
     141 
     142 
     143 
     144//! This methods   - kvuli ukladani pole stringu, dat jen privatne? 
     145void UI::save( const string &str, Setting &element ) 
     146{ 
     147        Setting &root = element.add( Setting::TypeString ); 
     148        root = str; 
     149} 
     150 
     151void UI::save( const mat &matrix, Setting &element, const string &name) 
     152{ 
     153         
     154        Setting &root = (name == "") ? element.add( Setting::TypeList )                                                  
     155                                                                 : element.add( name, Setting::TypeList );               
     156 
     157        Setting &cols = root.add( Setting::TypeInt ); 
     158        cols = matrix.cols(); 
     159 
     160        Setting &rows = root.add( Setting::TypeInt ); 
     161        rows = matrix.rows(); 
     162 
     163        Setting &elements = root.add( Setting::TypeArray ); 
     164 
     165        // build matrix row-wise 
     166        for( int i=0; i<matrix.rows(); i++ )  
     167                for( int j=0; j<matrix.cols(); j++) 
     168                { 
     169                        Setting &new_field = elements.add(Setting::TypeFloat); 
     170                        new_field = matrix(i,j); 
     171                } 
     172} 
     173 
     174 
     175        //! This methods tries to save a double vec  
     176void UI::save( const ivec &vec, Setting &element, const string &name) 
     177{ 
     178         
     179        Setting &root = (name == "") ? element.add( Setting::TypeArray )                                                         
     180                                                                 : element.add( name, Setting::TypeArray );              
     181        for( int i=0; i<vec.length(); i++ )  
     182        { 
     183                Setting &new_field = root.add(Setting::TypeInt); 
     184                new_field = vec(i); 
     185        } 
     186} 
     187 
     188 
     189//! This methods tries to build a new double matrix  
     190 
     191void UI::from_setting( mat& matrix, const Setting &element ) 
     192{ 
     193        const Link_Expander link_expander( element ); 
     194        const Setting &root = link_expander.root(); 
     195 
     196        if( root.isNumber() ) 
     197        { 
     198                matrix.set_size( 1, 1 ); 
     199                matrix(0,0) = root; 
     200                return; 
     201        } 
     202 
     203        if( root.isList() ) 
     204        { 
     205                if( root.getLength() != 3 ) 
     206                        ui_error( "the setting supposed to represent a matrix element has wrong syntax", root ); 
     207 
     208                Setting &cols_setting = root[0]; 
     209                Setting &rows_setting = root[1]; 
     210                Setting &elements = root[2]; 
     211 
     212                ASSERT_UITYPE(cols_setting,TypeInt); 
     213                ASSERT_UITYPE(rows_setting,TypeInt); 
     214                ASSERT_UITYPE(elements,TypeArray); 
     215 
     216                int cols = cols_setting; 
     217                int rows = rows_setting; 
     218                                         
     219                if( cols < 0 | rows < 0 ) 
     220                        ui_error( "the dimensions of a matrix has to be non-negative", root ); 
     221 
     222                if( elements.getLength() != cols * rows ) 
     223                        ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements ); 
     224 
     225                matrix.set_size( rows, cols ); 
     226 
     227                if( cols == 0 || rows == 0 ) 
     228                        return; 
     229 
     230                if( !elements[0].isNumber() ) 
     231                        ui_error( "matrix elements have to be numbers", elements[0] ); 
     232 
     233                // build matrix row-wise 
     234                int k = 0; 
     235                for( int i=0;i<rows;i++ )  
     236                        for( int j=0; j<cols; j++) 
     237                                matrix(i,j) = elements[k++]; 
     238                return; 
     239        } 
     240 
     241        ui_error( "only numeric types or TypeList are supported as matrix values", root ); 
     242} 
     243 
     244//! This methods tries to build a new integer vector 
     245void UI::from_setting( ivec &vec, const Setting &element ) 
     246{ 
     247        const Link_Expander link_expander( element ); 
     248        const Setting &root = link_expander.root(); 
     249 
     250        if( root.isNumber() ) 
     251        { 
     252                ASSERT_UITYPE(root,TypeInt); 
     253                vec.set_length( 1 ); 
     254                vec(0) = root; 
     255                return; 
     256        } 
     257 
     258        if( root.isList() ) 
     259        { 
     260                if( root.getLength() != 3 ) 
     261                        ui_error( "the setting supposed to represent a matrix element has wrong syntax", root ); 
     262 
     263                Setting &cols_setting = root[0]; 
     264                Setting &rows_setting = root[1]; 
     265                Setting &elements = root[2]; 
     266 
     267                ASSERT_UITYPE(cols_setting,TypeInt); 
     268                ASSERT_UITYPE(rows_setting,TypeInt); 
     269                ASSERT_UITYPE(elements,TypeArray); 
     270 
     271                int cols = cols_setting; 
     272                int rows = rows_setting; 
     273                 
     274                if( cols < 0 | rows < 0) 
     275                        ui_error( "the dimensions of a matrix has to be non-negative", root ); 
     276 
     277                if( elements.getLength() != cols * rows ) 
     278                        ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements ); 
     279 
     280                if( cols != 1 & rows !=1) 
     281                        ui_error( "the vector length is invalid, it seems to be rather a matrix", elements ); 
     282                 
     283                int len = rows * cols; 
     284                vec.set_length ( len ); 
     285                if( len == 0 ) return; 
     286 
     287                ASSERT_UITYPE(elements[0],TypeInt); 
     288                for( int i=0; i<len; i++ )  
     289                        vec(i) = elements[i]; 
     290                return; 
     291        } 
     292 
     293        if( root.isArray() ) 
     294        {        
     295                int len = root.getLength(); 
     296                vec.set_length( len ); 
     297                if( len == 0 ) return; 
     298 
     299                ASSERT_UITYPE(root[0],TypeInt); 
     300                for( int i=0; i < len; i++ )  
     301                        vec(i) = root[i]; 
     302                return; 
     303        } 
     304 
     305        ui_error( "only numeric types, TypeArray or TypeList are supported as vector values", root ); 
     306} 
     307 
     308 
     309void UI::from_setting( string &str, const Setting &element ) 
     310{ 
     311        ASSERT_UITYPE(element,TypeString); 
     312        str = (string) element; 
     313} 
     314 
     315 
     316///////////////////////// UI FILE ///////////////////////////////////////////// 
     317        //! This methods tries to save an instance of type T (or some of its descendant types) 
     318        //! and build DOM tree accordingly. Then, it creates a new DOMNode named according class_name 
     319        //! and connecti it to the passed Setting as a new child node. 
     320const Setting* UI::pointer_to_child_setting( const Setting &element, const int index ) 
     321{ 
     322        if( !element.isList()) 
     323                return NULL; 
     324 
     325        if( element.getLength() <= index ) 
     326                return NULL; 
     327 
     328        return &element[index]; 
     329} 
     330 
     331const Setting* UI::pointer_to_child_setting( const Setting &element, const string &name ) 
     332{ 
     333        if( !element.isGroup() ) 
     334                return NULL; 
     335 
     336        if( !element.exists( name ) ) 
     337                return NULL; 
     338 
     339        return &element[name]; 
     340} 
     341 
     342const Setting& UI::reference_to_child_setting( const Setting &element, const int index ) 
     343{ 
     344        if( !element.isList()) 
     345                ui_error( "only TypeList elements could be indexed by integers", element ); 
     346 
     347        if( element.getLength() <= index ) 
     348                ui_error( "there is not any child with index " + index, element ); 
     349 
     350        return element[index]; 
     351} 
     352 
     353const Setting& UI::reference_to_child_setting( const Setting &element, const string &name ) 
     354{ 
     355        ASSERT_UITYPE(element,TypeGroup); 
     356        if( !element.exists( name ) ) 
     357                ui_error( "there is not any child named """ + name, element ); 
     358        return element[name]; 
     359} 
     360 
     361 
     362} 
     363 
  • bdm/user_info.h

    r345 r351  
    22#define UIBUILD 
    33 
    4 #include <itpp/itbase.h> 
    5 #include "stat/libBM.h" 
    6 #include "libconfig/libconfig.h++" 
    74 
    85#include <sstream> 
     
    1613#include <iostream> 
    1714 
     15#include "libconfig/libconfig.h++" 
     16 
     17#include <itpp/itbase.h> 
     18 
     19#include "stat/libBM.h" 
     20 
    1821using std::string; 
    1922using namespace std; 
     
    2629namespace bdm 
    2730{ 
     31class UI_File : public Config 
     32{ 
     33private: 
     34        const string file_name; 
     35 
     36public: 
     37        //! attach new RootElement instance to a file (typically with an XML extension) 
     38        UI_File( const string &file_name ); 
     39 
     40        //! loads root element from a file 
     41        void load(); 
     42 
     43        //! save UserInfo to the file (typically with an XML extension) 
     44        void save(); 
     45 
     46        operator Setting&(); 
     47}; 
    2848 
    2949/*! 
     
    4969*/ 
    5070 
    51 class UI_File : public Config 
    52 { 
    53 private: 
    54         const string file_name; 
    55  
    56 public: 
    57         //! attach new RootElement instance to a file (typically with an XML extension) 
    58         UI_File( const string &file_name ); 
    59  
    60         //! loads root element from a file 
    61         void load(); 
    62  
    63         //! save UserInfo to the file (typically with an XML extension) 
    64         void save(); 
    65  
    66         operator Setting&(); 
    67 }; 
    68  
    6971 
    7072/*! 
     
    8991        //! The key property of this class is that it initilaized the internal map immediately 
    9092        //! when it is used for a first time. 
    91         class Class_To_UI 
     93        class Mapped_UI 
    9294        { 
    9395        private: 
    9496                //! Type definition of mapping which transforms type names to the related user infors 
    95                 typedef map< const string, UI* > Class_To_UI_Map; 
    96  
    97                 //! immediately initialized instance of type Class_To_UI_Map 
    98                 static Class_To_UI_Map& private_map(); 
     97                typedef map< const string, const UI* const > String_To_UI_Map; 
     98 
     99                //! Type definition of mapping which transforms type names to the related user infors 
     100                typedef map< const type_info * const, const string > Type_Info_To_String_Map; 
     101 
     102                //! immediately initialized instance of type String_To_UI_Map 
     103                static String_To_UI_Map& mapped_strings(); 
     104 
     105                //! immediately initialized instance of type String_To_UI_Map 
     106                static Type_Info_To_String_Map& mapped_type_infos(); 
    99107 
    100108        public: 
    101109                //! add a pair key-userinfo into the internal map 
    102                 static void add_class( const string &class_name, UI* ui ); 
     110                static void add_class( const string &class_name, const type_info * const class_type_info, const UI* const ui ); 
    103111 
    104112                //! search for an userinfo related to the passed key within the internal map 
    105                 static UI* retrieve_ui( const string &class_name ); 
     113                static const UI& retrieve_ui( const string &class_name ); 
     114 
     115                //! search for an userinfo related to the passed key within the internal map 
     116                static const string& retrieve_class_name( const type_info* const class_type_info ); 
    106117        }; 
    107                                  
     118 
     119        // vraci true, kdyz to byl platny link, jinak false.. v pripade chyby konci it_errorem.. 
     120        // do elementu vrati setting prislusny po rozbaleni linku, jinak ponecha beze zmeny 
     121        class Link_Expander      
     122        { 
     123        private: 
     124                UI_File *file; 
     125                const Setting *result; 
     126 
     127        public: 
     128 
     129                Link_Expander( const Setting &potential_link ); 
     130                 
     131                ~Link_Expander(); 
     132                 
     133                const Setting& root() const; 
     134        }; 
     135 
     136 
    108137        //! internal method assembling a typeless instance from components obtained by the 'AssemblyComponentsFromSetting()' method 
    109         virtual bdmroot* new_instance() = 0; 
     138        virtual bdmroot* new_instance() const = 0; 
    110139         
    111         //! type name defined by user 
    112         const string class_name; 
    113  
    114140        //! This methods tries to save an instance of type T (or some of its descendant types) 
    115141        //! and build DOM tree accordingly. Then, it creates a new DOMNode named according class_name 
    116142        //! and connecti it to the passed Setting as a new child node. 
    117         template<class T> static void to_setting( const T &instance, Setting &root ) 
    118         { 
    119                 const string &class_name = Particular_UI<T>::ui.class_name; 
    120                          
    121                 // add attribute "class"  
    122                 Setting &type = root.add( "class", Setting::TypeString ); 
    123                 type = class_name; 
    124          
    125                 try 
    126                 { 
    127                         // instance disassembling  
    128                         instance.to_setting( root ); 
    129                 } 
    130                 catch(SettingException xcptn) 
    131                 { 
    132                         it_error ( "UI error: the method " + class_name + ".to_setting(Setting&) has thrown an exception when filling the setting " + xcptn.getPath() + ". Try to correct this method." ); 
    133                 }        
    134         } 
    135  
    136         template<class T> static T* from_setting( const Setting &element ) 
     143        static const Setting* pointer_to_child_setting( const Setting &element, const int index ); 
     144 
     145        static const Setting* pointer_to_child_setting( const Setting &element, const string &name ); 
     146 
     147        static const Setting& reference_to_child_setting( const Setting &element, const int index ); 
     148 
     149        static const Setting& reference_to_child_setting( const Setting &element, const string &name ); 
     150 
     151 
     152        //! This methods tries to build a new double matrix  
     153        static void from_setting( mat& matrix, const Setting &element );         
     154        //! This methods tries to build a new integer vector 
     155        static void from_setting( ivec &vec, const Setting &element ); 
     156        // jednak kvuli pretypovani, apak taky proto, ze na string nefunguje link_expander.. 
     157        static void from_setting( string &str, const Setting &element ); 
     158        //! This methods tries to build a new templated array  
     159 
     160        template<class T> static void from_setting( T* &instance, const Setting &element ) 
    137161        {                        
    138162                const Link_Expander link_expander( element ); 
     
    147171         
    148172                // and finally we find a UserInfo related to this type 
    149                 UI* related_UI = Class_To_UI::retrieve_ui( class_name ); 
    150                 if( !related_UI) 
    151                         it_error ( "UI error: class " + class_name + " was not properly registered. Use the macro ""UIREGISTER([class name]);"" within your code." ); 
    152                  
    153                 bdmroot* typeless_instance = related_UI->new_instance(); 
    154  
    155                 T* ui = NULL; 
     173                const UI& related_UI = Mapped_UI::retrieve_ui( class_name ); 
     174                 
     175                bdmroot* typeless_instance = related_UI.new_instance(); 
     176 
     177                instance = NULL; 
    156178                try 
    157179                { 
    158                         ui = (T*) typeless_instance ; 
     180                        instance = (T*) typeless_instance ; 
    159181                } 
    160182                catch(...) 
     
    165187                try 
    166188                { 
    167                         // instance assembling  
    168                         ui->from_setting( root ); 
     189                        instance->from_setting( root ); 
    169190                } 
    170191                catch(SettingException xcptn) 
     
    172193                        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." ); 
    173194                } 
    174                 return ui; 
    175195        }        
    176196 
    177197 
    178         // vraci true, kdyz to byl platny link, jinak false.. v pripade chyby konci it_errorem.. 
    179         // do elementu vrati setting prislusny po rozbaleni linku, jinak ponecha beze zmeny 
    180         class Link_Expander      
    181         { 
    182         private: 
    183                 UI_File *file; 
    184                 const Setting *result; 
    185  
    186         public: 
    187  
    188                 Link_Expander( const Setting &potential_link ) 
    189                 { 
    190                         file = NULL; 
    191                         result = &potential_link; 
    192  
    193                         if( potential_link.getType() !=  Setting::TypeString ) 
    194                                 return; 
    195  
    196                         string link = (string) potential_link; 
    197                         size_t aerobase = link.find('@'); 
    198                         if( aerobase != string::npos ) 
    199                         { 
    200                                 string file_name = link.substr( aerobase + 1, link.length() ); 
    201                                 file = new UI_File( file_name ); 
    202                                 file->load(); 
    203                                 result = &(Setting&)(*file); 
    204                                 link = link.substr( 0, aerobase ); 
    205                         } 
    206                         else 
    207                                 while ( !result->isRoot() )  
    208                                         result = &result->getParent(); 
    209  
    210                         if( !result->exists( link ) ) 
    211                                 ui_error( "linked Setting was not found", potential_link ); 
    212  
    213                         result = &(*result)[link]; 
    214                 } 
    215  
    216                 ~Link_Expander() 
    217                 { 
    218                         if( file ) delete file; 
    219                 } 
    220                  
    221                 const Setting& root() const 
    222                 { 
    223                         return *result; 
    224                 } 
    225         }; 
    226  
    227                 static const Setting* to_child_setting( const Setting &element, const int index ) 
    228                 { 
    229                         if( !element.isAggregate()) 
    230                                 return NULL; 
    231  
    232                         if( element.getLength() <= index ) 
    233                                 return NULL; 
    234  
    235                         return &element[index]; 
    236                 } 
    237  
    238                 static const Setting* to_child_setting( const Setting &element, const string &name ) 
    239                 { 
    240                         if( !element.isGroup() ) 
    241                                 return NULL; 
    242  
    243                         if( !element.exists( name ) ) 
    244                                 return NULL; 
    245  
    246                         return &element[name]; 
    247                 } 
    248  
    249                 static Setting& to_child_setting( Setting &element, const int index ) 
    250                 { 
    251                         if( !element.isAggregate()) 
    252                                 ui_error( "it is not possible to index non-agregate element by integers", element ); 
    253  
    254                         if( element.getLength() <= index ) 
    255                                 ui_error( "there is not any child with index " + index, element ); 
    256  
    257                         return element[index]; 
    258                 } 
    259  
    260                 static Setting& to_child_setting( Setting &element, const string &name ) 
    261                 { 
    262                         ASSERT_UITYPE(element,TypeGroup); 
    263                         if( !element.exists( name ) ) 
    264                                 ui_error( "there is not any child named """ + name, element ); 
    265                         return element[name]; 
    266                 } 
    267  
    268         //! This methods tries to build a new double matrix  
    269         static void from_setting( mat& matrix, const Setting &element ) 
     198        //! This methods tries to build a new templated array ,  
     199        // efektivne jen pro vect, mat a string, pro dalsi je nutne pridat from_setting metodu.. ale to asi necceme 
     200        template<class T> static void from_setting( Array<T> &array_to_load, const Setting &element ) 
    270201        { 
    271202                const Link_Expander link_expander( element ); 
    272203                const Setting &root = link_expander.root(); 
    273204 
    274                 if( root.isNumber() ) 
    275                 { 
    276                         matrix.set_size( 1, 1 ); 
    277                         matrix(0,0) = root; 
    278                         return; 
    279                 } 
    280  
    281                 if( root.isList() ) 
    282                 { 
    283                         if( root.getLength() != 3 ) 
    284                                 ui_error( "the setting supposed to represent a matrix element has wrong syntax", root ); 
    285  
    286                         Setting &cols_setting = root[0]; 
    287                         Setting &rows_setting = root[1]; 
    288                         Setting &elements = root[2]; 
    289  
    290                         ASSERT_UITYPE(cols_setting,TypeInt); 
    291                         ASSERT_UITYPE(rows_setting,TypeInt); 
    292                         ASSERT_UITYPE(elements,TypeArray); 
    293  
    294                         int cols = cols_setting; 
    295                         int rows = rows_setting; 
    296                                                  
    297                         if( cols < 0 | rows < 0 ) 
    298                                 ui_error( "the dimensions of a matrix has to be non-negative", root ); 
    299  
    300                         if( elements.getLength() != cols * rows ) 
    301                                 ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements ); 
    302  
    303                         matrix.set_size( rows, cols ); 
    304  
    305                         if( cols == 0 || rows == 0 ) 
    306                                 return; 
    307  
    308                         if( !elements[0].isNumber() ) 
    309                                 ui_error( "matrix elements have to be numbers", elements[0] ); 
    310  
    311                         // build matrix row-wise 
    312                         int k = 0; 
    313                         for( int i=0;i<rows;i++ )  
    314                                 for( int j=0; j<cols; j++) 
    315                                         matrix(i,j) = elements[k++]; 
    316                         return; 
    317                 } 
    318  
    319                 ui_error( "only numeric types or TypeList are supported as matrix values", root ); 
    320         } 
    321  
    322         //! This methods tries to save a double matrix  
    323         static void to_setting( const mat &matrix, Setting &root ) 
    324         { 
    325                 Setting &cols = root.add( Setting::TypeInt ); 
    326                 cols = matrix.cols(); 
    327  
    328                 Setting &rows = root.add( Setting::TypeInt ); 
    329                 rows = matrix.rows(); 
    330  
    331                 Setting &elements = root.add( Setting::TypeArray ); 
    332  
    333                 // build matrix row-wise 
    334                 for( int i=0; i<matrix.rows(); i++ )  
    335                         for( int j=0; j<matrix.cols(); j++) 
    336                         { 
    337                                 Setting &newField = elements.add(Setting::TypeFloat); 
    338                                 newField = matrix(i,j); 
    339                         } 
    340         } 
    341  
    342         //! This methods tries to build a new integer vector 
    343         static void from_setting( ivec &vec, const Setting &element ) 
    344         { 
    345                 const Link_Expander link_expander( element ); 
    346                 const Setting &root = link_expander.root(); 
    347  
    348                 if( root.isNumber() ) 
    349                 { 
    350                         ASSERT_UITYPE(root,TypeInt); 
    351                         vec.set_length( 1 ); 
    352                         vec(0) = root; 
    353                         return; 
    354                 } 
    355  
    356                 if( root.isList() ) 
    357                 { 
    358                         if( root.getLength() != 3 ) 
    359                                 ui_error( "the setting supposed to represent a matrix element has wrong syntax", root ); 
    360  
    361                         Setting &cols_setting = root[0]; 
    362                         Setting &rows_setting = root[1]; 
    363                         Setting &elements = root[2]; 
    364  
    365                         ASSERT_UITYPE(cols_setting,TypeInt); 
    366                         ASSERT_UITYPE(rows_setting,TypeInt); 
    367                         ASSERT_UITYPE(elements,TypeArray); 
    368  
    369                         int cols = cols_setting; 
    370                         int rows = rows_setting; 
    371                          
    372                         if( cols < 0 | rows < 0) 
    373                                 ui_error( "the dimensions of a matrix has to be non-negative", root ); 
    374  
    375                         if( elements.getLength() != cols * rows ) 
    376                                 ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements ); 
    377  
    378                         if( cols != 1 & rows !=1) 
    379                                 ui_error( "the vector length is invalid, it seems to be rather a matrix", elements ); 
    380                          
    381                         int len = rows * cols; 
    382                         vec.set_length ( len ); 
    383                         if( len == 0 ) return; 
    384  
    385                         ASSERT_UITYPE(elements[0],TypeInt); 
    386                         for( int i=0; i<len; i++ )  
    387                                 vec(i) = elements[i]; 
    388                         return; 
    389                 } 
    390  
    391                 if( root.isArray() ) 
    392                 {        
    393                         int len = root.getLength(); 
    394                         vec.set_length( len ); 
    395                         if( len == 0 ) return; 
    396  
    397                         ASSERT_UITYPE(root[0],TypeInt); 
    398                         for( int i=0; i < len; i++ )  
    399                                 vec(i) = root[i]; 
    400                         return; 
    401                 } 
    402  
    403                 ui_error( "only numeric types, TypeArray or TypeList are supported as vector values", root ); 
    404         } 
    405  
    406         //! This methods tries to save an integer vector 
    407         static void to_setting( const ivec &vec, Setting &root ) 
    408         { 
    409                 for( int i=0; i<vec.length(); i++ )  
    410                 { 
    411                         Setting &newField = root.add(Setting::TypeInt); 
    412                         newField = vec(i); 
    413                 } 
    414         } 
    415  
    416         //! This methods tries to build a new array of strings  
    417         static void from_setting( Array<string> &string_array, const Setting &element ) 
    418         { 
    419                 const Link_Expander link_expander( element ); 
    420                 const Setting &root = link_expander.root(); 
    421  
    422                 if( root.getType() == Setting::TypeString ) 
    423                 { 
    424                         string_array.set_length( 1 ); 
    425                         string_array(0) = (string)root; 
    426                         return; 
    427                 } 
    428  
    429                 if( root.isArray() ) 
    430                 { 
    431                         int len = root.getLength(); 
    432                         string_array.set_length( len ); 
    433                         if( len == 0 ) return; 
    434  
    435                         ASSERT_UITYPE(root[0],TypeString); 
    436                         for( int i=0; i < len; i++ )  
    437                                 string_array(i) = (string)root[i]; 
    438                         return; 
    439                 } 
    440  
    441                 ui_error( "only TypeString or TypeArray are supported as vector of string values", root ); 
    442         } 
    443  
    444         //! This methods tries to save an array of strings 
    445         static void to_setting( const Array<string> &string_array, Setting &root ) 
    446         { 
    447                 for( int i=0; i<string_array.length(); i++ )  
    448                 { 
    449                         Setting &newField = root.add(Setting::TypeString); 
    450                         newField = string_array(i); 
    451                 } 
     205                ASSERT_UITYPE(root,TypeList); 
     206 
     207                int len = root.getLength(); 
     208                array_to_load.set_length( len ); 
     209                if( len == 0 ) return; 
     210                 
     211                for( int i=0; i < len; i++ )  
     212                        from_setting( array_to_load(i), root[i] );  
    452213        } 
    453214 
    454215protected: 
    455  
    456216        //! default constructor  
    457         UI( const string& class_name ) : class_name ( class_name ) 
     217        UI( const string& class_name, const type_info * const class_type_info )  
    458218        {        
    459                 Class_To_UI::add_class( class_name, this ); 
     219                Mapped_UI::add_class( class_name, class_type_info, this ); 
    460220        } 
    461221 
     
    463223        virtual ~UI(){}; 
    464224 
     225 
    465226public:  
    466  
    467227        static void ui_error( string message, const Setting &element ) 
    468228        { 
     
    477237 
    478238        //! Prototype of a UI builder. Return value is by the second argument since it type checking via \c dynamic_cast. 
    479         template<class T> static T* build( Setting &element, const int index ) 
    480         { 
    481                 return from_setting<T>( to_child_setting( element, index ) ); 
    482         } 
    483  
    484         template<class T> static T* build( Setting &element, const string &name ) 
     239        template<class T> static T* build( const Setting &element, const int index ) 
     240        { 
     241                T* instance; 
     242                from_setting<T>( reference_to_child_setting( element, index ) ); 
     243                return instance; 
     244        } 
     245 
     246        template<class T> static T* build( const Setting &element, const string &name ) 
    485247        {                        
    486                 return from_setting<T>( to_child_setting( element, name ) ); 
    487         } 
    488  
    489         //! This methods tries to save an instance of type T (or some of its descendant types) 
    490         //! and build DOM tree accordingly. Then, it creates a new DOMNode named according class_name 
    491         //! and connecti it to the passed Setting as a new child node. 
    492         template<class T> static void save( T &instance, Setting &element, const string &name = "") 
     248                T* instance; 
     249                from_setting<T>( instance, reference_to_child_setting( element, name ) ); 
     250                return instance; 
     251        } 
     252 
     253        //! This methods tries to build a new double matrix  
     254        template<class T> static bool get( T &instance, const Setting &element, const string &name ) 
     255        { 
     256                const Setting *root = pointer_to_child_setting( element, name ); 
     257                if( !root ) return false;                                
     258                from_setting( instance, *root ); 
     259                return true; 
     260        } 
     261 
     262        //! This methods tries to build a new double matrix  
     263        template<class T> static bool get( T &instance, const Setting &element, const int index ) 
     264        { 
     265                const Setting *root = pointer_to_child_setting( element, index ); 
     266                if( !root ) return false;                                
     267                from_setting( instance, *root ); 
     268                return true; 
     269        } 
     270 
     271        //! This methods tries to build a new double matrix  
     272        template<class T> static bool get( Array<T> &array_to_load, const Setting &element, const string &name ) 
     273        { 
     274                const Setting *root = pointer_to_child_setting( element, name ); 
     275                if( !root ) return false;                                
     276                from_setting( array_to_load, *root ); 
     277                return true; 
     278        } 
     279 
     280        //! This methods tries to build a new double matrix  
     281        template<class T> static bool get( Array<T> &array_to_load, const Setting &element, const int index ) 
     282        { 
     283                const Setting *root = pointer_to_child_setting( element, index ); 
     284                if( !root ) return false;                                
     285                from_setting( array_to_load, *root ); 
     286                return true; 
     287        } 
     288 
     289        template< class T> static void save( const T * const instance, Setting &element, const string &name = "") 
    493290        { 
    494291                Setting &root = (name == "") ? element.add( Setting::TypeGroup )                                                         
    495292                                                                         : element.add( name, Setting::TypeGroup );              
    496                 to_setting( instance, root ); 
    497         } 
    498  
    499         //! This methods tries to build a new double matrix  
    500         static bool get( mat& matrix, const Setting &element, const string &name ) 
    501         { 
    502                 const Setting *root = to_child_setting( element, name ); 
    503                 if( !root ) return false;                                
    504                 from_setting( matrix, *root ); 
    505                 return true; 
    506         } 
    507  
    508         //! This methods tries to build a new double matrix  
    509         static bool get( mat& matrix, const Setting &element, const int index ) 
    510         { 
    511                 const Setting *root = to_child_setting( element, index ); 
    512                 if( !root ) return false;                                
    513                 from_setting( matrix, *root ); 
    514                 return true; 
    515         } 
     293 
     294                const string &class_name = Mapped_UI::retrieve_class_name( &typeid(*instance) ); 
     295                         
     296                // add attribute "class"  
     297                Setting &type = root.add( "class", Setting::TypeString ); 
     298                type = class_name; 
     299 
     300                try 
     301                { 
     302                        instance->to_setting( root ); 
     303                } 
     304                catch(SettingException xcptn) 
     305                { 
     306                        it_error ( "UI error: the method " + class_name + ".to_setting(Setting&) has thrown an exception when filling the setting " + xcptn.getPath() + ". Try to correct this method." ); 
     307                }        
     308        } 
     309 
     310        //! This methods tries to save a double vec  
     311        template<class T> static void save( const Array<T> &array_to_save, Setting &element, const string &name = "" ) 
     312        { 
     313                ASSERT_UITYPE(element,TypeGroup); 
     314                Setting &list = (name == "") ? element.add( Setting::TypeList )                                                  
     315                                                                         : element.add( name, Setting::TypeList );               
     316                for( int i=0; i<array_to_save.length(); i++ )  
     317                        save( array_to_save(i), list ); 
     318        } 
     319 
    516320 
    517321        //! This methods tries to save a double matrix  
    518         static void save( mat &matrix, Setting &element, const string &name = "" ) 
    519         { 
    520                 Setting &root = (name == "") ? element.add( Setting::TypeList )                                                  
    521                                                                          : element.add( name, Setting::TypeList );               
    522                 to_setting( matrix, root ); 
    523         } 
    524  
    525         //! This methods tries to build a new double vec  
    526         static bool get( ivec& vec, const Setting &element, const string &name ) 
    527         { 
    528                 const Setting *root = to_child_setting( element, name ); 
    529                 if( !root ) return false;                                
    530                 from_setting( vec, *root ); 
    531                 return true; 
    532         } 
    533  
    534         //! This methods tries to build a new double vec  
    535         static bool get( ivec& vec, const Setting &element, const int index ) 
    536         { 
    537                 const Setting *root = to_child_setting( element, index ); 
    538                 if( !root ) return false;                                
    539                 from_setting( vec, *root ); 
    540                 return true; 
    541         } 
     322        static void save( const mat &matrix, Setting &element, const string &name = "" ); 
    542323 
    543324        //! This methods tries to save a double vec  
    544         static void save( ivec &vec, Setting &element, const string &name = "" ) 
    545         { 
    546                 Setting &root = (name == "") ? element.add( Setting::TypeArray )                                                         
    547                                                                          : element.add( name, Setting::TypeArray );              
    548                 to_setting( vec, root ); 
    549         } 
    550  
    551         //! This methods tries to build a new double string_array  
    552         static bool get( Array<string> &string_array, const Setting &element, const string &name ) 
    553         { 
    554                 const Setting *root = to_child_setting( element, name ); 
    555                 if( !root ) return false;                                
    556                 from_setting( string_array, *root ); 
    557                 return true; 
    558         } 
    559  
    560         //! This methods tries to build a new double string_array  
    561         static bool get( Array<string> &string_array, const Setting &element, const int index ) 
    562         { 
    563                 const Setting *root = to_child_setting( element, index ); 
    564                 if( !root ) return false;                                
    565                 from_setting( string_array, *root ); 
    566                 return true; 
    567         } 
    568  
    569         //! This methods tries to save a double string_array  
    570         static void save( Array<string> &string_array, Setting &element, const string &name = "" ) 
    571         { 
    572                 Setting &root = (name == "") ? element.add( Setting::TypeArray )                                                         
    573                                                                          : element.add( name, Setting::TypeArray );              
    574                 to_setting( string_array, root ); 
    575         } 
     325        static void save( const ivec &vec, Setting &element, const string &name = "" ); 
     326         
     327        private:  
     328        //! This methods tries to save a double vec  
     329        static void save( const string &str, Setting &element);  
     330 
    576331}; 
    577332 
     
    588343 
    589344        //! default constructor, which is intentionally declared as private 
    590         Particular_UI<T>( const string &class_name) : UI( class_name )  
     345        Particular_UI<T>( const string &class_name) : UI( class_name, &typeid(T) )  
    591346        {        
    592347        }; 
     
    596351        static Particular_UI<T>& ui;     
    597352 
    598         bdmroot* new_instance() 
     353        bdmroot* new_instance() const 
    599354        { 
    600355                return new T(); 
    601356        } 
    602357}; 
     358 
     359 
    603360 
    604361 
  • tests/UI/testUI.cpp

    r345 r351  
     1 
     2#include <string> 
     3 
    14#include <user_info.h> 
    2 #include <string> 
    35 
    46using std::string; 
     
    68using namespace bdm; 
    79 
     10class Passenger : public bdmroot 
     11{ 
     12public: 
     13 
     14        Passenger()      
     15        { 
     16        } 
     17}; 
     18 
     19class Human : public Passenger 
     20{ 
     21public: 
     22        string name; 
     23 
     24        Human()  
     25        { 
     26                name = "none"; 
     27        } 
     28 
     29        virtual void from_setting( const Setting &root ) 
     30        { 
     31                root.lookupValue( "name", name ); 
     32        } 
     33 
     34        virtual void to_setting( Setting &root ) const 
     35        {        
     36                Setting &name_setting = root.add("name", Setting::TypeString ); 
     37                name_setting = name; 
     38        } 
     39 
     40        string ToString() 
     41        { 
     42                return name; 
     43        } 
     44}; 
     45 
     46UIREGISTER(Human); 
     47 
     48class Robot : public Passenger 
     49{ 
     50public: 
     51        int number; 
     52        Array<string> software; 
     53 
     54        Robot() : software() 
     55        { 
     56                number = -1;             
     57        } 
     58 
     59        virtual void from_setting( const Setting &root ) 
     60        { 
     61                root.lookupValue( "number", number ); 
     62 
     63                UI::get( software, root, "software" ); 
     64        } 
     65 
     66        virtual void to_setting( Setting &root ) const 
     67        {        
     68                Setting &number_setting = root.add("number", Setting::TypeInt ); 
     69                number_setting = number; 
     70 
     71                UI::save( software, root, "software" ); 
     72        } 
     73 
     74        string ToString() 
     75        { 
     76                stringstream stream; 
     77                stream << number; 
     78                for( int i = 0; i<software.length(); i++) 
     79                        stream << "_" + software(i); 
     80                return stream.str(); 
     81        } 
     82}; 
     83 
     84UIREGISTER(Robot); 
     85 
    886class Transport : public bdmroot 
    987{ 
     
    29107        } 
    30108 
    31         virtual void to_setting( Setting &root )  
     109        virtual void to_setting( Setting &root ) const 
    32110        {        
    33111                Setting &year_setting = root.add("year", Setting::TypeInt ); 
     
    43121public: 
    44122        int kilometers; 
     123        Array<Passenger*> passengers; 
    45124 
    46125        Car() : Transport()                
     
    60139 
    61140                root.lookupValue( "kilometers", kilometers ); 
    62         } 
    63  
    64         virtual void to_setting( Setting &root )  
     141 
     142                UI::get( passengers, root, "passengers" ); 
     143        } 
     144 
     145        virtual void to_setting( Setting &root ) const 
    65146        {        
    66147                Transport::to_setting( root ); 
     
    68149                Setting &kilometers_setting = root.add("kilometers", Setting::TypeInt ); 
    69150                kilometers_setting = kilometers; 
     151 
     152                UI::save( passengers, root, "passengers" ); 
    70153        } 
    71154 
     
    73156        { 
    74157                stringstream stream; 
    75                 stream << "a car made in " << year << " by " << manufacturer << ", having " << kilometers << " kilometers on the clock."; 
     158                stream << "A car made in " << year << " by " << manufacturer << ", having " << kilometers << " kilometers on the clock."; 
     159                if( passengers.length() ) 
     160                { 
     161                        stream << "The names of passengers are as follows: "; 
     162                        for( int i=0; i<passengers.length(); i++) 
     163                                stream << passengers(i)->ToString() << " "; 
     164                } 
    76165                return stream.str(); 
    77166        } 
     
    109198        } 
    110199 
    111         void to_setting( Setting &root )  
     200        void to_setting( Setting &root ) const 
    112201        {        
    113202                Transport::to_setting( root ); 
     
    132221int main() 
    133222{        
     223        //////////////////////////////////// LOADING //////////////////////////////// 
     224        UI_File in("testUI_in.cfg");     
     225        in.load(); 
     226        Transport *pepikovo = UI::build<Transport>( in, "pepikovo");     
     227        cout << "pepikovo: " << pepikovo->ToString() << endl;            
     228        Transport *jardovo = UI::build<Transport>( in, "jardovo");       
     229        cout << "jardovo: " << jardovo->ToString() << endl;              
     230        Transport *ondrejovo = UI::build<Transport>( in, "ondrejovo");   
     231        cout << "ondrejovo: " << ondrejovo->ToString() << endl;          
     232        Transport *elisky = UI::build<Transport>( in, "elisky");         
     233        cout << "elisky: " << elisky->ToString() << endl;                
     234        Transport *kati = UI::build<Transport>( in, "kati");     
     235        cout << "kati: " << kati->ToString() << endl;            
     236        getchar();  
     237 
    134238        /////////////////////////////////// SAVING ////////////////////////// 
    135         /* 
    136         Car audi( 1998, "audi", 25000); 
    137         Car liaz( 1992, "liaz", 1555000); 
    138         Bike author( 1996, "author", true ); 
    139  
    140         UI_File root("testUI.cfg");      
    141         UI::save( audi, root, "pepikovo"); 
    142         UI::save( liaz, root, "jardovo");  
    143         UI::save( author, root, "ondrejovo"); 
    144         root.save(); 
     239 
     240        Car audi( 1968, "zyl", 200); 
     241        Car liaz( 1989, "skoda", 1000); 
     242        Bike author( 2001, "noname", false ); 
     243        UI_File out("testUI_out.cfg");   
     244 
     245        UI::save( &audi, out, "marty"); 
     246        UI::save( &liaz, out, "bohousovo");  
     247        UI::save( &author, out, "karlovo"); 
     248        UI::save( pepikovo, out, "pepikovo"); 
     249        out.save(); 
    145250 
    146251        cout << "all the transport means were saved correctly" << endl;                          
    147252        getchar(); 
    148         */ 
    149          
    150         //////////////////////////////////// LOADING //////////////////////////////// 
    151         UI_File root("testUI.cfg");      
    152         root.load(); 
    153         Transport *pepikovo = UI::build<Transport>( root, "pepikovo");   
    154         cout << "pepikovo: " << pepikovo->ToString() << endl;            
    155         Transport *jardovo = UI::build<Transport>( root, "jardovo");     
    156         cout << "jardovo: " << jardovo->ToString() << endl;              
    157         Transport *ondrejovo = UI::build<Transport>( root, "ondrejovo");         
    158         cout << "ondrejovo: " << ondrejovo->ToString() << endl;          
    159         Transport *elisky = UI::build<Transport>( root, "elisky");       
    160         cout << "elisky: " << elisky->ToString() << endl;                
    161         Transport *kati = UI::build<Transport>( root, "kati");   
    162         cout << "kati: " << kati->ToString() << endl;            
    163         getchar();  
    164253        return 0; 
    165254}