00001 #ifndef UIBUILD
00002 #define UIBUILD
00003
00004 #include "libconfig/libconfig.h++"
00005 #include <itpp/itbase.h>
00006 #include "stat/libBM.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 static const UIbuilder* theinstance;
00043 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 vec getivec ( Setting& S ) {
00061 CHECK_UITYPE(S,TypeArray);
00062 vec tmp;
00063 tmp.set_size ( S.getLength() );
00064 for ( int i=0;i<S.getLength();i++ ) {
00065 switch (S[i].getType()) {
00066 case Setting::TypeFloat :
00067 tmp[i]=double(S[i]);break;
00068 case Setting::TypeInt :
00069 tmp[i]=int(S[i]);break;
00070 case Setting::TypeBoolean :
00071 tmp[i]=bool(S[i]);break;
00072 default: it_error("libconfig error?");
00073 }
00074 }
00075 return tmp;
00076 };
00077 public:
00078 UIbuilder(const string &typ){__uimap__.insert(make_pair(typ,this));}
00079 virtual void build(Setting &S, void** result) const =0;
00080 };
00081
00082 class UIexternal:public UIbuilder{
00083 public:
00084 UIexternal():UIbuilder("external"){}
00085 void build(Setting &S, void** result) const;
00086 };
00087
00088 class UIinternal:public UIbuilder{
00089 public:
00090 UIinternal():UIbuilder("internal"){}
00091 void build(Setting &S, void** result) const;
00092 };
00093
00095 template<class T>
00096 void UIbuild(Setting &S, T** ret){
00097 CHECK_UITYPE(S,TypeGroup);
00098 T* tmp;
00099
00100 it_assert_debug(S.exists("type"), string(S.getPath())+" is not a valid UI!");
00101
00102 const string typ=S["type"];
00103
00104 UImap::const_iterator iter = __uimap__.find( typ );
00105 if( iter == __uimap__.end()) {
00106 it_error("UI of type \"" + typ + "\" is not registered!");
00107 }
00108 else {
00109 const UIbuilder* is= iter->second;
00110
00111 is->build(S,reinterpret_cast<void**>(&tmp));
00112 }
00113
00114 *ret=tmp;
00115 };
00116
00117 }
00118 #endif UIBUILD