00001 #ifndef MODULES_HEADER_
00002 #define MODULES_HEADER_
00003
00004
00005 class Module;
00006 class ModuleFactory;
00007 template <class Iface> class Interface;
00008
00009
00011
00012 class Module {
00013 friend class ModuleFactory;
00014
00015 public:
00017 enum CloneMethod { ShallowCopy, DeepCopy };
00019 enum ChoiceType {
00020 Stop,
00021 Int,
00022 IntLog2,
00023 Float,
00024 ModuleCombo,
00025 Combo
00026 };
00028 union SettingValue {
00029 int i;
00030 float f;
00031 };
00033 struct SettingType {
00034 ChoiceType type;
00035 SettingValue defaults;
00036
00037 union {
00038 int i[2];
00039 float f[2];
00040 const char *text;
00041
00043 const std::vector<int> *compatIDs;
00044 } data;
00045 };
00046
00048 struct SettingTypeItem {
00049 static const SettingTypeItem stopper;
00050
00051 const char *label
00052 , *desc;
00053 SettingType type;
00054 };
00055
00057 struct SettingItem {
00058 Module *m;
00059 SettingValue val;
00060
00062 SettingItem(): m(0) { DEBUG_ONLY( val.f= std::numeric_limits<float>::quiet_NaN(); ) }
00063
00065 SettingItem(const SettingTypeItem &typeItem): m(0), val(typeItem.type.defaults) {}
00066
00068 ~SettingItem() { delete m; }
00069 };
00070
00072 struct TypeInfo {
00073 int id;
00074 const char *name
00075 , *desc;
00076 int setLength;
00077 const SettingTypeItem *setType;
00078 };
00079
00080
00081 protected:
00082 SettingItem *settings;
00083
00086 private:
00088 SettingItem* copySettings(CloneMethod method) const;
00090 void initDefaultModuleLinks();
00092 void nullModuleLinks();
00094 void createDefaultSettings();
00095
00097 Module& operator=(const Module&);
00099 Module(const Module&);
00101 protected:
00103 Module(): settings(0) {}
00104
00107 virtual Module* abstractClone(CloneMethod method) const =0;
00108 public:
00110 template<class M> M* concreteClone(CloneMethod method) const;
00111
00112 public:
00114 virtual ~Module()
00115 { delete[] settings; }
00116
00119 virtual const TypeInfo& info() const =0;
00120
00121 DECLARE_debugModule_empty
00122
00125 public:
00128 virtual void adjustSettings( int which, QTreeWidgetItem *myTree, QGroupBox *setBox );
00129 protected:
00131 void widget2settings( const QWidget *widget, int which );
00133 void settings2widget( QWidget *widget, int which );
00135 void settingsType2widget( QWidget *widget, const SettingTypeItem &typeItem );
00137
00138
00139 protected:
00141 void file_saveAllSettings(std::ostream &stream);
00143 void file_loadAllSettings(std::istream &stream);
00145 void file_saveModuleType( std::ostream &os, int which );
00148 void file_loadModuleType( std::istream &is, int which );
00150 int& settingsInt(int index)
00151 { return settings[index].val.i; }
00152 int settingsInt(int index) const
00153 { return settings[index].val.i; }
00154
00158 static SettingType settingInt(int min,int defaults,int max,ChoiceType type=Int) {
00159 ASSERT( type==Int || type==IntLog2 );
00160 SettingType result;
00161 result.type= type;
00162 result.defaults.i= defaults;
00163 result.data.i[0]= min;
00164 result.data.i[1]= max;
00165 return result;
00166 }
00168 static SettingType settingFloat(float min,float defaults,float max) {
00169 SettingType result;
00170 result.type= Float;
00171 result.defaults.f= defaults;
00172 result.data.f[0]= min;
00173 result.data.f[1]= max;
00174 return result;
00175 }
00177 static SettingType settingCombo(const char *text,int defaults) {
00178 ASSERT( defaults>=0 && defaults<1+countEOLs(text) );
00179 SettingType result;
00180 result.type= Combo;
00181 result.defaults.i= defaults;
00182 result.data.text= text;
00183 return result;
00184 }
00188 template<class Iface> static SettingType settingModule(int defaultID) {
00189 const std::vector<int> &compMods= Iface::getCompMods();
00190 int index= find( compMods.begin(), compMods.end(), defaultID ) - compMods.begin();
00191 ASSERT( index < (int)compMods.size() );
00192 SettingType result;
00193 result.type= ModuleCombo;
00194 result.defaults.i= index;
00195 result.data.compatIDs= &compMods;
00196 return result;
00197 }
00199 template<class Iface> static SettingType settingModule() {
00200 return settingModule<Iface>( Iface::getCompMods().front() );
00201 }
00203 };
00204
00205
00207
00208 #define DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SETTYPE_...) \
00209 \
00210 friend class Module; \
00211 \
00212 friend struct ModuleFactory::Creator<CNAME_>; \
00213 public: \
00214 CNAME_* abstractClone(CloneMethod method=DeepCopy) const \
00215 { return concreteClone<CNAME_>(method); } \
00216 \
00217 const TypeInfo& info() const { \
00218 static SettingTypeItem setType_[]= {SETTYPE_}; \
00219 static TypeInfo info_= { \
00220 id: ModuleFactory::getModuleID<CNAME_>(), \
00221 name:NAME_, \
00222 desc: DESC_, \
00223 setLength: sizeof(setType_)/sizeof(*setType_)-1, \
00224 setType: setType_ \
00225 }; \
00226 return info_; \
00227 } \
00228 \
00229
00230
00233 #define DECLARE_TypeInfo_noSettings(CNAME_,NAME_,DESC_) \
00234 DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SettingTypeItem::stopper)
00235
00238 #define DECLARE_TypeInfo(CNAME_,NAME_,DESC_,SETTYPE_...) \
00239 DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SETTYPE_,SettingTypeItem::stopper)
00240
00241
00242
00244 class ModuleFactory {
00246 static ModuleFactory *instance;
00248 std::vector<Module*> prototypes;
00249
00251 ModuleFactory() {}
00253 ~ModuleFactory() {
00254 for_each( prototypes, std::mem_fun(&Module::nullModuleLinks) );
00255 clearContainer(prototypes);
00256 }
00258 void initialize();
00259
00260 public:
00262 template<class M> static int getModuleID();
00263
00265 static void init()
00266 { ASSERT(!instance); (instance=new ModuleFactory)->initialize(); }
00268 static void destroy()
00269 { delete instance; instance=0; }
00270
00272 static const Module& prototype(int id) {
00273 ASSERT( instance && instance->prototypes.at(id) );
00274 return *instance->prototypes[id];
00275 }
00277 static Module* newModule( int id, Module::CloneMethod method=Module::DeepCopy )
00278 { return prototype(id).abstractClone(method); }
00279
00281 static void changeDefaultSettings(const Module &module);
00282
00283 #ifndef __ICC
00284 private:
00285 #endif
00286
00287 template<class T> struct Creator {
00288 T* operator()() const { return new T; }
00289 };
00290 private:
00291 template<class T> struct Instantiator {
00292 int operator()() const;
00293 };
00295 static void instantiateModules();
00296 };
00297
00298
00300 template<class Iface> class Interface: public Module {
00301 static std::vector<int> compMods_;
00302 public:
00304 static const std::vector<int>& getCompMods();
00306 static const Iface& compatiblePrototype(int index=0) {
00307 ASSERT( index>=0 && index<(int)getCompMods().size() );
00308 return *debugCast<const Iface*>(&ModuleFactory::prototype( getCompMods()[index] ));
00309 }
00311 static Iface* newCompatibleModule(int index=0)
00312 { return compatiblePrototype(index).clone(); }
00313
00315 Iface* clone(CloneMethod method=DeepCopy) const
00316 { return debugCast<Iface*>( abstractClone(method) ); }
00317 };
00318
00319 #endif // MODULES_HEADER_