- Main Page
- Related Pages
- Modules
- 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 #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" );}
    00018
    00020
    00021 class UIbuilder;
    00023 typedef map<const string, const UIbuilder*> UImap;
    00024 extern UImap __uimap__;
    00025
    00026 class UIFile : public Config {
    00027 public:
    00028         UIFile ( const char * fname ) :Config() {
    00029                 try{Config::readFile ( fname );}
    00030                 catch ( FileIOException f ) {it_error ( "File " + string ( fname ) + " not found" );}
    00031                 catch ( ParseException& P ) {
    00032                         char msg[200];
    00033                         sprintf ( msg,"Error in file %s  on line %d.", fname, P.getLine() );
    00034                         it_error ( msg );
    00035                 }
    00036         }
    00037 };
    00038
    00041
    00043 inline vec getvec ( Setting& S ) {
    00044         CHECK_UITYPE ( S,TypeArray );
    00045         vec tmp;
    00046         tmp.set_size ( S.getLength() );
    00047         for ( int i=0;i<S.getLength();i++ ) {
    00048                 switch ( S[i].getType() ) {
    00049                         case Setting::TypeFloat :
    00050                                 tmp[i]=double ( S[i] );break;
    00051                         case Setting::TypeInt :
    00052                                 tmp[i]=int ( S[i] );break;
    00053                         case Setting::TypeBoolean :
    00054                                 tmp[i]=bool ( S[i] );break;
    00055                         default: it_error ( "libconfig error?" );
    00056                 }
    00057         }
    00058         return tmp;
    00059 };
    00060
    00062 inline mat getmat ( Setting& S , int ncols ) {
    00063         CHECK_UITYPE ( S,TypeArray );
    00064         mat tmp;
    00065         int nrows=S.getLength() /ncols;
    00066         int r=0,c=0;
    00067         tmp.set_size ( nrows, ncols );
    00068         // Build matrix row-wise
    00069         for ( int i=0;i<S.getLength();i++ ) {
    00070                 switch ( S[i].getType() ) {
    00071                         case Setting::TypeFloat :
    00072                                 tmp ( r,c ) =double ( S[i] );break;
    00073                         case Setting::TypeInt :
    00074                                 tmp ( r,c ) =int ( S[i] );break;
    00075                         case Setting::TypeBoolean :
    00076                                 tmp ( r,c ) =bool ( S[i] );break;
    00077                         default: it_error ( "libconfig error?" );
    00078                 }
    00079                 c++; if ( c==ncols ) {c=0;r++;}
    00080         }
    00081         return tmp;
    00082 };
    00083
    00085
    00086 inline ivec getivec ( Setting& S ) {
    00087         CHECK_UITYPE ( S,TypeArray );
    00088         ivec tmp;
    00089         tmp.set_size ( S.getLength() );
    00090         for ( int i=0;i<S.getLength();i++ ) {
    00091                 switch ( S[i].getType() ) {
    00092                         case Setting::TypeFloat :
    00093                                 tmp[i]=double ( S[i] );break;
    00094                         case Setting::TypeInt :
    00095                                 tmp[i]=int ( S[i] );break;
    00096                         case Setting::TypeBoolean :
    00097                                 tmp[i]=bool ( S[i] );break;
    00098                         default: it_error ( "libconfig error?" );
    00099                 }
    00100         }
    00101         return tmp;
    00102 };
    00103
    00105
    00106 inline Array<string> get_as ( Setting& S ) {
    00107         CHECK_UITYPE ( S,TypeArray );
    00108         Array<string> tmp;
    00109         tmp.set_size ( S.getLength() );
    00110         for ( int i=0;i<S.getLength();i++ ) {tmp ( i ) = ( const char* ) S[i];}
    00111         return tmp;
    00112 };
    00113
    00115
    00120 class UIbuilder {
    00121 protected:
    00122 public:
    00124         UIbuilder ( const string &typ ) {__uimap__.insert ( make_pair ( typ,this ) );}
    00126         virtual bdmroot* build ( Setting &S ) const =0;
    00127 };
    00128
    00138 class UIexternal:public UIbuilder {
    00139 public:
    00140         UIexternal() :UIbuilder ( "external" ) {}
    00141         bdmroot* build ( Setting &S ) const;
    00142 };
    00143
    00152 class UIinternal:public UIbuilder {
    00153 public:
    00154         UIinternal() :UIbuilder ( "internal" ) {}
    00155         bdmroot* build ( Setting &S ) const;
    00156 };
    00157
    00159 void UI_DBG ( Setting &S, const string &spc );
    00160
    00162 template<class T>
    00163 void UIbuild ( Setting &S, T* &ret ) {
    00164         CHECK_UITYPE ( S,TypeGroup );
    00165         // Check if field "type" is present, if not it is not a valid UI
    00166         it_assert_debug ( S.exists ( "type" ), string ( S.getPath() ) +" is not a valid UI!" );
    00167
    00168         const string typ=S["type"];
    00169         // Find "type" in list of registred UI builders
    00170         UImap::const_iterator iter = __uimap__.find ( typ );
    00171         if ( iter == __uimap__.end() ) {
    00172                 it_error ( "UI of type \"" + typ + "\" is not registered!" );
    00173         }
    00174
    00175         //BUILD the result
    00176         try {
    00177                 ret = dynamic_cast<T*> ( iter->second->build ( S ) );
    00178         }
    00179         catch UICATCH
    00180 };
    00181
    00183 template<class T>
    00184 void UIcall ( Setting &S, void ( *func ) ( Setting&, T ), T Tmp ) {
    00185         CHECK_UITYPE ( S,TypeGroup );
    00186         // Check if field "type" is present, if not it is not a valid UI
    00187         it_assert_debug ( S.exists ( "type" ), string ( S.getPath() ) +" is not a valid UI!" );
    00188
    00189         const string typ=S["type"];
    00190         if ( typ=="internal" ) {
    00191                 try {
    00192                         Setting* Stmp = &S;
    00193                         do {Stmp=& ( Stmp->getParent() );}
    00194                         while ( !Stmp->isRoot() );
    00195                         Setting& intS=Stmp->lookup ( ( const char* ) S["path"] );
    00196                         func ( intS, Tmp ); // <======== calling func
    00197                         return;
    00198                 }
    00199                 catch ( ... ) {
    00200                         it_error ( "Internal field " + string ( S.getPath() ) + " not valid" );
    00201                 }
    00202         }
    00203         if ( typ=="external" ) {
    00204                 UIFile C ( S["filename"] );
    00205                 try {
    00206                         func ( C.lookup ( ( const char* ) S["path"] ), Tmp );
    00207                 }
    00208                 catch ( ... ) {
    00209                         it_error ( "External field " + string ( S.getPath() ) + " not valid" );
    00210                 }
    00211                 return;
    00212         }
    00213
    00214         // v======================= calling final func
    00215         func ( S, Tmp );
    00216 };
    00217
    00218 }
    00219 #endif //UIBUILD