AW: KPluginFactory/-Loader as KLibFactory replacement and KDEenhanced QPluginLoader
Nhuh Put
nhuh.put at web.de
Sat Aug 25 02:58:27 BST 2007
> Von: Matthias Kretz
> Gesendet: Freitag, 24. August 2007 12:22
> An: kde-core-devel at kde.org
> Betreff: Re: KPluginFactory/-Loader as KLibFactory replacement and
> KDEenhanced QPluginLoader
>
> First: I'm very much in favour of getting this ready for next monday.
> At least the KPluginFactory part has to be done before 4.0. The
> KPluginLoader could be an addition after 4.0 but I'd rather put it in
> know and see how much of the KLibLoader API we can remove once we have
> KPluginLoader. And we could also remove kgenericfactory.h,
> kgenericfactory.tcc and ktypelist.h if we find a good way to
> automatically port away from KGenericFactory (though I don't see us
> having the man power to do this).
I could also change KLibrary into a wrapper for QLibrary. This would need
only a few lines of code and would make KLibLoader obsolete.
>
> > Index: util/klibloader.h
> > @@ -424,7 +463,7 @@
> > *error = ErrNoFactory;
> > return 0;
> > }
> > - QObject *object = factory->create( parent,
> T::staticMetaObject.className(), args );
> > + QObject *object = factory->create<T>(parent, QVariantList()
> > + <<
> args);
>
> careful with the QStringList -> QVariantList conversion. In
> KPluginFactory you have a different method for conversion. OTOH you
> could probably just call
> factory->create<T>(parent, args) here, it'll just result in two
> deprecation
> warnings.
I didn't check your changes to KLibLoader. Should have done it before
sending the mail. :/ I changed it as you suggested.
>
> > Index: util/klibloader_p.h
>
> If KLibFactory is removed this file is not necessary.
>
I removed it.
> > --- util/kpluginfactory.cpp (revision 0)
> > +++ util/kpluginfactory.cpp (revision 0)
> [...]
> > +KPluginFactory::KPluginFactory(const char *componentName, const
> > +char
> > *catalogName, QObject *parent)
> > + : QObject(parent), d_ptr(new KPluginFactoryPrivate) {
> > + Q_D(KPluginFactory);
> > + d->componentData = *createComponentData();
>
> This one is for compatiblity? For one it's a mem leak. Do it like this:
> KComponentData *kcd = createComponentData();
> if (kcd) {
> d->componentData = *kcd;
> delete kcd;
> }
> OTOH I don't like to have two createComponentData methods. Can you
> tell me why we need the createComponentData(KAboutData *) function?
>
I removed both functions. If a derived class want's to manipulate the
componentdata, it can do so in its constructor.
> [...]
> > +KPluginFactory::KPluginFactory(QObject *parent)
> Where is this ctor needed? Not enough to have the "KPluginFactory(const
> char
> *componentName = 0, const char *catalogName = 0, QObject *parent = 0)"
> ctor?
>
This is for backward compatibility. There a some derived LibFactories. It's
deprecated.
> [...]
> > +KComponentData *KPluginFactory::createComponentData()
> > +{
> > + return new KComponentData();
> > +}
>
> This one should return 0 now.
removed
>
> > Index: util/kpluginfactory.h
> [...]
> > + template<class impl>
> > + static QObject *createInstance(QObject *parent, const QVariantList
> > &args)
> > + {
> > + return new impl(parent, args);
> > + }
>
> Perhaps we'll need another one to ease porting:
> template<class impl>
> static QObject *createOldInstance(QObject *parent, const QVariantList
> &args)
> {
> return new impl(parent, variantListToStringList(args));
> }
>
> This could ship with the following macro:
>
> #define K_REGISTER_OLD_PLUGIN(impl, iface) \
> registerPlugin(iface::staticMetaObject.className(),
> &createOldInstance<impl>,
> QString());
>
> Then the current code looking like this:
> typedef KGenericFactory<MyPluginImpl> MyFactory;
> K_EXPORT_COMPONENT_FACTORY(libname, MyFactory("componentName"))
>
> could automatically be ported to:
> K_PLUGIN_FACTORY(MyFactory, K_REGISTER_OLD_PLUGIN(MyPluginImpl, QObject))
> K_EXPORT_PLUGIN(MyFactory)
> the interface part is a bit of a problem though, often what we want is
> MyPluginImpl::staticMetaObject().superClass()->className() instead of
> QObject
I could do this, but I'm not sure, if it's worth the effort. It would still
depend on deprecated stuff.
> > + virtual void setupTranslations();
>
> What are the use cases for having this virtual? I know KGenericFactory had
> it
> virtual, but was it ever reimplemented?
It's used for KOffice filters. They use the "kofficefilters" catalog, not
the component name. There are probably some other solutions.
>
> > + void initializeMessageCatalog();
>
> Do we need that in the public class. I'd like to move this function to the
> private if possible.
I made it private.
>
> > + virtual KDE_DEPRECATED QObject *createObject(QObject *parent, const
> > char *className, const QStringList &args);
>
> AFAIK marking this function deprecated only gives a warning when compiling
> KPluginFactory, not when reimplementing the function.
>
Well, it tells the human reader, that it's deprecated (if he locks at the
base class). I don't know a better solution.
> [...]
> > Index: util/kpluginloader.h
> [...]
> > +#include <QtCore/qplugin.h>
> That's <QtCore/QtPlugin>
>
changed
> [...]
> > +#define K_EXPORT_PLUGIN2(library, factory) \
> > +Q_EXPORT_PLUGIN2(library, factory) \
> > +K_PLUGIN_VERIFICATION_DATA
> > +
> > +#define K_EXPORT_PLUGIN(factory) K_EXPORT_PLUGIN2(factory, factory)
>
> Do we need this?
> First question: Will we ever support statically compiled in plugins? If
> not
> then
> #define K_EXPORT_PLUGIN(factory) \
> Q_EXPORT_PLUGIN(factory) \
> K_PLUGIN_VERIFICATION_DATA
removed
>
> is enough. Otherwise we should define
> #define K_EXPORT_PLUGIN(library, factory) \
> Q_EXPORT_PLUGIN2(library, factory) \
> K_PLUGIN_VERIFICATION_DATA
>
> For max convenience (and too many macros probably) we could also provide
> K_EXPORT_PLUGIN_FACTORY(name, pluginRegistrations) \
> K_PLUGIN_FACTORY(name, pluginRegistrations) \
> K_EXPORT_PLUGIN(name)
>
> > +class KDECORE_EXPORT KPluginLoader : public QPluginLoader
> > +{
> > + Q_OBJECT
> > + Q_PROPERTY(QString fileName READ fileName)
> > + Q_PROPERTY(QString pluginName READ fileName)
> > +public:
> > + explicit KPluginLoader(const QString &plugin, const KComponentData
> > &componentdata = KGlobal::mainComponent(), QObject *parent = 0); +
> > explicit KPluginLoader(const KService &service, const KComponentData
> > &componentdata = KGlobal::mainComponent(), QObject *parent = 0); +
> > ~KPluginLoader();
> > +
> > + KPluginFactory *factory();
> > +
> > + QString pluginName() const;
> > +
> > + bool isLoaded() const;
> > +
> > + bool load();
>
> What is this method needed for if it's already called automatically from
> the
> ctor?
I made it protected.
PutHuhn
-------------- next part --------------
A non-text attachment was scrubbed...
Name: kpluginfactoryloader.zip
Type: application/octet-stream
Size: 7290 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20070825/6e130493/attachment.obj>
More information about the kde-core-devel
mailing list