root/bdm/uibuilder.h @ 263

Revision 263, 5.2 kB (checked in by smidl, 16 years ago)

UIArxDS test

RevLine 
[254]1#ifndef UIBUILD
2#define UIBUILD
3
[243]4#include <itpp/itbase.h>
[254]5#include "stat/libBM.h"
[256]6#include "libconfig/libconfig.h++"
[243]7
[260]8namespace bdm {
[243]9
[260]10        using namespace libconfig;
11        using namespace std;
[246]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////////// GLOBAL VAriables
17
[260]18        class UIbuilder;
[246]19//! Internal structure mapping strings to UIBuilder objects
[260]20        typedef map<const string, const UIbuilder*> UImap;
21        extern UImap __uimap__;
[246]22
[260]23        class UIFile : public Config {
[243]24        public:
[260]25                UIFile ( const char * fname ) :Config() {
26                        try{Config::readFile ( fname );}
27                        catch ( ParseException& P ) {
28                                char msg[200];
29                                sprintf ( msg,"Error in file %s  on line %d.", fname, P.getLine() );
30                                it_error ( msg );
31                        }
32                        catch ( FileIOException f ) {it_error ( "File " + string ( fname ) + " not found" );}
33                }
34        };
[246]35
[260]36        /*!\brief Builds computational object from a UserInfo structure
[246]37
[260]38        Return value is a pointer to the created object (memory management issue?)
39        */
40        class UIbuilder {
[246]41        protected:
[260]42                const vec getvec ( Setting& S ) const {
43                        CHECK_UITYPE ( S,TypeArray );
44                        vec tmp;
45                        tmp.set_size ( S.getLength() );
46                        for ( int i=0;i<S.getLength();i++ ) {
47                                switch ( S[i].getType() ) {
48                                        case Setting::TypeFloat :
49                                                tmp[i]=double ( S[i] );break;
50                                        case Setting::TypeInt :
51                                                tmp[i]=int ( S[i] );break;
52                                        case Setting::TypeBoolean :
53                                                tmp[i]=bool ( S[i] );break;
54                                        default: it_error ( "libconfig error?" );
55                                }
56                        }
57                        return tmp;
58                };
[263]59                const mat getmat ( Setting& S , int ncols) const {
60                        CHECK_UITYPE ( S,TypeArray );
61                        mat tmp;
62                        int nrows=S.getLength()/ncols;
63                        int r=0,c=0;
64                        tmp.set_size ( nrows, ncols );
65                        // Build matrix row-wise
66                        for ( int i=0;i<S.getLength();i++ ) {
67                                switch ( S[i].getType() ) {
68                                        case Setting::TypeFloat :
69                                                tmp(r,c)=double ( S[i] );break;
70                                        case Setting::TypeInt :
71                                                tmp(r,c)=int ( S[i] );break;
72                                        case Setting::TypeBoolean :
73                                                tmp(r,c)=bool ( S[i] );break;
74                                        default: it_error ( "libconfig error?" );
75                                }
76                                c++; if (c==ncols) {c=0;r++;}
77                        }
78                        return tmp;
79                };
[260]80                const vec getivec ( Setting& S ) const {
81                        CHECK_UITYPE ( S,TypeArray );
82                        vec tmp;
83                        tmp.set_size ( S.getLength() );
84                        for ( int i=0;i<S.getLength();i++ ) {
85                                switch ( S[i].getType() ) {
86                                        case Setting::TypeFloat :
87                                                tmp[i]=double ( S[i] );break;
88                                        case Setting::TypeInt :
89                                                tmp[i]=int ( S[i] );break;
90                                        case Setting::TypeBoolean :
91                                                tmp[i]=bool ( S[i] );break;
92                                        default: it_error ( "libconfig error?" );
93                                }
94                        }
95                        return tmp;
96                };
[246]97        public:
[257]98                //!Constructor needs to be run only once macro UIREGISTER
[260]99                UIbuilder ( const string &typ ) {__uimap__.insert ( make_pair ( typ,this ) );}
[256]100                //! Function building the computational object
[260]101                virtual bdmroot* build ( Setting &S ) const =0;
102        };
[243]103
[260]104        class UIexternal:public UIbuilder {
[246]105        public:
[260]106                UIexternal() :UIbuilder ( "external" ) {}
107                bdmroot* build ( Setting &S ) const;
108        };
[246]109
[260]110        class UIinternal:public UIbuilder {
[246]111        public:
[260]112                UIinternal() :UIbuilder ( "internal" ) {}
113                bdmroot* build ( Setting &S ) const;
114        };
[246]115
[260]116        //! [Debugging] Print values in current S to cout
117        void UI_DBG ( Setting &S, const string &spc );
118
[257]119//! Prototype of a UI builder. Return value is by the second argument since it type checking via \c dynamic_cast.
[260]120        template<class T>
121        void UIbuild ( Setting &S, T* &ret ) {
122                CHECK_UITYPE ( S,TypeGroup );
123                // Check if field "type" is present, if not it is not a valid UI
124                it_assert_debug ( S.exists ( "type" ), string ( S.getPath() ) +" is not a valid UI!" );
[246]125
[260]126                const string typ=S["type"];
127                // Find "type" in list of registred UI builders
128                UImap::const_iterator iter = __uimap__.find ( typ );
129                if ( iter == __uimap__.end() ) {
130                        it_error ( "UI of type \"" + typ + "\" is not registered!" );
[257]131                }
[260]132
133                //BUILD the result
134                try {
135                        ret = dynamic_cast<T*> ( iter->second->build ( S ) );
[257]136                }
[260]137                catch ( SettingTypeException e ) {
138                        UI_DBG(S,""); 
139                        it_error ( "Setting " +string ( e.getPath() ) +" is of incorrect Type" );}
140                catch ( SettingNotFoundException e ) {
141                        UI_DBG(S,"");
142                        it_error ( "Setting " + string ( e.getPath() ) +" was not found" );}
143        };
144
145//! Auxiliary function allowing recursivity in S (too complex, remove?)
146        template<class T>
147        void UIcall ( Setting &S, void ( *func ) ( Setting&, T ), T Tmp ) {
148                CHECK_UITYPE ( S,TypeGroup );
149                // Check if field "type" is present, if not it is not a valid UI
150                it_assert_debug ( S.exists ( "type" ), string ( S.getPath() ) +" is not a valid UI!" );
151
152                const string typ=S["type"];
153                if ( typ=="internal" ) {
154                        try {
155                                Setting* Stmp = &S;
156                                do {Stmp=& ( Stmp->getParent() );}
157                                while ( !Stmp->isRoot() );
158                                Setting& intS=Stmp->lookup ( ( const char* ) S["path"] );
159                                func ( intS, Tmp ); // <======== calling func
160                                return;
161                        }
162                        catch ( ... ) {
163                                it_error ( "Internal field " + string ( S.getPath() ) + " not valid" );
164                        }
[257]165                }
[260]166                if ( typ=="external" ) {
167                        UIFile C(S["filename"]);
168                        try {
169                                func ( C.lookup ( ( const char* ) S["path"] ), Tmp );
170                        }
171                        catch ( ... ) {
172                                it_error ( "External field " + string ( S.getPath() ) + " not valid" );
173                        }
174                        return;
[257]175                }
176
[260]177                // v======================= calling final func
178                func ( S, Tmp );
179        };
180
[254]181}
[260]182#endif //UIBUILD
Note: See TracBrowser for help on using the browser.