tags:

views:

252

answers:

2

I'm making a task-based program that needs to have plugins. Tasks need to have properties which can be easily edited, I think this can be done with Qt's Meta-Object Compiler reflection capabilities (I could be wrong, but I should be able to stick this in a QtPropertyBrowser?)

So here's the base:

class Task : public QObject
{
Q_OBJECT
public:
    explicit Task(QObject *parent = 0) : QObject(parent){}

    virtual void run() = 0;

signals:
    void taskFinished(bool success = true);
}

Then a plugin might have this task:

class PrinterTask : public Task
{
Q_OBJECT
public:
    explicit PrinterTask(QObject *parent = 0) : Task(parent) {}

    void run()
    {
        Printer::getInstance()->Print(this->getData());  // fictional
        emit taskFinished(true); 
    }

    inline const QString &getData() const;
    inline void setData(QString data);

Q_PROPERTY(QString data READ getData WRITE setData) // for reflection
}

In a nutshell, here's what I want to do:

// load plugin
// find all the Tasks interface implementations in it
// have user able to choose a Task and edit its specific Q_PROPERTY's
// run the TASK

It's important that one .dll has multiple tasks, because I want them to be associated by their module. For instance, "FileTasks.dll" could have tasks for deleting files, making files, etc.

The only problem with Qt's plugin setup is I want to store X amount of Tasks in one .dll module. As far as I can tell, you can only load one interface per plugin (I could be wrong?). If so, the only possible way to do accomplish what I want is to create a FactoryInterface with string based keys which return the objects (as in Qt's Plug-And-Paint example), which is a terrible boilerplate that I would like to avoid.

Anyone know a cleaner C++ plugin architecture than Qt's to do what I want?

Also, am I safely assuming Qt's reflection capabilities will do what I want (i.e. able to edit an unknown dynamically loaded tasks' properties with the QtPropertyBrowser before dispatching)?

+3  A: 

Sounds like you've been giving this a thorough thought, which is great and needed. I cannot comment on the Qt specifics, but be sure to not miss out on these pieces of plugin advice, particularly versioning: link text

Johann Gerell
Great read and an example framework solution to boot. Basically it says you just need a smarter Factory system to avoid the boilerplate that the string keys give you, I suppose I was over-thinking the problem. This will probably solve my woes if I can integrate it. Thanks.
Pirate for Profit
+3  A: 

Any reason you are avoiding Qt's built-in plugin framework?

Example here.

Edit: Sorry I missed the

As far as I can tell, you can only load one interface per plugin

before. The plug-and-paint example shows you can implement many interfaces in one plugin. And I'm confused about the string based factory you are talking about, the example uses QObjects, slots, and signals after loading the plugins. The strings are just used to show the name of the plugin in the help menu.

Adam W
I mean a way to easily load many classes that inherit one interface in a plugin. Maybe I'm confused, but it looks like you can only load one of each interface type? Have to use a workaround I think.
Pirate for Profit
Maybe I'm confused as well, you want to have multiple plugins loaded from one dll? First, why other than less files? Second, I believe if that is the case then yes, you are correct. Each dll is only one plugin, but each plugin can implement multiple interfaces. If the only reason you want a single dll is for less files, I would strongly suggest otherwise. Smaller compilation units lead to faster recompile times and easier testing.
Adam W