Changeset 344

Show
Ignore:
Timestamp:
05/20/09 14:42:05 (16 years ago)
Author:
mido
Message:

funkcni verze noveho UI, zbyva jeste ucesat

Files:
6 modified

Legend:

Unmodified
Added
Removed
  • bdm/stat/libBM.h

    r342 r344  
    1616 
    1717#include "../itpp_ext.h" 
    18 #include "libconfig/libconfig.h++" 
     18#include "../libconfig/libconfig.h++" 
    1919#include <map> 
    2020 
     
    3535        } 
    3636 
     37        //! This method returns a basic info about the current instance 
    3738        virtual string ToString() 
    3839        { 
     
    4142 
    4243        //! This method arrange instance properties according the data stored in the Setting structure 
    43         virtual void FromSetting( Setting &root ) 
     44        virtual void FromSetting( const Setting &root ) 
    4445        { 
    4546        } 
  • bdm/uibuilder.cpp

    r281 r344  
     1// 
     2// C++ Implementation: itpp_ext 
     3// 
     4// Description: 
     5// 
     6// 
     7// Author: smidl <smidl@utia.cas.cz>, (C) 2008 
     8// 
     9// Copyright: See COPYING file that comes with this distribution 
     10// 
     11// 
     12 
     13#include "uibuilder.h" 
     14 
     15namespace bdm { 
     16 
     17UI::StringToUIMap::MappedString2UI& UI::StringToUIMap::privateMap() 
     18{ 
     19        static MappedString2UI var; 
     20        return var; 
     21} 
     22 
     23void UI::StringToUIMap::Add( const string &className, pUI pInstance ) 
     24{ 
     25        privateMap().insert( make_pair( className, pInstance ) ); 
     26} 
     27 
     28UI::pUI UI::StringToUIMap::Retrieve( const string &className ) 
     29{ 
     30        MappedString2UI::const_iterator iter = privateMap().find( className ); 
     31        if( iter == privateMap().end()) return NULL; 
     32        else return iter->second; 
     33}        
     34 
     35////////////////////////////////////////////////////////////////////// 
     36 
     37 
     38UIFile::UIFile ( const string &file_name ) : fileName( file_name ) 
     39{ 
     40        Config::setAutoConvert( true ); 
     41} 
     42 
     43//! loads root element from a file 
     44void UIFile::Load()  
     45{ 
     46        try 
     47        { 
     48                Config::readFile( fileName.c_str()  ); 
     49        } 
     50        catch ( FileIOException f )  
     51        { 
     52                it_error ( "UI: file " + fileName + " not found." ); 
     53        } 
     54        catch ( ParseException& P )  
     55        { 
     56                stringstream msg; 
     57                msg << "UI: parsing error """ << P.getError() << """ in file " << fileName << " on line " <<  P.getLine() << "."; 
     58                it_error ( msg.str() ); 
     59        }        
     60} 
     61 
     62 
     63//! Save UserInfo to the file (typically with an XML extension) 
     64void UIFile::Save() 
     65{ 
     66        try 
     67        { 
     68                Config::writeFile ( fileName.c_str()  ); 
     69        } 
     70        catch ( FileIOException f )  
     71        { 
     72                it_error( "UI: file " + fileName + " is inacessible." ); 
     73        }                
     74}        
     75 
     76UIFile::operator Setting&() 
     77{ 
     78        return getRoot(); 
     79} 
     80 
     81} 
     82/* 
    183#include "uibuilder.h" 
    284 
     
    486 
    587//! global map of UIbulder names to instances of UIbuilders. Created by UIREGISTER macro 
    6 UImap __uimap__; 
     88UIbuilder::UImap UIbuilder::__uimap__; 
    789 
    890bdmroot* UIexternal::build ( Setting &S ) const { 
     
    1799        try { 
    18100                Setting& remS=C.lookup ( ( const char* ) S["path"] ); 
    19                 UIbuild ( remS,tmp ); 
     101                UIbuilder::build( remS,tmp ); 
    20102        } 
    21103        catch ( ... ) { 
     
    33115                while ( !Stmp->isRoot() ); 
    34116                Setting& intS=Stmp->lookup ( ( const char* ) S["path"] ); 
    35                 UIbuild ( intS,tmp ); 
     117                UIbuilder::build( intS,tmp ); 
    36118        } 
    37119        catch ( ... ) { 
     
    81163} 
    82164//UIexternal* UIexternal_instance =new UIexternal(); 
     165*/ 
  • bdm/uibuilder.h

    r334 r344  
    66#include "libconfig/libconfig.h++" 
    77 
    8 namespace bdm { 
    9  
     8#include <sstream> 
     9#include <iostream> 
     10#include <stdio.h> 
     11#include <string> 
     12#include <typeinfo> 
     13#include <map> 
     14#include <utility> 
     15#include <vector> 
     16#include <iostream> 
     17 
     18using std::string; 
     19using namespace std; 
    1020using namespace libconfig; 
    11 using namespace std; 
    12  
    13 #define CHECK_UITYPE(S,Type) it_assert_debug(S.getType()==Setting::Type, string("Wrong input path \"")+string(S.getPath())+string("\"")); 
    14 #define UIREGISTER(UI) UI* UI##_global_instance = new UI(); 
    15  
    16 //!Standard catches for UIs, use as: catch UICATCH 
    17 #define UICATCH  ( SettingTypeException e ) {it_error ( "Setting " +string ( e.getPath() ) +" is of incorrect Type" );} catch ( SettingNotFoundException e ) {it_error ( "Setting " + string ( e.getPath() ) +" was not found" );} 
    18  
    19 ////////// GLOBAL VAriables 
    20  
    21 class UIbuilder; 
    22 //! Internal structure mapping strings to UIBuilder objects 
    23 typedef map<const string, const UIbuilder*> UImap; 
    24 extern UImap __uimap__; 
    25  
    26 class UIFile : public Config { 
     21 
     22#define UIREGISTER(className) template<> ParticularUI<className>& ParticularUI<className>::ui = ParticularUI<className>(#className) 
     23 
     24#define ASSERT_UITYPE(S,Type) it_assert_debug(S.getType()==Setting::Type, string("Wrong setting type, see input path \"")+string(S.getPath())+string("\"")) 
     25 
     26namespace bdm 
     27{ 
     28 
     29/*! 
     30@brief This class serves to load and/or save DOMElements into/from files 
     31stored on a hard-disk. 
     32 
     33Firstly, you associate new RootElement instance with some filename during a time of its  
     34construtcion. Then, you save some object into the new RootElement instance, 
     35and save it into the file this way: 
     36\code 
     37        CAudi audi; 
     38        RootElement root("cars.xml"); 
     39        UserInfo::Save( audi, root, "TT"); 
     40        root.Save(); 
     41\endcode 
     42 
     43In the other way round, when loading object from a XML file, the appropriate code looks like this: 
     44\code 
     45        RootElement root("cars.xml"); 
     46        root.Load(); 
     47        UserInfo::Build<T>(root,"TT"); 
     48\endcode 
     49*/ 
     50 
     51class UIFile : public Config 
     52{ 
     53private: 
     54        const string fileName; 
     55 
    2756public: 
    28         UIFile ( const char * fname ) :Config() { 
    29                 try{Config::readFile ( fname );} 
    30                 catch ( FileIOException f ) {it_error ( "File " + string ( fname ) + " not found" );} 
    31                 catch ( ParseException& P ) { 
    32                         char msg[200]; 
    33                         sprintf ( msg,"Error in file %s  on line %d.", fname, P.getLine() ); 
     57        //! attach new RootElement instance to a file (typically with an XML extension) 
     58        UIFile( 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 
     69 
     70/*! 
     71@brief UserInfo is an abstract is for internal purposes only. Use CompoundUserInfo<T> or ParticularUI<T> instead. 
     72The raison d'etre of this class is to allow pointers to its templated descendants.  
     73 
     74Also, the main functions of the whole UserInfo library are included within this class, see 
     75static methods 'Build' and 'Save'. 
     76 
     77 
     78/*!\brief Builds computational object from a UserInfo structure 
     79 
     80Return value is a pointer to the created object (memory management issue?) 
     81/ 
     82 
     83*/ 
     84class UI  
     85{ 
     86private: 
     87        //! just a typedef shortuct for a constant pointer to UI 
     88        typedef UI* pUI; 
     89 
     90        //! static class encalupsating map of names to related UserInfos 
     91        //!  
     92        //! The key property of this class is that it initilaized the internal map immediately 
     93        //! when it is used for a first time. 
     94        class StringToUIMap 
     95        { 
     96        private: 
     97                //! Type definition of mapping which transforms type names to the related user infors 
     98                typedef map< const string, pUI > MappedString2UI; 
     99 
     100                //! immediately initialized instance of type MappedString2UI 
     101                static MappedString2UI& privateMap(); 
     102 
     103        public: 
     104                //! add a pair key-userinfo into the internal map 
     105                static void Add( const string &className, pUI pInstance ); 
     106 
     107                //! search for an userinfo related to the passed key within the internal map 
     108                static pUI Retrieve( const string &className ); 
     109        }; 
     110                                 
     111        //! internal method assembling a typeless instance from components obtained by the 'AssemblyComponentsFromSetting()' method 
     112        virtual bdmroot* New() = 0; 
     113         
     114        //! type name defined by user 
     115        const string className; 
     116 
     117protected: 
     118 
     119        //! default constructor  
     120        UI( const string& className ) : className ( className ) 
     121        {        
     122                StringToUIMap::Add( className, this ); 
     123        } 
     124 
     125        //! Virtual destructor for future use; 
     126        virtual ~UI(){}; 
     127 
     128private: 
     129 
     130        //! This methods tries to save an instance of type T (or some of its descendant types) 
     131        //! and build DOM tree accordingly. Then, it creates a new DOMNode named according className 
     132        //! and connecti it to the passed Setting as a new child node. 
     133        template<class T> static void ToSetting( T &instance, Setting &element ) 
     134        { 
     135                string &className = ParticularUI<T>::ui.className; 
     136                         
     137                // add attribute "class"  
     138                Setting &type = root.add( "class", Setting::TypeString ); 
     139                type = className; 
     140         
     141                try 
     142                { 
     143                        // instance disassembling  
     144                        instance.ToSetting( root ); 
     145                } 
     146                catch(SettingException xcptn) 
     147                { 
     148                        it_error ( "UI: the method " + className + ".ToSetting(Setting&) has thrown an exception when filling the setting " + xcptn.getPath() + ". Try to correct this method." ); 
     149                }        
     150        } 
     151 
     152        template<class T> static T* FromSetting( const Setting &element ) 
     153        {                        
     154                RevealIfLinked revealed_link( element ); 
     155                const Setting &root = revealed_link.root(); 
     156 
     157                ASSERT_UITYPE(root,TypeGroup); 
     158 
     159                // we get a velue stored in the "class" attribute  
     160                string className; 
     161                if( !root.lookupValue( "class", className ) ) 
     162                { 
     163                        stringstream msg; 
     164                        msg << "UI: the class identifier is missing within the setting """ << root.getPath() <<  """. Check line "  
     165                                << root.getSourceLine() << "."; 
     166                        it_error ( msg.str() ); 
     167                } 
     168 
     169         
     170                // and finally we find a UserInfo related to this type 
     171                pUI pRelatedUI = StringToUIMap::Retrieve( className ); 
     172                if( !pRelatedUI) 
     173                        it_error ( "UI: class " + className + " was not properly registered. Use the macro ""UIREGISTER([class name]);"" within your code." ); 
     174                 
     175                bdmroot* pTypelessInstance = pRelatedUI->New(); 
     176 
     177                T* pInstance = NULL; 
     178                try 
     179                { 
     180                        pInstance = (T*) pTypelessInstance ; 
     181                } 
     182                catch(...) 
     183                { 
     184                        it_error ( "UI: class " + className + " is not a descendant of the desired output class. Try to call the UI::Build function with a different type parameter." ); 
     185                } 
     186                 
     187                try 
     188                { 
     189                        // instance assembling  
     190                        pInstance->FromSetting( root ); 
     191                } 
     192                catch(SettingException xcptn) 
     193                { 
     194                        string msg = "UI: the method " + className + ".FromSetting(Setting&) has thrown an exception when parsing the setting " + xcptn.getPath() + ". Try to correct this method."; 
    34195                        it_error ( msg ); 
    35196                } 
    36         } 
     197                return pInstance; 
     198        }        
     199 
     200 
     201 
     202public: 
     203 
     204        // vraci true, kdyz to byl platny link, jinak false.. v pripade chyby konci it_errorem.. 
     205        // do elementu vrati setting prislusny po rozbaleni linku, jinak ponecha beze zmeny 
     206        class RevealIfLinked     
     207        { 
     208        private: 
     209                UIFile *file; 
     210                const Setting * result; 
     211 
     212        public: 
     213 
     214                RevealIfLinked( const Setting &element ) 
     215                { 
     216                        file = NULL; 
     217                        result = &element; 
     218 
     219                        if( element.getType() !=  Setting::TypeString ) 
     220                                return; 
     221 
     222                        string link = (string) element; 
     223                        size_t aerobase = link.find('@'); 
     224                        if( aerobase != string::npos ) 
     225                        { 
     226                                string file_name = link.substr( aerobase + 1, link.length() ); 
     227                                file = new UIFile( file_name ); 
     228                                file->Load(); 
     229                                // TODO OSETRIT FALSE, vyhodit iterr 
     230 
     231                                result = &(Setting&)(*file); 
     232 
     233                                link = link.substr( 0, aerobase ); 
     234                        } 
     235                        else 
     236                                while ( !result->isRoot() )  
     237                                        result = &result->getParent(); 
     238 
     239                        if( !result->exists( link ) ) 
     240                        { 
     241                                // vyhodi chybu v pripade chyby 
     242                                printf(""); 
     243                        } 
     244                        result = &(*result)[link]; 
     245                        return; 
     246                } 
     247 
     248                ~RevealIfLinked() 
     249                { 
     250                        if( file ) delete file; 
     251                } 
     252 
     253                 
     254                const Setting& root() 
     255                { 
     256                        return *result; 
     257                } 
     258        }; 
     259 
     260        private: 
     261                static const Setting* ToChildSetting( const Setting &element, const int index ) 
     262                { 
     263                        if( !element.isAggregate()) 
     264                                return NULL; 
     265 
     266                        if( element.getLength() <= index ) 
     267                                return NULL; 
     268 
     269                        return &element[index]; 
     270                } 
     271 
     272                static const Setting* ToChildSetting( const Setting &element, const string &name ) 
     273                { 
     274                        if( !element.isGroup() ) 
     275                                return NULL; 
     276 
     277                        if( !element.exists( name ) ) 
     278                                return NULL; 
     279 
     280                        return &element[name]; 
     281                } 
     282 
     283                static Setting& ToChildSetting( Setting &element, const int index ) 
     284                { 
     285                        if( !element.isAggregate()) 
     286                        { 
     287                                // TODO CO ZA TYP? ASI NE GROUP, COZ.. 
     288                        } 
     289                        if( element.getLength() <= index ) 
     290                        { 
     291                                stringstream msg; 
     292                                msg << "UI: there is not any child with index " << index << " in the parsed setting "  
     293                                        << element.getPath() <<  ", check line " << element.getSourceLine() << "."; 
     294 
     295                                it_error ( msg.str() ); 
     296                        } 
     297                        return element[index]; 
     298                } 
     299 
     300                static Setting& ToChildSetting( Setting &element, const string &name ) 
     301                { 
     302                        ASSERT_UITYPE(element,TypeGroup); 
     303                        if( !element.exists( name ) ) 
     304                        { 
     305                                stringstream msg; 
     306                                msg << "UI: there is not any child named """ << name << """ in the parsed setting "  
     307                                        << element.getPath() <<  ", check line " << element.getSourceLine() << "."; 
     308 
     309                                it_error ( msg.str() ); 
     310                        } 
     311                        return element[name]; 
     312                } 
     313 
     314        //! This methods tries to build a new double matrix  
     315        static bool FromSetting( mat& matrix, const Setting &root ) 
     316        { 
     317                ASSERT_UITYPE(root,TypeList); 
     318                if( root.getLength() != 3 ) 
     319                { 
     320                        stringstream msg; 
     321                        msg << "UI: the setting " << root.getPath() <<  """ supposed to represent a matrix element has wrong syntax"". Check line "  
     322                                << root.getSourceLine() << "."; 
     323                        it_error ( msg.str() ); 
     324                } 
     325 
     326                Setting &cols_setting = root[0]; 
     327                Setting &rows_setting = root[1]; 
     328                Setting &values = root[2]; 
     329 
     330                ASSERT_UITYPE(cols_setting,TypeInt); 
     331                ASSERT_UITYPE(rows_setting,TypeInt); 
     332                ASSERT_UITYPE(values,TypeArray); 
     333 
     334                int cols = cols_setting; 
     335                int rows = rows_setting; 
     336                 
     337                if( values.getLength() != cols * rows ) 
     338                { 
     339                        stringstream msg; 
     340                        msg << "UI: the lenght of array containing matrix values within setting " << root.getPath() <<  """ is improper, check line "  
     341                                << root.getSourceLine() << "."; 
     342                        it_error ( msg.str() ); 
     343                } 
     344 
     345                matrix.set_size( rows, cols ); 
     346 
     347                if( cols == 0 || rows == 0 ) 
     348                        return true; 
     349 
     350                if( !values[0].isNumber() ) 
     351                { 
     352                        stringstream msg; 
     353                        msg << "UI: the array containing matrix values within setting " << root.getPath() <<  """ has to contain numeric values only! Check line "  
     354                                << root.getSourceLine() << "."; 
     355                        it_error ( msg.str() ); 
     356                } 
     357 
     358                // Build matrix row-wise 
     359                int k = 0; 
     360                for( int i=0;i<rows;i++ )  
     361                        for( int j=0; j<cols; j++) 
     362                                matrix(i,j) = values[k++]; 
     363 
     364                return true; 
     365        } 
     366 
     367        //! This methods tries to save a double matrix  
     368        static void ToSetting( mat &matrix, Setting &root ) 
     369        { 
     370                Setting &cols = root.add( Setting::TypeInt ); 
     371                cols = matrix.cols(); 
     372 
     373                Setting &rows = root.add( Setting::TypeInt ); 
     374                rows = matrix.rows(); 
     375 
     376                Setting &values = root.add( Setting::TypeArray ); 
     377 
     378                // Build matrix row-wise 
     379                for( int i=0; i<matrix.rows(); i++ )  
     380                        for( int j=0; j<matrix.cols(); j++) 
     381                        { 
     382                                Setting &newField = values.add(Setting::TypeFloat); 
     383                                newField = matrix(i,j); 
     384                        } 
     385        } 
     386 
     387        //! This methods tries to build a new integer vector 
     388        static bool FromSetting( ivec &vec, const Setting &root ) 
     389        { 
     390                ASSERT_UITYPE(root,TypeArray); 
     391 
     392                int len = root.getLength(); 
     393                vec.set_length( len ); 
     394                if( len == 0 ) return true; 
     395                ASSERT_UITYPE(root[0],TypeInt); 
     396 
     397                for( int i=0; i < len; i++ )  
     398                        vec(i) = root[i]; 
     399                 
     400                return true; 
     401        } 
     402 
     403        //! This methods tries to save an integer vector 
     404        static void ToSetting( ivec &vec, Setting &root ) 
     405        { 
     406                for( int i=0; i<vec.length(); i++ )  
     407                { 
     408                        Setting &newField = root.add(Setting::TypeInt); 
     409                        newField = vec(i); 
     410                } 
     411        } 
     412 
     413        //! This methods tries to build a new array of strings  
     414        static bool FromSetting( Array<string> &string_array, const Setting &root) 
     415        { 
     416                ASSERT_UITYPE(root,TypeArray); 
     417 
     418                int len = root.getLength(); 
     419                string_array.set_length( len ); 
     420                if( len == 0 ) return true; 
     421                ASSERT_UITYPE(root[0],TypeString); 
     422 
     423                for( int i=0; i < len; i++ )  
     424                        string_array(i) = (string)root[i]; 
     425 
     426                return true; 
     427        } 
     428 
     429        //! This methods tries to save an array of strings 
     430        static void ToSetting( Array<string> &string_array, Setting &root ) 
     431        { 
     432                for( int i=0; i<string_array.length(); i++ )  
     433                { 
     434                        Setting &newField = root.add(Setting::TypeString); 
     435                        newField = string_array(i); 
     436                } 
     437        } 
     438 
     439public:  
     440 
     441        //! This methods tries to build a new instance of type T (or some of its descendant types) 
     442        //! according to a data stored in a DOMNode named className within a child nodes of the passed element. 
     443        //! If an error occurs, it returns a NULL pointer. 
     444 
     445        //! Prototype of a UI builder. Return value is by the second argument since it type checking via \c dynamic_cast. 
     446        template<class T> static T* Build( Setting &element, const int index ) 
     447        { 
     448                return FromSetting<T>( ToChildSetting( element, index ) ); 
     449        } 
     450 
     451        template<class T> static T* Build( Setting &element, const string &name ) 
     452        {                        
     453                return FromSetting<T>( ToChildSetting( element, name ) ); 
     454        } 
     455 
     456        //! This methods tries to save an instance of type T (or some of its descendant types) 
     457        //! and build DOM tree accordingly. Then, it creates a new DOMNode named according className 
     458        //! and connecti it to the passed Setting as a new child node. 
     459        template<class T> static void Save( T &instance, Setting &element ) 
     460        { 
     461                Setting &root = element.add( Setting::TypeGroup );               
     462                ToSetting( instance, root ); 
     463        } 
     464 
     465        //! This methods tries to save an instance of type T (or some of its descendant types) 
     466        //! and build DOM tree accordingly. Then, it creates a new DOMNode named according className 
     467        //! and connecti it to the passed Setting as a new child node. 
     468        template<class T> static void Save( T &instance, Setting &element, const string &name ) 
     469        { 
     470                Setting &root = element.add( name, Setting::TypeGroup );                 
     471                ToSetting( instance, root ); 
     472        } 
     473 
     474        //! This methods tries to build a new double matrix  
     475        static bool Get( mat& matrix, const Setting &element, const string &name ) 
     476        { 
     477                const Setting *root = ToChildSetting( element, name ); 
     478                if( !root ) return false;                                
     479                return FromSetting( matrix, *root ); 
     480        } 
     481 
     482        //! This methods tries to build a new double matrix  
     483        static bool Get( mat& matrix, const Setting &element, const int index ) 
     484        { 
     485                const Setting *root = ToChildSetting( element, index ); 
     486                if( !root ) return false;                                
     487                return FromSetting( matrix, *root ); 
     488        } 
     489 
     490        //! This methods tries to save a double matrix  
     491        static void Save( mat &matrix, Setting &element, const string &name ) 
     492        { 
     493                Setting &root = element.add( name, Setting::TypeList );          
     494                ToSetting( matrix, root ); 
     495        } 
     496 
     497        //! This methods tries to save a double matrix  
     498        static void Save( mat &matrix, Setting &element ) 
     499        { 
     500                Setting &root = element.add( Setting::TypeList );                
     501                ToSetting( matrix, root ); 
     502        } 
     503 
     504 
     505        //! This methods tries to build a new double vec  
     506        static bool Get( ivec& vec, const Setting &element, const string &name ) 
     507        { 
     508                const Setting *root = ToChildSetting( element, name ); 
     509                if( !root ) return false;                                
     510                return FromSetting( vec, *root ); 
     511        } 
     512 
     513        //! This methods tries to build a new double vec  
     514        static bool Get( ivec& vec, const Setting &element, const int index ) 
     515        { 
     516                const Setting *root = ToChildSetting( element, index ); 
     517                if( !root ) return false;                                
     518                return FromSetting( vec, *root ); 
     519        } 
     520 
     521        //! This methods tries to save a double vec  
     522        static void Save( ivec &vec, Setting &element, const string &name ) 
     523        { 
     524                Setting &root = element.add( name, Setting::TypeArray );                 
     525                ToSetting( vec, root ); 
     526        } 
     527 
     528        //! This methods tries to save a double vec  
     529        static void Save( ivec &vec, Setting &element) 
     530        { 
     531                Setting &root = element.add( Setting::TypeArray );               
     532                ToSetting( vec, root ); 
     533        } 
     534 
     535 
     536        //! This methods tries to build a new double string_array  
     537        static bool Get( Array<string> &string_array, const Setting &element, const string &name ) 
     538        { 
     539                const Setting *root = ToChildSetting( element, name ); 
     540                if( !root ) return false;                                
     541                return FromSetting( string_array, *root ); 
     542        } 
     543 
     544        //! This methods tries to build a new double string_array  
     545        static bool Get( Array<string> &string_array, const Setting &element, const int index ) 
     546        { 
     547                const Setting *root = ToChildSetting( element, index ); 
     548                if( !root ) return false;                                
     549                return FromSetting( string_array, *root ); 
     550        } 
     551 
     552        //! This methods tries to save a double string_array  
     553        static void Save( Array<string> &string_array, Setting &element, const string &name ) 
     554        { 
     555                Setting &root = element.add( name, Setting::TypeArray );                 
     556                ToSetting( string_array, root ); 
     557        } 
     558 
     559        //! This methods tries to save a double string_array  
     560        static void Save( Array<string> &string_array, Setting &element ) 
     561        { 
     562                Setting &root = element.add( Setting::TypeArray );               
     563                ToSetting( string_array, root ); 
     564        } 
     565 
     566 
    37567}; 
    38568 
    39 //! \name elem Elementary build functions 
    40 //!@{ 
    41  
    42 //! construct itpp::vec from Setting of type Array 
    43 inline vec getvec ( Setting& S ) { 
    44         vec vector; 
    45         if (S.getType() == Setting::TypeArray) {         
    46                 vector.set_size ( S.getLength() ); 
    47                 for ( int i=0;i<S.getLength();i++ ) { 
    48                         switch ( S[i].getType() ) { 
    49                                 case Setting::TypeFloat : 
    50                                         vector[i]=double ( S[i] );break; 
    51                                 case Setting::TypeInt : 
    52                                         vector[i]=int ( S[i] );break; 
    53                                 case Setting::TypeBoolean : 
    54                                         vector[i]=bool ( S[i] );break; 
    55                                 default: it_error ( "libconfig error?" ); 
    56                         } 
    57                 } 
    58         } else if (S.getType() == Setting::TypeGroup) { 
    59                 vector = getvec(S["elements"]); 
    60                 int cols = S["cols"]; 
    61                 if (vector.length() != cols) {  
    62                         it_error("requested vector is a matrix"); 
    63                 } 
    64         } else { 
    65                 it_error("requested vector has invalid type"); 
    66         } 
    67         return vector; 
     569 
     570/*! 
     571@brief The main userinfo template class. You should derive this class whenever you need  
     572a new userinfo of a class which is compound from smaller elements (all having its 
     573own userinfo class prepared). 
     574*/ 
     575template<typename T> class ParticularUI : private UI 
     576{ 
     577        // to permit acces to the ParticularUI<T>::ui to the UI class 
     578        friend UI; 
     579 
     580        //! default constructor, which is intentionally declared as private 
     581        ParticularUI<T>( const string &className) : UI( className )  
     582        {        
     583        }; 
     584 
     585        //! the only instance of this class (each type T has its own instance) 
     586        //! which is used as a factory for processing related UI 
     587        static ParticularUI<T>& ui;      
     588 
     589        bdmroot* New() 
     590        { 
     591                return new T(); 
     592        } 
    68593}; 
    69594 
    70 //! construct itpp::mat from Setting of type Array, number of columns must be given 
    71 inline mat getmat ( Setting& S , int ncols ) { 
    72         CHECK_UITYPE ( S,TypeArray ); 
    73         mat tmp; 
    74         int nrows=S.getLength() /ncols; 
    75         int r=0,c=0; 
    76         tmp.set_size ( nrows, ncols ); 
    77         // Build matrix row-wise 
    78         for ( int i=0;i<S.getLength();i++ ) { 
    79                 switch ( S[i].getType() ) { 
    80                         case Setting::TypeFloat : 
    81                                 tmp ( r,c ) =double ( S[i] );break; 
    82                         case Setting::TypeInt : 
    83                                 tmp ( r,c ) =int ( S[i] );break; 
    84                         case Setting::TypeBoolean : 
    85                                 tmp ( r,c ) =bool ( S[i] );break; 
    86                         default: it_error ( "libconfig error?" ); 
    87                 } 
    88                 c++; if ( c==ncols ) {c=0;r++;} 
    89         } 
    90         return tmp; 
     595 
     596} 
     597 
     598/*! Recursive build of objects defined in the same file 
     599 
     600\code  
     601{type="internal"; 
     602path="system.profile.[0]";    // Path from the root  
    91603}; 
    92  
    93 //! construct itpp::mat from Setting of type Group containing settings 
    94 //! "elements" and "cols" 
    95 inline mat getmat (Setting & S) { 
    96         CHECK_UITYPE (S, TypeGroup); 
    97         return getmat(S["elements"], S["cols"]); 
    98 } 
    99  
    100 //! construct itpp::ivec from Setting of type Array 
    101  
    102 inline ivec getivec ( Setting& S ) { 
    103         CHECK_UITYPE ( S,TypeArray ); 
    104         ivec tmp; 
    105         tmp.set_size ( S.getLength() ); 
    106         for ( int i=0;i<S.getLength();i++ ) { 
    107                 switch ( S[i].getType() ) { 
    108                         case Setting::TypeFloat : 
    109                                 tmp[i]=double ( S[i] );break; 
    110                         case Setting::TypeInt : 
    111                                 tmp[i]=int ( S[i] );break; 
    112                         case Setting::TypeBoolean : 
    113                                 tmp[i]=bool ( S[i] );break; 
    114                         default: it_error ( "libconfig error?" ); 
    115                 } 
    116         } 
    117         return tmp; 
    118 }; 
    119  
    120 //! construct itpp::Array<string> from Setting of type Array 
    121  
    122 inline Array<string> get_as ( Setting& S ) { 
    123         CHECK_UITYPE ( S,TypeArray ); 
    124         Array<string> tmp; 
    125         tmp.set_size ( S.getLength() ); 
    126         for ( int i=0;i<S.getLength();i++ ) {tmp ( i ) = ( const char* ) S[i];} 
    127         return tmp; 
    128 }; 
    129  
    130 //!@} 
    131  
    132 /*!\brief Builds computational object from a UserInfo structure 
    133  
    134 Return value is a pointer to the created object (memory management issue?) 
    135 */ 
    136 class UIbuilder { 
    137 protected: 
    138 public: 
    139         //!Constructor needs to be run only once macro UIREGISTER 
    140         UIbuilder ( const string &typ ) {__uimap__.insert ( make_pair ( typ,this ) );} 
    141         //! Function building the computational object 
    142         virtual bdmroot* build ( Setting &S ) const =0; 
    143         //! Virtual destructor for future use; 
    144         virtual ~UIbuilder(){}; 
    145 }; 
     604\endcode 
     605 */ 
     606 
     607 
    146608 
    147609/*! Recursive build of objects defined in external file 
     
    153615}; 
    154616\endcode 
    155 */ 
    156 class UIexternal:public UIbuilder { 
    157 public: 
    158         UIexternal() :UIbuilder ( "external" ) {} 
    159         bdmroot* build ( Setting &S ) const; 
    160 }; 
    161  
    162 /*! Recursive build of objects defined in the same file 
    163  
    164 \code  
    165 {type="internal"; 
    166 path="system.profile.[0]";    // Path from the root  
    167 }; 
    168 \endcode 
    169  */ 
    170 class UIinternal:public UIbuilder { 
    171 public: 
    172         UIinternal() :UIbuilder ( "internal" ) {} 
    173         bdmroot* build ( Setting &S ) const; 
    174 }; 
     617/ 
     618 
    175619 
    176620//! [Debugging] Print values in current S to cout 
    177621void UI_DBG ( Setting &S, const string &spc ); 
    178622 
    179 //! Prototype of a UI builder. Return value is by the second argument since it type checking via \c dynamic_cast. 
    180 template<class T> 
    181 void UIbuild ( Setting &S, T* &ret ) { 
    182         CHECK_UITYPE ( S,TypeGroup ); 
    183         // Check if field "type" is present, if not it is not a valid UI 
    184         it_assert_debug ( S.exists ( "type" ), string ( S.getPath() ) +" is not a valid UI!" ); 
    185  
    186         const string typ=S["type"]; 
    187         // Find "type" in list of registred UI builders 
    188         UImap::const_iterator iter = __uimap__.find ( typ ); 
    189         if ( iter == __uimap__.end() ) { 
    190                 it_error ( "UI of type \"" + typ + "\" is not registered!" ); 
    191         } 
    192  
    193         //BUILD the result 
    194         try { 
    195                 ret = dynamic_cast<T*> ( iter->second->build ( S ) ); 
    196         } 
    197         catch UICATCH 
    198 }; 
    199  
     623 
     624/* 
    200625//! Auxiliary function allowing recursivity in S (too complex, remove?) 
    201626template<class T> 
    202627void UIcall ( Setting &S, void ( *func ) ( Setting&, T ), T Tmp ) { 
    203         CHECK_UITYPE ( S,TypeGroup ); 
    204         // Check if field "type" is present, if not it is not a valid UI 
    205         it_assert_debug ( S.exists ( "type" ), string ( S.getPath() ) +" is not a valid UI!" ); 
    206  
    207         const string typ=S["type"]; 
     628        ASSERT_UITYPE ( S,TypeGroup ); 
     629        // Check if field "class" is present, if not it is not a valid UI 
     630        it_assert_debug ( S.exists ( "class" ), string ( S.getPath() ) +" is not a valid UI!" ); 
     631 
     632        const string typ=S["class"]; 
    208633        if ( typ=="internal" ) { 
    209634                try { 
     
    235660 
    236661} 
    237 #endif //UIBUILD 
     662 
     663*/ 
     664 
     665#endif // #ifndef UIBUILD 
  • tests/UI/UIbuilder_test.cfg

    r278 r344  
    11//test 
    2 test: 
     2pepikovo :  
    33{ 
    4 type= "test"; 
    5 a= 1; 
    6 S= "hello!!!"; 
     4  class = "Car"; 
     5  year = 1998; 
     6  manufacturer = "audi"; 
     7  kilometers = 25000; 
    78}; 
    8 test2: 
     9jardovo :  
    910{ 
    10 type= "internal"; 
    11 path="int"; 
     11  class = "Car"; 
     12  year = 1992; 
     13  manufacturer = "liaz"; 
     14  kilometers = 1555000; 
    1215}; 
    13 test3: 
     16ondrejovo :  
    1417{ 
    15 type= "external"; 
    16 filename = "UIbuilder_test_ex.cfg"; 
    17 path="test2"; 
     18  class = "Bike"; 
     19  year = 1996; 
     20  manufacturer = "author"; 
     21  electricLights = true; 
     22  matr = ( 2, 2, [ 1.0, 0.0, 0.0, 1.0 ] ); 
    1823}; 
    19 int: 
    20 { 
    21 type= "test2"; 
    22 a= 1; 
    23 S= "yeah!!!"; 
    24 }; 
     24elisky : "jardovo"; 
     25kati : "skubankovo@UIbuilder_test_ex.cfg"; 
  • tests/UI/UIbuilder_test.cpp

    r278 r344  
    11#include <uibuilder.h> 
     2#include <string> 
    23 
    3 using namespace libconfig; 
     4using std::string; 
    45using namespace std; 
    56using namespace bdm; 
    67 
    7 class cls :public bdmroot{ 
    8         public: 
    9                 int a; 
    10                 string S; 
    11                 cls(int a0, string S0):a(a0),S(S0){}; 
    12                 virtual void print(){cout << a << " and "<< S << endl;} 
    13 }; 
    14 class cls2: public cls{ 
    15         public: 
    16         cls2(int a0, string S0):cls(a0,S0){}; 
    17         void print(){cout << a << " or "<< S << endl;} 
     8class Transport : public bdmroot 
     9{ 
     10public: 
     11        int year; 
     12        string manufacturer; 
     13 
     14        Transport() 
     15        { 
     16                year = 1900; 
     17                manufacturer = "unknown"; 
     18        } 
     19 
     20        Transport( int year, string manufacturer ) 
     21                : year( year ), manufacturer( manufacturer ) 
     22        { 
     23        } 
     24 
     25        virtual void FromSetting( const Setting &root ) 
     26        { 
     27                root.lookupValue( "year", year ); 
     28                root.lookupValue( "manufacturer", manufacturer ); 
     29        } 
     30 
     31        virtual void ToSetting( Setting &root )  
     32        {        
     33                Setting &year_setting = root.add("year", Setting::TypeInt ); 
     34                year_setting = year; 
     35 
     36                Setting &manufacturer_setting = root.add("manufacturer", Setting::TypeString ); 
     37                manufacturer_setting = manufacturer;     
     38        } 
    1839}; 
    1940 
    20 class UItest : public UIbuilder{ 
    21         public: 
    22         UItest():UIbuilder("test"){} 
    23         bdmroot* build(Setting &S) const{ 
    24                         int a=S["a"]; 
    25                         string St; 
    26                         S.lookupValue("S",St); 
    27                         cls* tmp = new cls(a,St); 
    28                         return tmp; 
    29         }        
     41class Car : public Transport 
     42{ 
     43public: 
     44        int kilometers; 
     45 
     46        Car() : Transport()                
     47        { 
     48                kilometers = 0; 
     49        } 
     50 
     51 
     52        Car( int year, string manufacturer, int kilometers ) 
     53                : Transport( year, manufacturer ), kilometers( kilometers ) 
     54        { 
     55        } 
     56 
     57        virtual void FromSetting( const Setting &root )  
     58        {        
     59                Transport::FromSetting( root ); 
     60 
     61                root.lookupValue( "kilometers", kilometers ); 
     62        } 
     63 
     64        virtual void ToSetting( Setting &root )  
     65        {        
     66                Transport::ToSetting( root ); 
     67 
     68                Setting &kilometers_setting = root.add("kilometers", Setting::TypeInt ); 
     69                kilometers_setting = kilometers; 
     70        } 
     71 
     72        string ToString() 
     73        { 
     74                stringstream stream; 
     75                stream << "a car made in " << year << " by " << manufacturer << ", having " << kilometers << " kilometers on the clock."; 
     76                return stream.str(); 
     77        } 
    3078}; 
    3179 
    32 class UItest2 : public UIbuilder{ 
    33         public: 
    34         UItest2():UIbuilder("test2"){} 
    35         bdmroot* build(Setting &S) const{ 
    36                         int a=S["a"]; 
    37                         string St; 
    38                         S.lookupValue("S",St); 
    39                         return  new cls2(a,St); 
    40         }        
    41         int no(){return 2;} 
     80UIREGISTER(Car); 
     81 
     82class Bike : public Transport 
     83{ 
     84public: 
     85        bool electricLights; 
     86        mat matr; 
     87 
     88        Bike() : Transport(), matr("2,2;3,4") 
     89        { 
     90                electricLights = false;          
     91        } 
     92 
     93        Bike( int year, string manufacturer, bool electricLights ) 
     94                : Transport( year, manufacturer ), electricLights( electricLights ) 
     95        { 
     96        } 
     97 
     98        ~Bike() 
     99        { 
     100        } 
     101 
     102        void FromSetting( const Setting &root )  
     103        {        
     104                Transport::FromSetting( root ); 
     105 
     106                root.lookupValue( "electricLights", electricLights ); 
     107 
     108                UI::Get( matr, root, "matr" ); 
     109        } 
     110 
     111        void ToSetting( Setting &root )  
     112        {        
     113                Transport::ToSetting( root ); 
     114 
     115                Setting &electricLights_setting = root.add("electricLights", Setting::TypeBoolean ); 
     116                electricLights_setting = electricLights; 
     117 
     118                UI::Save( matr, root, "matr" ); 
     119        } 
     120 
     121        string ToString() 
     122        { 
     123                stringstream stream; 
     124                stream << "a bike made in " << year << " by " << manufacturer; 
     125                if( electricLights ) stream << " with electric lights included";                                                 
     126                return stream.str(); 
     127        } 
    42128}; 
    43129 
    44 UIREGISTER(UItest); 
    45 UIREGISTER(UItest2); 
    46 //UItest* UItest_instance = new UItest(); 
    47 //UItest2* UItest2_instance = new UItest2(); 
     130UIREGISTER(Bike); 
    48131 
    49 int main(){ 
    50 UIFile UI("UIbuilder_test.cfg"); 
     132int main() 
     133{        
     134        /////////////////////////////////// SAVING ////////////////////////// 
     135        /* 
     136        Car audi( 1998, "audi", 25000); 
     137        Car liaz( 1992, "liaz", 1555000); 
     138        Bike author( 1996, "author", true ); 
    51139 
    52 cls* Cls; 
    53 UIbuild(UI.lookup("test"),Cls); 
    54 cls* Cls2; 
    55 UIbuild(UI.lookup("test2"),Cls2); 
    56 cls* Cls3; 
    57 UIbuild(UI.lookup("test3"),Cls3); 
     140        UIFile root("UIbuilder_test.cfg");       
     141        UI::Save( audi, root, "pepikovo"); 
     142        UI::Save( liaz, root, "jardovo");  
     143        UI::Save( author, root, "ondrejovo"); 
     144        root.Save(); 
    58145 
    59 Cls->print(); 
    60 Cls2->print(); 
    61 Cls3->print();  
    62  
    63 delete Cls; 
    64 delete Cls2; 
    65 delete Cls3; 
     146        cout << "all the transport means were saved correctly" << endl;                          
     147        getchar(); 
     148        */ 
     149         
     150        //////////////////////////////////// LOADING //////////////////////////////// 
     151        UIFile root("UIbuilder_test.cfg");       
     152        root.Load(); 
     153        Transport *pepikovo = UI::Build<Transport>( root, "pepikovo");   
     154        cout << "pepikovo: " << pepikovo->ToString() << endl;            
     155        Transport *jardovo = UI::Build<Transport>( root, "jardovo");     
     156        cout << "jardovo: " << jardovo->ToString() << endl;              
     157        Transport *ondrejovo = UI::Build<Transport>( root, "ondrejovo");         
     158        cout << "ondrejovo: " << ondrejovo->ToString() << endl;          
     159        Transport *elisky = UI::Build<Transport>( root, "elisky");       
     160        cout << "elisky: " << elisky->ToString() << endl;                
     161        Transport *kati = UI::Build<Transport>( root, "kati");   
     162        cout << "kati: " << kati->ToString() << endl;            
     163        getchar();  
     164        return 0; 
    66165} 
  • tests/UI/UIbuilder_test_ex.cfg

    r278 r344  
    1 test2: 
     1skubankovo :  
    22{ 
    3 type= "test2"; 
    4 a= 1; 
    5 S= "distant hello!!!"; 
     3  class = "Car"; 
     4  year = 1980; 
     5  manufacturer = "vecernicek"; 
     6  kilometers = 250000; 
    67};