PDA

View Full Version : automatic loading plugin factory



lni
30th August 2015, 06:17
Hi,

I have a base class for a base plugin factory (BaseFactory), and many derived factories (DerivedFactory). In each DerivedFactory, there is a static singleton DerivedFactory::instance() as in the following code




class BaseFactory : public QObject
{
};

class DerivedFactory : public BaseFactory
{
public:

virtual ~DerivedFactory();
static const DerivedFactory& instance();

private:

DerivedFactory();
};



Each DerivedFactory::instance() needed to be called immediately after the QApplication is created so the factory is ready to produce object base on class name.

The problem is I have quite a few of those factories, so I hope to force programmers to register the derived factory into the base by some macros, so the base factory will call all DerivedFactory::instance() in one go. This will also avoid some derived factory not be initialized, causing program to crash when restoring previously saved session (because factory has not loaded the plugin yet).

I try following way, and obviously, the function prototype does not match. How can I achieve this goal? Many thanks!




class BaseFactory : public QObject
{
typedef const BaseFactory& (FactoryReg)();

/// register the factory to be called by loadAllFactories
static int registerFactory( const QString& key, FactoryReg* );

static void loadAllFactories();

};

#define REGISTER_FACTORY( Key, Func ) \
static const BaseFactory& instance = BaseFactory::registerFactory( #Key, Func );

class DerivedFactory : public BaseFactory
{
public:

virtual ~DerivedFactory();
static const DerivedFactory& instance();

private:

DerivedFactory();
};

// in DerivedFactory C++ file, add this line, but fail to compile of course.
REGISTER_FACTORY( DerivedFactory, DerivedFactory::instance );

anda_skoa
30th August 2015, 10:02
Can you show how the factories are being used?
Are you calling a static method of the base class which then iterates over all derived class objects?

Cheers,
_

lni
30th August 2015, 10:26
Yes, I try to register all derived classes static instance (DerivedClass::instance()) into a based class static function pointer array.

Then I can iterates through the function pointer array and call them at appropriate time.

anda_skoa
30th August 2015, 11:56
Maybe this can help: http://doc.qt.io/qt-5/qcoreapplication.html#Q_COREAPP_STARTUP_FUNCTION

Cheers,
_

lni
31st August 2015, 14:52
Hi,

My instance doesn't return void, it s like

static MyFactor& MyFactory::instance();

Is there is solution for this?

Of course I can write another static like

static void init() {
MyFactory::instance();
}

But this would required adding a new static init function...

anda_skoa
31st August 2015, 17:31
What do you need the instance() function with return value for?
You are registering all derived factories with the base class and calling them through there, no?

Cheers,
_

lni
1st September 2015, 21:43
What do you need the instance() function with return value for?
You are registering all derived factories with the base class and calling them through there, no?

Cheers,
_

The returned value (the factory itself) is needed, for instance, an algorithm factory will give all available plugins, so in gui, I can give a choice for users to choose which plugin to use...

anda_skoa
1st September 2015, 23:08
But how do you call a static method on a class that you don't know?

Wouldn't you just have a pointer to the base?

Cheers,
_

lni
2nd September 2015, 16:38
Maybe this can help: http://doc.qt.io/qt-5/qcoreapplication.html#Q_COREAPP_STARTUP_FUNCTION

Cheers,
_

I am using Qt4.8, is there a similar macro for Q_COREAPP_STARTUP_FUNCTION in Qt4? Thanks

anda_skoa
2nd September 2015, 17:57
No, I think that was added in Qt5.

Cheers,
_