- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

# uibuilder.h

    00001 #ifndef UIBUILD
    00002 #define UIBUILD
    00003
    00004 #include <itpp/itbase.h>
    00005 #include "stat/libBM.h"
    00006 #include "libconfig/libconfig.h++"
    00007
    00008 namespace bdm {
    00009
    00010         using namespace libconfig;
    00011         using namespace std;
    00012
    00013 #define CHECK_UITYPE(S,Type) it_assert_debug(S.getType()==Setting::Type, string("Wrong input path \"")+string(S.getPath())+string("\""));
    00014 #define UIREGISTER(UI) UI* UI##_global_instance = new UI();
    00015
    00017
    00018         class UIbuilder;
    00020         typedef map<const string, const UIbuilder*> UImap;
    00021         extern UImap __uimap__;
    00022
    00023         class UIFile : public Config {
    00024         public:
    00025                 UIFile ( const char * fname ) :Config() {
    00026                         try{Config::readFile ( fname );}
    00027                         catch ( ParseException& P ) {
    00028                                 char msg[200];
    00029                                 sprintf ( msg,"Error in file %s  on line %d.", fname, P.getLine() );
    00030                                 it_error ( msg );
    00031                         }
    00032                         catch ( FileIOException f ) {it_error ( "File " + string ( fname ) + " not found" );}
    00033                 }
    00034         };
    00035
    00040         class UIbuilder {
    00041         protected:
    00042                 const vec getvec ( Setting& S ) const {
    00043                         CHECK_UITYPE ( S,TypeArray );
    00044                         vec tmp;
    00045                         tmp.set_size ( S.getLength() );
    00046                         for ( int i=0;i<S.getLength();i++ ) {
    00047                                 switch ( S[i].getType() ) {
    00048                                         case Setting::TypeFloat :
    00049                                                 tmp[i]=double ( S[i] );break;
    00050                                         case Setting::TypeInt :
    00051                                                 tmp[i]=int ( S[i] );break;
    00052                                         case Setting::TypeBoolean :
    00053                                                 tmp[i]=bool ( S[i] );break;
    00054                                         default: it_error ( "libconfig error?" );
    00055                                 }
    00056                         }
    00057                         return tmp;
    00058                 };
    00059                 const mat getmat ( Setting& S , int ncols) const {
    00060                         CHECK_UITYPE ( S,TypeArray );
    00061                         mat tmp;
    00062                         int nrows=S.getLength()/ncols;
    00063                         int r=0,c=0;
    00064                         tmp.set_size ( nrows, ncols );
    00065                         // Build matrix row-wise
    00066                         for ( int i=0;i<S.getLength();i++ ) {
    00067                                 switch ( S[i].getType() ) {
    00068                                         case Setting::TypeFloat :
    00069                                                 tmp(r,c)=double ( S[i] );break;
    00070                                         case Setting::TypeInt :
    00071                                                 tmp(r,c)=int ( S[i] );break;
    00072                                         case Setting::TypeBoolean :
    00073                                                 tmp(r,c)=bool ( S[i] );break;
    00074                                         default: it_error ( "libconfig error?" );
    00075                                 }
    00076                                 c++; if (c==ncols) {c=0;r++;}
    00077                         }
    00078                         return tmp;
    00079                 };
    00080                 const vec getivec ( Setting& S ) const {
    00081                         CHECK_UITYPE ( S,TypeArray );
    00082                         vec tmp;
    00083                         tmp.set_size ( S.getLength() );
    00084                         for ( int i=0;i<S.getLength();i++ ) {
    00085                                 switch ( S[i].getType() ) {
    00086                                         case Setting::TypeFloat :
    00087                                                 tmp[i]=double ( S[i] );break;
    00088                                         case Setting::TypeInt :
    00089                                                 tmp[i]=int ( S[i] );break;
    00090                                         case Setting::TypeBoolean :
    00091                                                 tmp[i]=bool ( S[i] );break;
    00092                                         default: it_error ( "libconfig error?" );
    00093                                 }
    00094                         }
    00095                         return tmp;
    00096                 };
    00097         public:
    00099                 UIbuilder ( const string &typ ) {__uimap__.insert ( make_pair ( typ,this ) );}
    00101                 virtual bdmroot* build ( Setting &S ) const =0;
    00102         };
    00103
    00104         class UIexternal:public UIbuilder {
    00105         public:
    00106                 UIexternal() :UIbuilder ( "external" ) {}
    00107                 bdmroot* build ( Setting &S ) const;
    00108         };
    00109
    00110         class UIinternal:public UIbuilder {
    00111         public:
    00112                 UIinternal() :UIbuilder ( "internal" ) {}
    00113                 bdmroot* build ( Setting &S ) const;
    00114         };
    00115
    00117         void UI_DBG ( Setting &S, const string &spc );
    00118
    00120         template<class T>
    00121         void UIbuild ( Setting &S, T* &ret ) {
    00122                 CHECK_UITYPE ( S,TypeGroup );
    00123                 // Check if field "type" is present, if not it is not a valid UI
    00124                 it_assert_debug ( S.exists ( "type" ), string ( S.getPath() ) +" is not a valid UI!" );
    00125
    00126                 const string typ=S["type"];
    00127                 // Find "type" in list of registred UI builders
    00128                 UImap::const_iterator iter = __uimap__.find ( typ );
    00129                 if ( iter == __uimap__.end() ) {
    00130                         it_error ( "UI of type \"" + typ + "\" is not registered!" );
    00131                 }
    00132
    00133                 //BUILD the result
    00134                 try {
    00135                         ret = dynamic_cast<T*> ( iter->second->build ( S ) );
    00136                 }
    00137                 catch ( SettingTypeException e ) {
    00138                         UI_DBG(S,"");
    00139                         it_error ( "Setting " +string ( e.getPath() ) +" is of incorrect Type" );}
    00140                 catch ( SettingNotFoundException e ) {
    00141                         UI_DBG(S,"");
    00142                         it_error ( "Setting " + string ( e.getPath() ) +" was not found" );}
    00143         };
    00144
    00146         template<class T>
    00147         void UIcall ( Setting &S, void ( *func ) ( Setting&, T ), T Tmp ) {
    00148                 CHECK_UITYPE ( S,TypeGroup );
    00149                 // Check if field "type" is present, if not it is not a valid UI
    00150                 it_assert_debug ( S.exists ( "type" ), string ( S.getPath() ) +" is not a valid UI!" );
    00151
    00152                 const string typ=S["type"];
    00153                 if ( typ=="internal" ) {
    00154                         try {
    00155                                 Setting* Stmp = &S;
    00156                                 do {Stmp=& ( Stmp->getParent() );}
    00157                                 while ( !Stmp->isRoot() );
    00158                                 Setting& intS=Stmp->lookup ( ( const char* ) S["path"] );
    00159                                 func ( intS, Tmp ); // <======== calling func
    00160                                 return;
    00161                         }
    00162                         catch ( ... ) {
    00163                                 it_error ( "Internal field " + string ( S.getPath() ) + " not valid" );
    00164                         }
    00165                 }
    00166                 if ( typ=="external" ) {
    00167                         UIFile C(S["filename"]);
    00168                         try {
    00169                                 func ( C.lookup ( ( const char* ) S["path"] ), Tmp );
    00170                         }
    00171                         catch ( ... ) {
    00172                                 it_error ( "External field " + string ( S.getPath() ) + " not valid" );
    00173                         }
    00174                         return;
    00175                 }
    00176
    00177                 // v======================= calling final func
    00178                 func ( S, Tmp );
    00179         };
    00180
    00181 }
    00182 #endif //UIBUILD