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

- File List
- File Members

# 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                 setAutoConvert(true);
    00037         }
    00038 };
    00039
    00042
    00044 inline vec getvec ( Setting& S ) {
    00045         vec vector;
    00046         if (S.getType() == Setting::TypeArray) {
    00047                 vector.set_size ( S.getLength() );
    00048                 for ( int i=0;i<S.getLength();i++ ) {
    00049                         switch ( S[i].getType() ) {
    00050                                 case Setting::TypeFloat :
    00051                                         vector[i]=double ( S[i] );break;
    00052                                 case Setting::TypeInt :
    00053                                         vector[i]=int ( S[i] );break;
    00054                                 case Setting::TypeBoolean :
    00055                                         vector[i]=bool ( S[i] );break;
    00056                                 default: it_error ( "libconfig error?" );
    00057                         }
    00058                 }
    00059         } else if (S.getType() == Setting::TypeGroup) {
    00060                 vector = getvec(S["elements"]);
    00061                 int cols = S["cols"];
    00062                 if (vector.length() != cols) {
    00063                         it_error("requested vector is a matrix");
    00064                 }
    00065         } else {
    00066                 it_error("requested vector has invalid type");
    00067         }
    00068         return vector;
    00069 };
    00070
    00072 inline mat getmat ( Setting& S , int ncols ) {
    00073         CHECK_UITYPE ( S,TypeArray );
    00074         mat tmp;
    00075         int nrows=S.getLength() /ncols;
    00076         int r=0,c=0;
    00077         tmp.set_size ( nrows, ncols );
    00078         // Build matrix row-wise
    00079         for ( int i=0;i<S.getLength();i++ ) {
    00080                 switch ( S[i].getType() ) {
    00081                         case Setting::TypeFloat :
    00082                                 tmp ( r,c ) =double ( S[i] );break;
    00083                         case Setting::TypeInt :
    00084                                 tmp ( r,c ) =int ( S[i] );break;
    00085                         case Setting::TypeBoolean :
    00086                                 tmp ( r,c ) =bool ( S[i] );break;
    00087                         default: it_error ( "libconfig error?" );
    00088                 }
    00089                 c++; if ( c==ncols ) {c=0;r++;}
    00090         }
    00091         return tmp;
    00092 };
    00093
    00096 inline mat getmat (Setting & S) {
    00097         CHECK_UITYPE (S, TypeGroup);
    00098         return getmat(S["elements"], S["cols"]);
    00099 }
    00100
    00102
    00103 inline ivec getivec ( Setting& S ) {
    00104         CHECK_UITYPE ( S,TypeArray );
    00105         ivec tmp;
    00106         tmp.set_size ( S.getLength() );
    00107         for ( int i=0;i<S.getLength();i++ ) {
    00108                 switch ( S[i].getType() ) {
    00109                         case Setting::TypeFloat :
    00110                                 tmp[i]=double ( S[i] );break;
    00111                         case Setting::TypeInt :
    00112                                 tmp[i]=int ( S[i] );break;
    00113                         case Setting::TypeBoolean :
    00114                                 tmp[i]=bool ( S[i] );break;
    00115                         default: it_error ( "libconfig error?" );
    00116                 }
    00117         }
    00118         return tmp;
    00119 };
    00120
    00122
    00123 inline Array<string> get_as ( Setting& S ) {
    00124         //CHECK_UITYPE ( S,TypeArray );
    00125         Array<string> tmp;
    00126         tmp.set_size ( S.getLength() );
    00127         for ( int i=0;i<S.getLength();i++ ) {tmp ( i ) = ( const char* ) S[i];}
    00128         return tmp;
    00129 };
    00130
    00132
    00137 class UIbuilder {
    00138 protected:
    00139 public:
    00141         UIbuilder ( const string &typ ) {__uimap__.insert ( make_pair ( typ,this ) );}
    00143         virtual bdmroot* build ( Setting &S ) const =0;
    00145         virtual ~UIbuilder(){};
    00146 };
    00147
    00157 class UIexternal:public UIbuilder {
    00158 public:
    00159         UIexternal() :UIbuilder ( "external" ) {}
    00160         bdmroot* build ( Setting &S ) const;
    00161 };
    00162
    00171 class UIinternal:public UIbuilder {
    00172 public:
    00173         UIinternal() :UIbuilder ( "internal" ) {}
    00174         bdmroot* build ( Setting &S ) const;
    00175 };
    00176
    00178 void UI_DBG ( Setting &S, const string &spc );
    00179
    00181 template<class T>
    00182 void UIbuild ( Setting &S, T* &ret ) {
    00183         CHECK_UITYPE ( S,TypeGroup );
    00184         // Check if field "type" is present, if not it is not a valid UI
    00185         it_assert_debug ( S.exists ( "type" ), string ( S.getPath() ) +" is not a valid UI!" );
    00186
    00187         const string typ=S["type"];
    00188         // Find "type" in list of registred UI builders
    00189         UImap::const_iterator iter = __uimap__.find ( typ );
    00190         if ( iter == __uimap__.end() ) {
    00191                 it_error ( "UI of type \"" + typ + "\" is not registered!" );
    00192         }
    00193
    00194         //BUILD the result
    00195         try {
    00196                 ret = dynamic_cast<T*> ( iter->second->build ( S ) );
    00197         }
    00198         catch UICATCH
    00199 };
    00200
    00202 template<class T>
    00203 void UIcall ( Setting &S, void ( *func ) ( Setting&, T ), T Tmp ) {
    00204         CHECK_UITYPE ( S,TypeGroup );
    00205         // Check if field "type" is present, if not it is not a valid UI
    00206         it_assert_debug ( S.exists ( "type" ), string ( S.getPath() ) +" is not a valid UI!" );
    00207
    00208         const string typ=S["type"];
    00209         if ( typ=="internal" ) {
    00210                 try {
    00211                         Setting* Stmp = &S;
    00212                         do {Stmp=& ( Stmp->getParent() );}
    00213                         while ( !Stmp->isRoot() );
    00214                         Setting& intS=Stmp->lookup ( ( const char* ) S["path"] );
    00215                         func ( intS, Tmp ); // <======== calling func
    00216                         return;
    00217                 }
    00218                 catch ( ... ) {
    00219                         it_error ( "Internal field " + string ( S.getPath() ) + " not valid" );
    00220                 }
    00221         }
    00222         if ( typ=="external" ) {
    00223                 UIFile C ( S["filename"] );
    00224                 try {
    00225                         func ( C.lookup ( ( const char* ) S["path"] ), Tmp );
    00226                 }
    00227                 catch ( ... ) {
    00228                         it_error ( "External field " + string ( S.getPath() ) + " not valid" );
    00229                 }
    00230                 return;
    00231         }
    00232
    00233         // v======================= calling final func
    00234         func ( S, Tmp );
    00235 };
    00236
    00237 }
    00238 #endif //UIBUILD