root/bdm/uibuilder.h @ 278

Revision 278, 5.4 kB (checked in by smidl, 15 years ago)

props

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