1 #ifndef MODULES_HEADER_
2 #define MODULES_HEADER_
6 // Forwards for all classes visible outside this header
9 template <class Iface
> class Interface
;
12 /** A common base class for all modules */
14 friend class ModuleFactory
; ///< Permission for the ModuleFactory to manipulate Modules
18 /** Two types of cloning, used in #clone */
19 enum CloneMethod
{ ShallowCopy
, DeepCopy
};
20 /** Types of a setting */
22 Stop
, ///< a list-terminator
23 Int
, ///< integer from an interval
24 IntLog2
, ///< integer from an interval prefixed with 2^
25 Float
, ///< real number from an interval
26 ModuleCombo
,///< a connection to another module (shown as a combo-box)
27 Combo
/// choice from a list of strings
29 /** Represents one setting - one number, real or integer */
31 int i
; ///< Setting value for integer/module types (see Module::ChoiceType)
32 float f
; ///< Setting value for real-number type (see Module::ChoiceType)
34 /** Represent the type of one module's setting - without label and description */
36 ChoiceType type
; ///< The type of the item
37 SettingValue defaults
; ///< The default setting
40 int i
[2]; ///< Lower and upper bound (type==Int,IntLog2)
41 float f
[2]; ///< Lower and upper bound (type==Float)
42 const char *text
; ///< Lines of the combo-box (type==Combo)
43 /** Pointer to the vector of IDs of compatible modules (type==ModuleCombo),
44 * meant to be one of Interface::getCompMods() */
45 const std::vector
<int> *compatIDs
;
46 } data
; ///< Additional data, differs for different #type
49 /** Represents the type of one setting - including label, description, etc.\ */
50 struct SettingsTypeItem
{
51 static const SettingsTypeItem stopper
; ///< Predefined list terminator
53 const char *label
/// The text label of the setting
54 , *desc
; ///< Description text
55 SettingsType type
; ///< The type of this setting
58 /** Represents one setting value in a module */
60 Module
*m
; ///< Pointer to the connected module (if type is Module::ModuleCombo)
61 SettingValue val
; ///< The setting value
63 /** Just nulls the module pointer */
64 SettingsItem(): m(0) { DEBUG_ONLY( val
.f
= std::numeric_limits
<float>::quiet_NaN(); ) }
66 /** Creates a default settings-item for a settings-item-type */
67 SettingsItem(const SettingsTypeItem
&typeItem
): m(0), val(typeItem
.type
.defaults
) {}
69 /** Just deletes the module pointer */
70 ~SettingsItem() { delete m
; }
73 /** Information about one module-type */
75 int id
; ///< The module-type's ID
76 const char *name
/// The module-type's name
77 , *desc
; ///< The module-type's description
78 int setLength
; ///< The number of setting items
79 const SettingsTypeItem
*setType
; ///< The types of module's settings
84 SettingsItem
*settings
; ///< The current setting values of this Module
86 /** \name Construction, destruction and related methods
87 * @{ - all private, only to be used by ModuleFactory */
89 /** Creates a copy of module's settings (includes the whole module subtree) */
90 SettingsItem
* copySettings(CloneMethod method
) const;
91 /** Called for prototypes to initialize the default links to other modules */
92 void initDefaultModuleLinks();
93 /** Called for prototypes to null links to other modules */
94 void nullModuleLinks();
95 /** Called for prototypes to create the settings and inicialize them with defaults */
96 void createDefaultSettings();
98 /** Denial of assigment */
99 Module
& operator=(const Module
&);
100 /** Denial of copying */
101 Module(const Module
&);
103 /** Initializes an empty module */
104 Module(): settings(0) {}
106 /** Cloning method, implemented in all modules via macros \return a new module
107 * \param method determines creation of a deep or a shallow copy (zeroed children) */
108 virtual Module
* abstractClone(CloneMethod method
) const =0;
109 /** Concrete cloning method - templated by the actual type of the module */
110 template<class M
> M
* concreteClone(CloneMethod method
) const;
112 /** Saves all the settings, icluding child modules */
113 void saveAllSettings(std::ostream
&stream
);
114 void loadAllSettings(std::istream
&stream
);
116 /** Friend non-member cloning function (returns the type it gets) */
117 template<class M
> friend M
* clone( const M
*module
, CloneMethod method
=Module::DeepCopy
)
118 { return debugCast
<M
*>( module
->abstractClone(method
) ); }
120 /** Deletes the settings, destroying child modules as well */
122 { delete[] settings
; }
124 virtual const TypeInfo
& info() const =0;
126 DECLARE_debugModule_empty
131 /** \name Settings visualization and related methods
132 * @{ - all implemented in gui.cpp */
134 /** Creates or updates settings-box and/or settings-tree,
135 * if overridden in derived modules, it is recommended to call this one at first */
136 virtual void adjustSettings( int which
, QTreeWidgetItem
*myTree
, QGroupBox
*setBox
);
138 /** Reads a setting value from a widget */
139 void widget2settings( const QWidget
*widget
, int which
);
140 /** Writes a setting value into a widget */
141 void settings2widget( QWidget
*widget
, int which
);
142 /** Initializes a widget according to a setting-item type */
143 void settingsType2widget( QWidget
*widget
, const SettingsTypeItem
&typeItem
);
148 /** Puts a module-identifier in a stream (which = the index in settings) */
149 void file_saveModuleType( std::ostream
&os
, int which
);
150 /** Gets an module-identifier from the stream, initializes the pointer in settings
151 * with a new empty instance and does some checking (bounds,Iface) */
152 void file_loadModuleType( std::istream
&is
, int which
);
153 /** A shortcut method for working with integer settings */
154 int& settingsInt(int index
)
155 { return settings
[index
].val
.i
; }
156 int settingsInt(int index
) const
157 { return settings
[index
].val
.i
; }
160 static SettingsType
settingInt(int min
,int defaults
,int max
,ChoiceType type
=Int
) {
161 ASSERT( type
==Int
|| type
==IntLog2
);
164 result
.defaults
.i
= defaults
;
165 result
.data
.i
[0]= min
;
166 result
.data
.i
[1]= max
;
169 static SettingsType
settingFloat(float min
,float defaults
,float max
) {
172 result
.defaults
.f
= defaults
;
173 result
.data
.f
[0]= min
;
174 result
.data
.f
[1]= max
;
177 static SettingsType
settingCombo(const char *text
,int defaults
) {
178 ASSERT( defaults
>=0 && defaults
<1+countEOLs(text
) );
181 result
.defaults
.i
= defaults
;
182 result
.data
.text
= text
;
185 template<class Iface
> static SettingsType
settingModule(int index
=0) {
186 const std::vector
<int> &compMods
= Iface::getCompMods();
187 ASSERT( index
< (int)compMods
.size() );
189 result
.type
= ModuleCombo
;
190 result
.defaults
.i
= index
;
191 result
.data
.compatIDs
= &compMods
;
197 #define DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SETTYPE_...) \
198 friend class Module; \
199 friend class ModuleFactory; \
200 friend struct ModuleFactory::Creator<CNAME_>; /* Needed for GCC-3 */ \
202 CNAME_* abstractClone(CloneMethod method=DeepCopy) const \
203 { return concreteClone<CNAME_>(method); } \
205 const TypeInfo& info() const { \
206 static SettingsTypeItem setType_[]= {SETTYPE_}; \
207 static TypeInfo info_= { \
208 id: ModuleFactory::getModuleID<CNAME_>(), \
211 setLength: sizeof(setType_)/sizeof(*setType_)-1, \
217 /** Macros for easier Module-writing */
218 #define DECLARE_TypeInfo(CNAME_,NAME_,DESC_,SETTYPE_...) \
219 DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SETTYPE_,SettingsTypeItem::stopper)
221 #define DECLARE_TypeInfo_noSettings(CNAME_,NAME_,DESC_) \
222 DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SettingsTypeItem::stopper)
225 /** A singleton factory class for creating modules */
226 class ModuleFactory
{
227 /** Static pointer to the only instance of the ModuleFactory */
228 static ModuleFactory
*instance
;
230 /** Pointers to the prototypes for every module type (indexed by their ID's) */
231 std::vector
<Module
*> prototypes
;
233 /** Private constructor to avoid uncontrolled instantiation */
235 /** Deletes the prototypes */
237 for_each( prototypes
.begin(), prototypes
.end(), std::mem_fun(&Module::nullModuleLinks
) );
238 for_each( prototypes
.begin(), prototypes
.end(), SingleDeleter
<Module
>() );
240 /** The real constructing routine */
244 /** Returns the ID of a module-type */
245 template<class M
> static int getModuleID();
247 /** Method to instantiate the singleton */
249 { ASSERT(!instance
); (instance
=new ModuleFactory
)->initialize(); }
250 /** Method to delete the singleton */
251 static void destroy()
252 { delete instance
; instance
=0; }
254 /** Returns a reference to the prototype of the module with given id */
255 static const Module
& prototype(int id
) {
256 ASSERT( instance
&& instance
->prototypes
.at(id
) );
257 return *instance
->prototypes
[id
];
259 /** Returns the name of the module-type with given id */
260 static const char* moduleName(int id
)
261 { return prototype(id
).info().name
; }
262 /** Returns the description of the module-type with given id */
263 static const char* moduleDescription(int id
)
264 { return prototype(id
).info().desc
; }
265 /** Returns a new instance of the module-type with given id */
266 static Module
* newModule( int id
, Module::CloneMethod method
=Module::DeepCopy
)
267 { return prototype(id
).abstractClone(method
); }
269 /** Sets appropriate prototype settings according to given module's settings */
270 static void changeDefaultSettings(const Module
&module
);
274 template<class T
> struct Creator
{
275 T
* operator()() const
278 template<class T
> struct Instantiator
{
279 int operator()() const;
281 /** Never called, only exists for certain templates to be instantiated in modules.cpp */
282 static void instantiateModules();
285 /** A base class for all interfaces, parametrized by the interface's type */
286 template<class Iface
> class Interface
: public Module
{
287 static std::vector
<int> compMods_
; ///< IDs of modules derived from this interface
289 /** Returns a reference to #compMods_ (initializes it if empty) */
290 static const std::vector
<int>& getCompMods();
291 /** Returns a reference to the index-th prototype implementing this interface */
292 static const Iface
& compatiblePrototype(int index
=0) {
293 ASSERT( index
>=0 && index
<(int)getCompMods().size() );
294 return *debugCast
<const Iface
*>(&ModuleFactory::prototype( getCompMods()[index
] ));
296 /** Creates a new instance of the index-th compatible module */
297 static Iface
* newCompatibleModule(int index
=0)
298 { return clone( &compatiblePrototype(index
) ); }
301 #endif // MODULES_HEADER_