1 #ifndef MODULES_HEADER_
2 #define MODULES_HEADER_
4 // Forwards for all classes visible outside this header
7 template <class Iface
> class Interface
;
10 /// \defgroup modules Module implementations
11 /** A common base class for all modules */
13 friend class ModuleFactory
; ///< Permission for the ModuleFactory to manipulate Modules
16 /** Two types of cloning, used in ::clone */
17 enum CloneMethod
{ ShallowCopy
, DeepCopy
};
18 /** Types of a setting */
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 */
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 */
34 ChoiceType type
; ///< The type of the item
35 SettingValue defaults
; ///< The default setting
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 */
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 */
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
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 */
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
&);
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 public: // public because of GCC-3 versions
109 /** Concrete cloning method - templated by the actual type of the module */
110 template<class M
> M
* concreteClone(CloneMethod method
) const;
113 /** Deletes the settings, destroying child modules as well */
115 { delete[] settings
; }
117 /** Returns reference to module-type's information,
118 * like count and types of settings, etc.\ Implemented in all modules via macros */
119 virtual const TypeInfo
& info() const =0;
121 DECLARE_debugModule_empty
123 /** \name Settings visualization and related methods
124 * @{ - common code for all modules, implemented in gui.cpp */
126 /** Creates or updates settings-box and/or settings-tree.\
127 * if overridden in derived modules, it is recommended to call this one at first */
128 virtual void adjustSettings( int which
, QTreeWidgetItem
*myTree
, QGroupBox
*setBox
);
130 /** Reads a setting value from a widget */
131 void widget2settings( const QWidget
*widget
, int which
);
132 /** Writes a setting value into a widget */
133 void settings2widget( QWidget
*widget
, int which
);
134 /** Initializes a widget according to a setting-item type */
135 void settingsType2widget( QWidget
*widget
, const SettingTypeItem
&typeItem
);
140 /** Saves all the settings, icluding child modules */
141 void file_saveAllSettings(std::ostream
&stream
);
142 /** Loads all the settings, icluding child modules (and their settings) */
143 void file_loadAllSettings(std::istream
&stream
);
144 /** Puts a module-identifier in a stream (\p which is the index in settings) */
145 void file_saveModuleType( std::ostream
&os
, int which
);
146 /** Gets an module-identifier from the stream, initializes the pointer in settings
147 * with a new empty instance and does some checking (bounds,Iface) */
148 void file_loadModuleType( std::istream
&is
, int which
);
149 /** A shortcut method for working with integer settings */
150 int& settingsInt(int index
)
151 { return settings
[index
].val
.i
; }
152 int settingsInt(int index
) const
153 { return settings
[index
].val
.i
; }
155 /** \name SettingType construction methods
156 * @{ - to be used within DECLARE_TypeInfo macros when declaring modules */
157 /** Creates a bounded integer setting, optionally shown as a power of two */
158 static SettingType
settingInt(int min
,int defaults
,int max
,ChoiceType type
=Int
) {
159 ASSERT( type
==Int
|| type
==IntLog2
);
162 result
.defaults
.i
= defaults
;
163 result
.data
.i
[0]= min
;
164 result
.data
.i
[1]= max
;
167 /** Creates a bounded real-number setting */
168 static SettingType
settingFloat(float min
,float defaults
,float max
) {
171 result
.defaults
.f
= defaults
;
172 result
.data
.f
[0]= min
;
173 result
.data
.f
[1]= max
;
176 /** Creates a choose-one-of setting shown as a combo-box */
177 static SettingType
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 /** Creates a connection to another module (type specified as a template parameter).
186 * It will be shown as a combo-box and automatically filled by compatible modules.
187 * The default possibility can be specified */
188 template<class Iface
> static SettingType
settingModule(int defaultID
) {
189 const std::vector
<int> &compMods
= Iface::getCompMods();
190 int index
= find( compMods
.begin(), compMods
.end(), defaultID
) - compMods
.begin();
191 ASSERT( index
< (int)compMods
.size() );
193 result
.type
= ModuleCombo
;
194 result
.defaults
.i
= index
;
195 result
.data
.compatIDs
= &compMods
;
198 /** A shortcut to set the first compatible module as the default one */
199 template<class Iface
> static SettingType
settingModule() {
200 return settingModule
<Iface
>( Iface::getCompMods().front() );
206 //// Macros for easier Module-writing
208 #define DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SETTYPE_...) \
210 friend class Module; /* Needed for concreteClone */ \
211 /*friend class ModuleFactory;*/ \
212 friend struct ModuleFactory::Creator<CNAME_>; /* Needed for GCC-3 and ICC */ \
214 CNAME_* abstractClone(CloneMethod method=DeepCopy) const \
215 { return concreteClone<CNAME_>(method); } \
217 const TypeInfo& info() const { \
218 static SettingTypeItem setType_[]= {SETTYPE_}; \
219 static TypeInfo info_= { \
220 id: ModuleFactory::getModuleID<CNAME_>(), \
223 setLength: sizeof(setType_)/sizeof(*setType_)-1, \
230 /** Declares technical stuff within a Module descendant that contains no settings
231 * - parameters: the name of the class (Token),
232 * the name of the module ("Name"), some description ("Desc...") */
233 #define DECLARE_TypeInfo_noSettings(CNAME_,NAME_,DESC_) \
234 DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SettingTypeItem::stopper)
236 /** Like DECLARE_TypeInfo_noSettings, but for a module containing settings
237 * - additional parameter: an array of SettingTypeItem */
238 #define DECLARE_TypeInfo(CNAME_,NAME_,DESC_,SETTYPE_...) \
239 DECLARE_TypeInfo_helper(CNAME_,NAME_,DESC_,SETTYPE_,SettingTypeItem::stopper)
243 /** A singleton factory class for creating modules */
244 class ModuleFactory
{
245 /** Static pointer to the only instance of the ModuleFactory */
246 static ModuleFactory
*instance
;
247 /** Pointers to the prototypes for every module type (indexed by their ID's) */
248 std::vector
<Module
*> prototypes
;
250 /** Private constructor to avoid uncontrolled instantiation */
252 /** Deletes the prototypes */
254 for_each( prototypes
, std::mem_fun(&Module::nullModuleLinks
) );
255 clearContainer(prototypes
);
257 /** The real constructing routine */
261 /** Returns the ID of a module-type */
262 template<class M
> static int getModuleID();
264 /** Method to instantiate the singleton */
266 { ASSERT(!instance
); (instance
=new ModuleFactory
)->initialize(); }
267 /** Method to delete the singleton */
268 static void destroy()
269 { delete instance
; instance
=0; }
271 /** Returns a reference to the module prototype with given id */
272 static const Module
& prototype(int id
) {
273 ASSERT( instance
&& instance
->prototypes
.at(id
) );
274 return *instance
->prototypes
[id
];
276 /** Returns a new instance of the module-type with given id */
277 static Module
* newModule( int id
, Module::CloneMethod method
=Module::DeepCopy
)
278 { return prototype(id
).abstractClone(method
); }
280 /** Sets appropriate prototype settings according to given module's settings */
281 static void changeDefaultSettings(const Module
&module
);
287 template<class T
> struct Creator
{
288 T
* operator()() const { return new T
; }
291 template<class T
> struct Instantiator
{
292 int operator()() const;
294 /** Never called, only exists for certain templates to be instantiated in modules.cpp */
295 static void instantiateModules();
296 }; // ModuleFactory class
299 /** A base class for all interfaces, parametrized by the interface's type */
300 template<class Iface
> class Interface
: public Module
{
301 static std::vector
<int> compMods_
; ///< IDs of modules derived from this interface
303 /** Returns a reference to #compMods_ (initializes it if empty) */
304 static const std::vector
<int>& getCompMods();
305 /** Returns a reference to the index-th prototype implementing this interface */
306 static const Iface
& compatiblePrototype(int index
=0) {
307 ASSERT( index
>=0 && index
<(int)getCompMods().size() );
308 return *debugCast
<const Iface
*>(&ModuleFactory::prototype( getCompMods()[index
] ));
310 /** Creates a new instance of the index-th compatible module (deep copy of the prototype) */
311 static Iface
* newCompatibleModule(int index
=0)
312 { return compatiblePrototype(index
).clone(); }
314 /** Works like abstractClone(), but is public and returns the correct type */
315 Iface
* clone(CloneMethod method
=DeepCopy
) const
316 { return debugCast
<Iface
*>( abstractClone(method
) ); }
319 #endif // MODULES_HEADER_