Skip to content

Commit

Permalink
libdnf5 IPlugin: Pass IPluginData instead of Base to constructor
Browse files Browse the repository at this point in the history
IPluginData was introduced to allow future changes to the passed dataset
without changing the API and ABI.

IPluginData now represents Base. But in the future it may be
a struct/class.

And increases the libdnf5 plugin API version to 2.0.
  • Loading branch information
jrohel authored and jan-kolarik committed Apr 17, 2024
1 parent d94d641 commit 60338b9
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 20 deletions.
8 changes: 5 additions & 3 deletions include/libdnf5/plugin/iplugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ struct Version {
std::uint16_t micro;
};

class IPluginData;

/// @brief A base class for implementing LIBDNF5 plugins that introduce additional logic into the library using hooks.
class IPlugin {
public:
explicit IPlugin(Base & base);
explicit IPlugin(IPluginData & data);
virtual ~IPlugin();

IPlugin() = delete;
Expand Down Expand Up @@ -121,7 +123,7 @@ class IPlugin {
/// Finish the plugin and release all resources obtained by the init method and in hooks.
virtual void finish() noexcept;

Base & get_base() noexcept;
Base & get_base() const noexcept;

private:
class Impl;
Expand All @@ -147,7 +149,7 @@ libdnf5::plugin::Version libdnf_plugin_get_version(void);

/// Creates a new plugin instance. Passes the API version to the plugin.
libdnf5::plugin::IPlugin * libdnf_plugin_new_instance(
libdnf5::LibraryVersion library_version, libdnf5::Base & base, libdnf5::ConfigParser & parser);
libdnf5::LibraryVersion library_version, libdnf5::plugin::IPluginData & data, libdnf5::ConfigParser & parser);

/// Deletes plugin instance.
void libdnf_plugin_delete_instance(libdnf5::plugin::IPlugin * plugin_instance);
Expand Down
2 changes: 1 addition & 1 deletion include/libdnf5/version.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ struct PluginAPIVersion {
std::uint16_t minor; // plugin must implement the `minor` version >= than the libdnf5 to work together
};

static constexpr PluginAPIVersion PLUGIN_API_VERSION{.major = 1, .minor = 0};
static constexpr PluginAPIVersion PLUGIN_API_VERSION{.major = 2, .minor = 0};

/// @return Library version
/// @since 5.0
Expand Down
8 changes: 5 additions & 3 deletions libdnf5-plugins/actions/actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct CommandToRun {

class Actions : public plugin::IPlugin {
public:
Actions(libdnf5::Base & base, libdnf5::ConfigParser &) : IPlugin(base) {}
Actions(libdnf5::plugin::IPluginData & data, libdnf5::ConfigParser &) : IPlugin(data) {}
virtual ~Actions() = default;

PluginAPIVersion get_api_version() const noexcept override { return PLUGIN_API_VERSION; }
Expand Down Expand Up @@ -777,8 +777,10 @@ plugin::Version libdnf_plugin_get_version(void) {
}

plugin::IPlugin * libdnf_plugin_new_instance(
[[maybe_unused]] LibraryVersion library_version, libdnf5::Base & base, libdnf5::ConfigParser & parser) try {
return new Actions(base, parser);
[[maybe_unused]] LibraryVersion library_version,
libdnf5::plugin::IPluginData & data,
libdnf5::ConfigParser & parser) try {
return new Actions(data, parser);
} catch (...) {
return nullptr;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ constexpr const char * attrs_value[]{"Jaroslav Rohel", "[email protected]", "Plu

class PythonPluginLoader : public plugin::IPlugin {
public:
PythonPluginLoader(libdnf5::Base & base, libdnf5::ConfigParser &) : IPlugin(base) {}
PythonPluginLoader(libdnf5::plugin::IPluginData & data, libdnf5::ConfigParser &) : IPlugin(data) {}
virtual ~PythonPluginLoader();

PluginAPIVersion get_api_version() const noexcept override { return PLUGIN_API_VERSION; }
Expand Down Expand Up @@ -327,8 +327,10 @@ plugin::Version libdnf_plugin_get_version(void) {
}

plugin::IPlugin * libdnf_plugin_new_instance(
[[maybe_unused]] LibraryVersion library_version, libdnf5::Base & base, libdnf5::ConfigParser & parser) try {
return new PythonPluginLoader(base, parser);
[[maybe_unused]] LibraryVersion library_version,
libdnf5::plugin::IPluginData & data,
libdnf5::ConfigParser & parser) try {
return new PythonPluginLoader(data, parser);
} catch (...) {
return nullptr;
}
Expand Down
8 changes: 5 additions & 3 deletions libdnf5-plugins/rhsm/rhsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ constexpr const char * attrs_value[]{

class Rhsm : public plugin::IPlugin {
public:
Rhsm(libdnf5::Base & base, libdnf5::ConfigParser &) : IPlugin(base) {}
Rhsm(libdnf5::plugin::IPluginData & data, libdnf5::ConfigParser &) : IPlugin(data) {}
virtual ~Rhsm() = default;

PluginAPIVersion get_api_version() const noexcept override { return PLUGIN_API_VERSION; }
Expand Down Expand Up @@ -153,8 +153,10 @@ plugin::Version libdnf_plugin_get_version(void) {
}

plugin::IPlugin * libdnf_plugin_new_instance(
[[maybe_unused]] LibraryVersion library_version, libdnf5::Base & base, libdnf5::ConfigParser & parser) try {
return new Rhsm(base, parser);
[[maybe_unused]] LibraryVersion library_version,
libdnf5::plugin::IPluginData & data,
libdnf5::ConfigParser & parser) try {
return new Rhsm(data, parser);
} catch (...) {
return nullptr;
}
Expand Down
12 changes: 6 additions & 6 deletions libdnf5/plugin/iplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,23 @@ You should have received a copy of the GNU Lesser General Public License
along with libdnf. If not, see <https://www.gnu.org/licenses/>.
*/

#include "libdnf5/plugin/iplugin.hpp"
#include "iplugin_private.hpp"

namespace libdnf5::plugin {


class IPlugin::Impl {
public:
explicit Impl(Base & base) : base(&base) {}
explicit Impl(IPluginData & data) : data(&data) {}

Base & get_base() const noexcept { return *base; }
Base & get_base() const noexcept { return plugin::get_base(*data); }

private:
Base * base;
IPluginData * data;
};


IPlugin::IPlugin(Base & base) : p_impl(new Impl(base)) {}
IPlugin::IPlugin(IPluginData & data) : p_impl(new Impl(data)) {}

IPlugin::~IPlugin() = default;

Expand All @@ -59,7 +59,7 @@ void IPlugin::post_transaction([[maybe_unused]] const libdnf5::base::Transaction

void IPlugin::finish() noexcept {}

Base & IPlugin::get_base() noexcept {
Base & IPlugin::get_base() const noexcept {
return p_impl->get_base();
}

Expand Down
40 changes: 40 additions & 0 deletions libdnf5/plugin/iplugin_private.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
Copyright Contributors to the libdnf project.
This file is part of libdnf: https://github.com/rpm-software-management/libdnf/
Libdnf is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 of the License, or
(at your option) any later version.
Libdnf is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with libdnf. If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef LIBDNF5_PLUGIN_IPLUGIN_PRIVATE_HPP
#define LIBDNF5_PLUGIN_IPLUGIN_PRIVATE_HPP

#include "libdnf5/plugin/iplugin.hpp"

namespace libdnf5::plugin {

// IPluginData exists to allow the set of passed data to be changed in the future without changing the API and ABI.
// IPluginData now represents Base. But in the future it may be a struct/class.

inline IPluginData & get_iplugin_data(Base & base) noexcept {
return *reinterpret_cast<IPluginData *>(&base);
}

inline Base & get_base(IPluginData & data) noexcept {
return *reinterpret_cast<Base *>(&data);
}

} // namespace libdnf5::plugin

#endif
3 changes: 2 additions & 1 deletion libdnf5/plugin/plugins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.

#include "plugins.hpp"

#include "iplugin_private.hpp"
#include "utils/library.hpp"

#include "libdnf5/base/base.hpp"
Expand Down Expand Up @@ -74,7 +75,7 @@ PluginLibrary::PluginLibrary(Base & base, ConfigParser && parser, const std::str
get_version = reinterpret_cast<TGetVersionFunc>(library.get_address("libdnf_plugin_get_version"));
new_instance = reinterpret_cast<TNewInstanceFunc>(library.get_address("libdnf_plugin_new_instance"));
delete_instance = reinterpret_cast<TDeleteInstanceFunc>(library.get_address("libdnf_plugin_delete_instance"));
iplugin_instance = new_instance(libdnf5::get_library_version(), base, get_config_parser());
iplugin_instance = new_instance(libdnf5::get_library_version(), get_iplugin_data(base), get_config_parser());
}

PluginLibrary::~PluginLibrary() {
Expand Down

0 comments on commit 60338b9

Please sign in to comment.