#ifndef UIBUILD #define UIBUILD #include #include "stat/libBM.h" #include "libconfig/libconfig.h++" namespace bdm { using namespace libconfig; using namespace std; #define CHECK_UITYPE(S,Type) it_assert_debug(S.getType()==Setting::Type, string("Wrong input path \"")+string(S.getPath())+string("\"")); #define UIREGISTER(UI) UI* UI##_global_instance = new UI(); //!Standard catches for UIs, use as: catch UICATCH #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" );} ////////// GLOBAL VAriables class UIbuilder; //! Internal structure mapping strings to UIBuilder objects typedef map UImap; extern UImap __uimap__; class UIFile : public Config { public: UIFile ( const char * fname ) :Config() { try{Config::readFile ( fname );} catch ( FileIOException f ) {it_error ( "File " + string ( fname ) + " not found" );} catch ( ParseException& P ) { char msg[200]; sprintf ( msg,"Error in file %s on line %d.", fname, P.getLine() ); it_error ( msg ); } } }; //! \name elem Elementary build functions //!@{ //! construct itpp::vec from Setting of type Array inline vec getvec ( Setting& S ) { CHECK_UITYPE ( S,TypeArray ); vec tmp; tmp.set_size ( S.getLength() ); for ( int i=0;i from Setting of type Array inline Array get_as ( Setting& S ) { CHECK_UITYPE ( S,TypeArray ); Array tmp; tmp.set_size ( S.getLength() ); for ( int i=0;i void UIbuild ( Setting &S, T* &ret ) { CHECK_UITYPE ( S,TypeGroup ); // Check if field "type" is present, if not it is not a valid UI it_assert_debug ( S.exists ( "type" ), string ( S.getPath() ) +" is not a valid UI!" ); const string typ=S["type"]; // Find "type" in list of registred UI builders UImap::const_iterator iter = __uimap__.find ( typ ); if ( iter == __uimap__.end() ) { it_error ( "UI of type \"" + typ + "\" is not registered!" ); } //BUILD the result try { ret = dynamic_cast ( iter->second->build ( S ) ); } catch UICATCH }; //! Auxiliary function allowing recursivity in S (too complex, remove?) template void UIcall ( Setting &S, void ( *func ) ( Setting&, T ), T Tmp ) { CHECK_UITYPE ( S,TypeGroup ); // Check if field "type" is present, if not it is not a valid UI it_assert_debug ( S.exists ( "type" ), string ( S.getPath() ) +" is not a valid UI!" ); const string typ=S["type"]; if ( typ=="internal" ) { try { Setting* Stmp = &S; do {Stmp=& ( Stmp->getParent() );} while ( !Stmp->isRoot() ); Setting& intS=Stmp->lookup ( ( const char* ) S["path"] ); func ( intS, Tmp ); // <======== calling func return; } catch ( ... ) { it_error ( "Internal field " + string ( S.getPath() ) + " not valid" ); } } if ( typ=="external" ) { UIFile C ( S["filename"] ); try { func ( C.lookup ( ( const char* ) S["path"] ), Tmp ); } catch ( ... ) { it_error ( "External field " + string ( S.getPath() ) + " not valid" ); } return; } // v======================= calling final func func ( S, Tmp ); }; } #endif //UIBUILD