#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(); ////////// 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 (ParseException& P) { char msg[200]; sprintf(msg,"Error in file %s on line %d.", fname, P.getLine()); it_error(msg); } catch (FileIOException f) {it_error("File " + string(fname) + " not found");} } }; /*!\brief Builds computational object from a UserInfo structure Return value is a pointer to the created object (memory management issue?) */ class UIbuilder { protected: static const UIbuilder* theinstance; vec getvec ( Setting& S ) { CHECK_UITYPE(S,TypeArray); vec 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 ret = dynamic_cast(iter->second->build(S)); }; //! Auxiliary function allowing recursivity in S 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 UIset return; } catch (...) { it_error("Internal field " + string(S.getPath()) + " not valid"); } } if(typ=="extern"){ Config C; bdmroot* tmp; try{C.readFile((const char*)S["filename"]);} catch (...){ it_error("File " + string((const char*)S["filename"]) + " not found or broken"); } try {func(C.lookup((const char*)S["path"]), Tmp);} catch (...) { //<=========== calling UIset it_error("External field " + string(S.getPath()) + " not valid"); } return; } // v======================= calling final set func(S, Tmp); }; } #endif UIBUILD