[libcalamares] Port away from KPluginFactory

This commit is contained in:
Adriaan de Groot 2022-02-08 15:50:17 +01:00
parent 8f769006d6
commit 5160fdc26a

View File

@ -4,10 +4,6 @@
* SPDX-FileCopyrightText: 2017-2018 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Based on KPluginFactory from KCoreAddons, KDE project
* SPDX-FileCopyrightText: 2007 Matthias Kretz <kretz@kde.org>
* SPDX-FileCopyrightText: 2007 Bernhard Loos <nhuh.put@web.de>
*
* Calamares is Free Software: see the License-Identifier above.
*
*
@ -16,81 +12,100 @@
#ifndef UTILS_PLUGINFACTORY_H
#define UTILS_PLUGINFACTORY_H
#include <KPluginFactory>
#include <QObject>
#define CalamaresPluginFactory_iid "io.calamares.PluginFactory"
/** @brief Plugin factory for Calamares
*
* Try to re-use KPluginFactory as much as possible (since the
* old code for PluginFactory was a fork of an old version of
* exactly that).
* A Calamares plugin contains just one kind of plugin -- either
* a job, or a viewstep -- so the factory is straightforward.
* It gets a single CreateInstanceFunction and calls that;
* the function is set when registerPlugin() is called in a subclass.
*
* The current createInstance() method passes more arguments
* to the job and viewstep constructors than we want; chasing
* that change means modifying each Calamares module. This class
* implements a version of createInstance() with fewer arguments
* and overloads registerPlugin() to use that.
*/
class CalamaresPluginFactory : public KPluginFactory
class CalamaresPluginFactory : public QObject
{
Q_OBJECT
public:
explicit CalamaresPluginFactory()
: KPluginFactory()
{
}
explicit CalamaresPluginFactory() {}
~CalamaresPluginFactory() override;
/** @brief Create an object from the factory.
*
* Ignores all the @p args since they are not used. Calls
* Calamares constructors for the Jobs and ViewSteps.
*/
template < class impl, class ParentType >
static QObject* createInstance( QWidget* parentWidget, QObject* parent, const QVariantList& args )
typedef QObject* ( *CreateInstanceFunction )( QObject* );
template < class T >
T* create( QObject* parent = nullptr )
{
Q_UNUSED( parentWidget )
Q_UNUSED( args )
ParentType* p = nullptr;
if ( parent )
auto* op = fn ? fn( parent ) : nullptr;
if ( !op )
{
p = qobject_cast< ParentType* >( parent );
Q_ASSERT( p );
return nullptr;
}
return new impl( p );
T* tp = qobject_cast< T* >( op );
if ( !tp )
{
delete op;
}
return tp;
}
/** @brief register a plugin
*
* The Calamares version doesn't accept keywords, and uses
* the Calamares createInstance() version which ignores
* the QVariantList of arguments.
*/
template < class T >
void registerPlugin()
{
KPluginFactory::registerPlugin< T >( QString(), &createInstance< T, QObject > );
}
protected:
CreateInstanceFunction fn = nullptr;
};
/** @brief declare a Calamares Plugin Factory
*
* This would be defined as K_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY,
* except that does not actually use the base factory class that is
* passed in.
* There should be one declaration -- generally alongside the
* class definition for the Job or ViewStep that the plugin is
* going to provide, in the header -- and one definition -- in
* the corresponding implementation.
*/
#define CALAMARES_PLUGIN_FACTORY_DECLARATION( name ) \
class name : public CalamaresPluginFactory \
{ \
Q_OBJECT \
Q_INTERFACES( KPluginFactory ) \
Q_INTERFACES( CalamaresPluginFactory ) \
Q_PLUGIN_METADATA( IID CalamaresPluginFactory_iid ) \
public: \
explicit name(); \
~name() override; \
template < class T > \
static QObject* createInstance( QObject* parent ) \
{ \
return new T( parent ); \
} \
template < class T > \
void registerPlugin() \
{ \
fn = createInstance< T >; \
} \
};
/** @brief Define a Calamares Plugin Factory
*
* This should be done exactly once, generally in the translation
* unit containing the definitions for the main class of the plugin,
* either the Job or the ViewStep definitions.
*
* The @p name must match the name used in the declaration, while
* @p pluginRegistrations should be a single call to `registerPlugin<T>()`
* where `T` is the type (subclass of Job or ViewStep) defined by the
* plugin, eg.
*
* ```
* CALAMARES_PLUGIN_FACTORY_DEFINITION( MyPlugin, registerPlugin<MyPluginJob>() )
* ```
*
* Leaving out the `()` will lead to generally-weird compiler warnings.
*/
#define CALAMARES_PLUGIN_FACTORY_DEFINITION( name, pluginRegistrations ) \
K_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY( name, CalamaresPluginFactory, pluginRegistrations )
name::name() \
: CalamaresPluginFactory() \
{ \
pluginRegistrations; \
} \
name::~name() {}
Q_DECLARE_INTERFACE( CalamaresPluginFactory, CalamaresPluginFactory_iid )
#endif