How to set plugin data without setter method in base class ?
Issue
Many cases occurred for which it is needed to set some optional parameters into plugin classes whereas the related parent class does not exhibit a method to do so.
In order to keep as simpler as possible the class hierarchy for any concept, the main constraint is to provide a solution of this issue using an external way. In other words, it is not relevant to derive the concepts from a meta-concept which would offer an introspection mechanism. First such an introspection is not systematically required, second, in the case it becomes necessary it would imply changes in the hierarchy breaking binary compatibility.
dtkCorePluginTuner architecture
Owing to the above constraints, dtkCorePluginTuner is a not so beautiful attempt to set data into plugin classes without casting. dtkCorePluginTuner is a pure virtual class templated by the parent concept of the plugin. Here follows its current interface:
template < typename T > class dtkCorePluginTuner
{
public:
dtkCorePluginTuner(void);
virtual ~dtkCorePluginTuner(void);
void setObject(T *object);
void setMap(const QVariantHash& map);
virtual void update(void) = 0;
T *object(void) const;
const QVariantHash& map(void) const;
private:
T *m_object;
QVariantHash m_map;
};
The QVariantHash
is in charge of the matching between data names and data values of the derived class. The tuner can then be derived into plugin and one has just to implement update()
method to set the data values.
Giving a base class A
and its concrete class B
that has a method setRadius
which requires a double value, one can implement the following tuner:
class dtkTunerB : public dtkCorePluginTuner<A>
{
public:
void update(void) {
B *b = dynamic_cast<B *>(this->object());
if (b) {
const QVariantHash m = this->map();
b->setRadius(m["Radius"].toDouble());
}
}
};
dtkCorePluginFactory modifications
In order to register and to create the concrete tuner, the dtkCorePluginFactory has been equiped with recordTuner()
and createTuner()
methods:
template < typename T > class dtkCorePluginFactory
{
public:
typedef dtkCorePluginTuner<T> *(*tunerCreator) ();
public:
void recordTuner(const QString& key, tunerCreator func);
public:
dtkCorePluginTuner<T> *createTuner(const QString& key) const;
};
Outlooks
dtkCorePluginTuner has to be regarded as a first prototype to solve the issue. dtk developers are asked to bring improvements.