From 5160fdc26a3ef7d065e6f01c771cc6431b3a2ff8 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 8 Feb 2022 15:50:17 +0100 Subject: [PATCH] [libcalamares] Port away from KPluginFactory --- src/libcalamares/utils/PluginFactory.h | 111 ++++++++++++++----------- 1 file changed, 63 insertions(+), 48 deletions(-) diff --git a/src/libcalamares/utils/PluginFactory.h b/src/libcalamares/utils/PluginFactory.h index a3371dd72..8e841f5e7 100644 --- a/src/libcalamares/utils/PluginFactory.h +++ b/src/libcalamares/utils/PluginFactory.h @@ -4,10 +4,6 @@ * SPDX-FileCopyrightText: 2017-2018 Adriaan de Groot * SPDX-License-Identifier: GPL-3.0-or-later * - * Based on KPluginFactory from KCoreAddons, KDE project - * SPDX-FileCopyrightText: 2007 Matthias Kretz - * SPDX-FileCopyrightText: 2007 Bernhard Loos - * * Calamares is Free Software: see the License-Identifier above. * * @@ -16,81 +12,100 @@ #ifndef UTILS_PLUGINFACTORY_H #define UTILS_PLUGINFACTORY_H -#include +#include #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()` + * where `T` is the type (subclass of Job or ViewStep) defined by the + * plugin, eg. + * + * ``` + * CALAMARES_PLUGIN_FACTORY_DEFINITION( MyPlugin, registerPlugin() ) + * ``` + * + * 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