Fixed cstring include in kdTree.h, some infinity and comment stuff.
[fic.git] / modules.h
blobb06617534b088bba90644ffaf5fcc805062f62be
1 #ifndef MODULES_HEADER_
2 #define MODULES_HEADER_
4 // Forwards for all classes visible outside this header
5 class Module;
6 class ModuleFactory;
7 template <class Iface> class Interface;
10 /// \defgroup modules Module implementations
11 /** A common base class for all modules */
12 class Module {
13 friend class ModuleFactory; ///< Permission for the ModuleFactory to manipulate Modules
14 // Type definitions
15 public:
16 /** Two types of cloning, used in ::clone */
17 enum CloneMethod { ShallowCopy, DeepCopy };
18 /** Types of a setting */
19 enum ChoiceType {
20 Stop, ///< a list-terminator
21 Int, ///< integer from an interval
22 IntLog2, ///< integer from an interval prefixed with 2^
23 Float, ///< real number from an interval
24 ModuleCombo,///< a connection to another module (shown as a combo-box)
25 Combo /// choice from a list of strings
27 /** Represents one setting - one number, real or integer */
28 union SettingValue {
29 int i; ///< Setting value for integer/module types (see Module::ChoiceType)
30 float f; ///< Setting value for real-number type (see Module::ChoiceType)
32 /** Represents the type of one module's setting - without label and description */
33 struct SettingType {
34 ChoiceType type; ///< The type of the item
35 SettingValue defaults; ///< The default setting
37 union {
38 int i[2]; ///< Lower and upper bound (#type==Int,IntLog2)
39 float f[2]; ///< Lower and upper bound (#type==Float)
40 const char *text; ///< Lines of the combo-box (#type==Combo)
41 /** Pointer to the vector of IDs of compatible modules (#type==ModuleCombo),
42 * meant to be one of Interface::getCompMods() */
43 const std::vector<int> *compatIDs;
44 } data; ///< Additional data, differs for different #type
47 /** Represents the type of one setting - including label, description, etc.\ */
48 struct SettingTypeItem {
49 static const SettingTypeItem stopper; ///< Predefined list terminator
51 const char *label /// The text label of the setting
52 , *desc; ///< Description text
53 SettingType type; ///< The type of this setting
56 /** Represents one setting value in a module */
57 struct SettingItem {
58 Module *m; ///< Pointer to the connected module (if type is Module::ModuleCombo)
59 SettingValue val; ///< The setting value
61 /** Just nulls the module pointer */
62 SettingItem(): m(0) { DEBUG_ONLY( val.f= std::numeric_limits<float>::quiet_NaN(); ) }
64 /** Creates a default settings-item for a settings-item-type */
65 SettingItem(const SettingTypeItem &typeItem): m(0), val(typeItem.type.defaults) {}
67 /** Just deletes the module pointer */
68 ~SettingItem() { delete m; }
71 /** Information about one module-type */
72 struct TypeInfo {
73 int id; ///< The module-type's ID
74 const char *name /// The module-type's name
75 , *desc; ///< The module-type's description
76 int setLength; ///< The number of setting items
77 const SettingTypeItem *setType; ///< The types of module's settings
80 // Data definitions
81 protected:
82 SettingItem *settings; ///< The current setting values of this Module
84 /** \name Construction, destruction and related methods
85 * @{ - all private, only to be used by ModuleFactory on module prototypes */
86 private:
87 /** Creates a copy of module's settings (includes the whole module subtree) */
88 SettingItem* copySettings(CloneMethod method) const;
89 /** Called for prototypes to initialize the default links to other modules */
90 void initDefaultModuleLinks();
91 /** Called for prototypes to null links to other modules */
92 void nullModuleLinks();
93 /** Called for prototypes to create the settings and inicialize them with defaults */
94 void createDefaultSettings();
96 /** Denial of assigment */
97 Module& operator=(const Module&);
98 /** Denial of copying */
99 Module(const Module&);
100 /// @}
101 protected:
102 /** Initializes an empty module */
103 Module(): settings(0) {}
105 /** Cloning method, implemented in all modules via macros \return a new module
106 * \param method determines creation of a deep or a shallow copy (zeroed children) */
107 virtual Module* abstractClone(CloneMethod method) const =0;
108 /** Concrete cloning method - templated by the actual type of the module */
109 template<class M> M* concreteClone(CloneMethod method) const;
111 public:
112 /** Deletes the settings, destroying child modules as well */
113 virtual ~Module()
114 { delete[] settings; }
116 /** Returns reference to module-type's information,
117 * like count and types of settings, etc.\ Implemented in all modules via macros */
118 virtual const TypeInfo& info() const =0;
120 DECLARE_debugModule_empty
122 /** \name Settings visualization and related methods
123 * @{ - common code for all modules, implemented in gui.cpp */
124 public:
125 /** Creates or updates settings-box and/or settings-tree.\
126 * if overridden in derived modules, it is recommended to call this one at first */
127 virtual void adjustSettings( int which, QTreeWidgetItem *myTree, QGroupBox *setBox );
128 protected:
129 /** Reads a setting value from a widget */
130 void widget2settings( const QWidget *widget, int which );
131 /** Writes a setting value into a widget */
132 void settings2widget( QWidget *widget, int which );
133 /** Initializes a widget according to a setting-item type */
134 void settingsType2widget( QWidget *widget, const SettingTypeItem &typeItem );
135 /// @}
137 // Other methods
138 protected:
139 /** Saves all the settings, icluding child modules */
140 void file_saveAllSettings(std::ostream &stream);
141 /** Loads all the settings, icluding child modules (and their settings) */
142 void file_loadAllSettings(std::istream &stream);
143 /** Puts a module-identifier in a stream (\p which is the index in settings) */
144 void file_saveModuleType( std::ostream &os, int which );
145 /** Gets an module-identifier from the stream, initializes the pointer in settings
146 * with a new empty instance and does some checking (bounds,Iface) */
147 void file_loadModuleType( std::istream &is, int which );
148 /** A shortcut method for working with integer settings */
149 int& settingsInt(int index)
150 { return settings[index].val.i; }
151 int settingsInt(int index) const
152 { return settings[index].val.i; }
154 /** \name SettingType construction methods
155 * @{ - to be used within DECLARE_TypeInfo macros when declaring modules */
156 /** Creates a bounded integer setting, optionally shown as a power of two */
157 static SettingType settingInt(int min,int defaults,int max,ChoiceType type=Int) {
158 ASSERT( type==Int || type==IntLog2 );
159 SettingType result;
160 result.type= type;
161 result.defaults.i= defaults;
162 result.data.i[0]= min;
163 result.data.i[1]= max;
164 return result;
166 /** Creates a bounded real-number setting */
167 static SettingType settingFloat(float min,float defaults,float max) {
168 SettingType result;
169 result.type= Float;
170 result.defaults.f= defaults;
171 result.data.f[0]= min;
172 result.data.f[1]= max;
173 return result;
175 /** Creates a choose-one-of setting shown as a combo-box */
176 static SettingType settingCombo(const char *text,int defaults) {
177 ASSERT( defaults>=0 && defaults<1+countEOLs(text) );
178 SettingType result;
179 result.type= Combo;
180 result.defaults.i= defaults;
181 result.data.text= text;
182 return result;
184 /** Creates a connection to another module (type specified as a template parameter).
185 * It will be shown as a combo-box and automatically filled by compatible modules.
186 * The default possibility can be specified */
187 template<class Iface> static SettingType settingModule(int defaultID) {
188 const std::vector<int> &compMods= Iface::getCompMods();
189 int index= find( compMods.begin(), compMods.end(), defaultID ) - compMods.begin();
190 ASSERT( index < (int)compMods.size() );
191 SettingType result;
192 result.type= ModuleCombo;
193 result.defaults.i= index;
194 result.data.compatIDs= &compMods;
195 return result;
197 /** A shortcut to set the first compatible module as the default one */
198 template<class Iface> static SettingType settingModule() {
199 return settingModule<Iface>( Iface::getCompMods().front() );
201 /// @}
202 }; // Module class
205 //// Macros for easier Module-writing
207 #define DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SETTYPE_...) \
208 /** \cond */ \
209 friend class Module; /* Needed for concreteClone */ \
210 /*friend class ModuleFactory;*/ \
211 friend struct ModuleFactory::Creator<CNAME_>; /* Needed for GCC-3 and ICC */ \
212 public: \
213 CNAME_* abstractClone(CloneMethod method=DeepCopy) const \
214 { return concreteClone<CNAME_>(method); } \
216 const TypeInfo& info() const { \
217 static SettingTypeItem setType_[]= {SETTYPE_}; \
218 static TypeInfo info_= { \
219 id: ModuleFactory::getModuleID<CNAME_>(), \
220 name: NAME_, \
221 desc: DESC_, \
222 setLength: sizeof(setType_)/sizeof(*setType_)-1, \
223 setType: setType_ \
224 }; \
225 return info_; \
227 /** \endcond */ \
229 /** Declares technical stuff within a Module descendant that contains no settings
230 * - parameters: the name of the class (Token),
231 * the name of the module ("Name"), some description ("Desc...") */
232 #define DECLARE_TypeInfo_noSettings(CNAME_,NAME_,DESC_) \
233 DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SettingTypeItem::stopper)
235 /** Like DECLARE_TypeInfo_noSettings, but for a module containing settings
236 * - additional parameter: an array of SettingTypeItem */
237 #define DECLARE_TypeInfo(CNAME_,NAME_,DESC_,SETTYPE_...) \
238 DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SETTYPE_,SettingTypeItem::stopper)
242 /** A singleton factory class for creating modules */
243 class ModuleFactory {
244 /** Static pointer to the only instance of the ModuleFactory */
245 static ModuleFactory *instance;
246 /** Pointers to the prototypes for every module type (indexed by their ID's) */
247 std::vector<Module*> prototypes;
249 /** Private constructor to avoid uncontrolled instantiation */
250 ModuleFactory() {}
251 /** Deletes the prototypes */
252 ~ModuleFactory() {
253 for_each( prototypes, std::mem_fun(&Module::nullModuleLinks) );
254 clearContainer(prototypes);
256 /** The real constructing routine */
257 void initialize();
259 public:
260 /** Returns the ID of a module-type */
261 template<class M> static int getModuleID();
263 /** Method to instantiate the singleton */
264 static void init()
265 { ASSERT(!instance); (instance=new ModuleFactory)->initialize(); }
266 /** Method to delete the singleton */
267 static void destroy()
268 { delete instance; instance=0; }
270 /** Returns a reference to the module prototype with given id */
271 static const Module& prototype(int id) {
272 ASSERT( instance && instance->prototypes.at(id) );
273 return *instance->prototypes[id];
275 /** Returns a new instance of the module-type with given id */
276 static Module* newModule( int id, Module::CloneMethod method=Module::DeepCopy )
277 { return prototype(id).abstractClone(method); }
279 /** Sets appropriate prototype settings according to given module's settings */
280 static void changeDefaultSettings(const Module &module);
282 #ifndef __ICC
283 private:
284 #endif
285 // some helper stuff
286 template<class T> struct Creator {
287 T* operator()() const { return new T; }
289 private:
290 template<class T> struct Instantiator {
291 int operator()() const;
293 /** Never called, only exists for certain templates to be instantiated in modules.cpp */
294 static void instantiateModules();
295 }; // ModuleFactory class
298 /** A base class for all interfaces, parametrized by the interface's type */
299 template<class Iface> class Interface: public Module {
300 static std::vector<int> compMods_; ///< IDs of modules derived from this interface
301 public:
302 /** Returns a reference to #compMods_ (initializes it if empty) */
303 static const std::vector<int>& getCompMods();
304 /** Returns a reference to the index-th prototype implementing this interface */
305 static const Iface& compatiblePrototype(int index=0) {
306 ASSERT( index>=0 && index<(int)getCompMods().size() );
307 return *debugCast<const Iface*>(&ModuleFactory::prototype( getCompMods()[index] ));
309 /** Creates a new instance of the index-th compatible module (deep copy of the prototype) */
310 static Iface* newCompatibleModule(int index=0)
311 { return compatiblePrototype(index).clone(); }
313 /** Works like abstractClone(), but is public and returns the correct type */
314 Iface* clone(CloneMethod method=DeepCopy) const
315 { return debugCast<Iface*>( abstractClone(method) ); }
318 #endif // MODULES_HEADER_