Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting/getting global variables in Plugins #19

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions include/ppplugin/c/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,25 @@ class CPlugin {
plugin_, function_name, std::forward<Args>(args)...);
}

// TODO: remove code duplication here and in C++ plugin
template <typename VariableType>
CallResult<VariableType> global(const std::string& variable_name)
{
auto p = detail::boost_dll::getSymbol(plugin_, variable_name);
if (p.hasValue()) {
return *reinterpret_cast<VariableType*>(p.value().value());
}
return { p.error().value() };
}
template <typename VariableType>
void global(const std::string& variable_name, VariableType&& new_value)
{
auto p = detail::boost_dll::getSymbol(plugin_, variable_name);
if (p.hasValue()) {
*reinterpret_cast<VariableType*>(p.value().value()) = std::forward<VariableType>(new_value);
}
}

private:
CPlugin() = default;

Expand Down
18 changes: 18 additions & 0 deletions include/ppplugin/cpp/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,24 @@ class CppPlugin {
plugin_, function_name, std::forward<Args>(args)...);
}

template <typename VariableType>
CallResult<VariableType> global(const std::string& variable_name)
{
auto p = detail::boost_dll::getSymbol(plugin_, variable_name);
if (p.hasValue()) {
return *reinterpret_cast<VariableType*>(p.value().value());
}
return { p.error().value() };
}
template <typename VariableType>
void global(const std::string& variable_name, VariableType&& new_value)
{
auto p = detail::boost_dll::getSymbol(plugin_, variable_name);
if (p.hasValue()) {
*reinterpret_cast<VariableType*>(p.value().value()) = std::forward<VariableType>(new_value);
}
}

private:
CppPlugin() = default;

Expand Down
1 change: 1 addition & 0 deletions include/ppplugin/detail/boost_dll_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace ppplugin::detail::boost_dll {

[[nodiscard]] CallResult<void*> getFunctionSymbol(const boost::dll::shared_library& library, const std::string& function_name);
[[nodiscard]] CallResult<void*> getFunctionPointerSymbol(const boost::dll::shared_library& library, const std::string& function_name);
[[nodiscard]] CallResult<void**> getSymbol(const boost::dll::shared_library& library, const std::string& function_name);

template <bool isPointer, typename ReturnValue, typename... Args>
[[nodiscard]] CallResult<ReturnValue> call(const boost::dll::shared_library& library, const std::string& function_name, Args&&... args)
Expand Down
18 changes: 18 additions & 0 deletions include/ppplugin/lua/lua_script.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@ class LuaScript {
return { CallError::Code::symbolNotFound };
}

template <typename VariableType>
CallResult<VariableType> global(const std::string& variable_name)
{
if (state_.pushGlobal(variable_name)) {
if (auto value = state_.pop<VariableType>()) {
return value.value();
}
return { CallError::Code::unknown };
}
return { CallError::Code::symbolNotFound };
}
template <typename VariableType>
void global(const std::string& variable_name, VariableType&& new_value)
{
state_.push(new_value);
state_.markGlobal(variable_name);
}

private:
LuaScript();

Expand Down
11 changes: 11 additions & 0 deletions include/ppplugin/lua/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ class LuaPlugin {
return script_.call<ReturnValue>(function_name, std::forward<Args>(args)...);
}

template <typename VariableType>
CallResult<VariableType> global(const std::string& variable_name)
{
return script_.global<VariableType>(variable_name);
}
template <typename VariableType>
void global(const std::string& variable_name, VariableType&& new_value)
{
script_.global(variable_name, std::forward<VariableType>(new_value));
}

private:
explicit LuaPlugin(LuaScript&& script)
: script_ { std::move(script) }
Expand Down
11 changes: 11 additions & 0 deletions include/ppplugin/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ class GenericPlugin {
template <typename ReturnValue, typename... Args>
[[nodiscard]] CallResult<ReturnValue> call(const std::string& function_name, Args&&... args);

template <typename VariableType>
CallResult<VariableType> global(const std::string& variable_name)
{
return plugin_.global(variable_name);
}
template <typename VariableType>
void global(const std::string& variable_name, VariableType&& new_value)
{
plugin_.global(variable_name, std::forward<VariableType>(new_value));
}

template <typename P>
std::optional<std::reference_wrapper<P>> plugin();

Expand Down
11 changes: 11 additions & 0 deletions include/ppplugin/python/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ class PythonPlugin {
template <typename ReturnValue, typename... Args>
[[nodiscard]] CallResult<ReturnValue> call(const std::string& function_name, Args&&... args);

template <typename VariableType>
CallResult<VariableType> global(const std::string& variable_name)
{
return interpreter_.global<VariableType>(variable_name);
}
template <typename VariableType>
void global(const std::string& variable_name, VariableType&& new_value)
{
interpreter_.global(variable_name, std::forward<VariableType>(new_value));
}

private:
PythonPlugin() = default;

Expand Down
16 changes: 16 additions & 0 deletions include/ppplugin/python/python_interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ class PythonInterpreter {
template <typename ReturnValue, typename... Args>
CallResult<ReturnValue> call(const std::string& function_name, Args&&... args);

template <typename VariableType>
CallResult<VariableType> global(const std::string& variable_name)
{
// TODO implement global for Python
(void)variable_name;
throw std::logic_error { "unimplemented" };
}
template <typename VariableType>
void global(const std::string& variable_name, VariableType&& new_value)
{
// TODO implement global for Python
(void)variable_name;
(void)new_value;
throw std::logic_error { "unimplemented" };
}

private:
PyThreadState* state() { return state_.get(); }
PyObject* mainModule() { return main_module_.get(); }
Expand Down
30 changes: 20 additions & 10 deletions src/boost_dll_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <boost/filesystem/path.hpp>

namespace {
std::optional<ppplugin::CallError> isCallable(const boost::dll::shared_library& library, const std::string& function_name)
[[nodiscard]] std::optional<ppplugin::CallError> isCallable(const boost::dll::shared_library& library, const std::string& function_name)
{
if (!library.is_loaded()) {
return ppplugin::CallError::Code::notLoaded;
Expand All @@ -25,7 +25,7 @@ std::optional<ppplugin::CallError> isCallable(const boost::dll::shared_library&
} // namespace

namespace ppplugin::detail::boost_dll {
[[nodiscard]] CallResult<void*> getFunctionSymbol(const boost::dll::shared_library& library, const std::string& function_name)
CallResult<void*> getFunctionSymbol(const boost::dll::shared_library& library, const std::string& function_name)
{
if (auto error = isCallable(library, function_name)) {
return { *error };
Expand All @@ -41,7 +41,7 @@ namespace ppplugin::detail::boost_dll {
return { CallError::Code::unknown };
}

[[nodiscard]] CallResult<void*> getFunctionPointerSymbol(const boost::dll::shared_library& library, const std::string& function_name)
CallResult<void*> getFunctionPointerSymbol(const boost::dll::shared_library& library, const std::string& function_name)
{
if (auto error = isCallable(library, function_name)) {
return { *error };
Expand All @@ -57,13 +57,23 @@ namespace ppplugin::detail::boost_dll {
return { CallError::Code::unknown };
}

/**
* Attempt to load shared library from given path.
*
* Returned library object is not necessarily loaded, check
* boost::dll::shared_library::is_loaded().
*/
[[nodiscard]] std::optional<boost::dll::shared_library> loadSharedLibrary(
CallResult<void**> getSymbol(const boost::dll::shared_library& library, const std::string& function_name)
{
if (auto error = isCallable(library, function_name)) {
return { *error };
}
try {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
if (auto** symbol = &library.get<void*>(function_name)) {
return symbol;
}
} catch (const std::exception& exception) {
return CallError { CallError::Code::unknown, exception.what() };
}
return { CallError::Code::unknown };
}

std::optional<boost::dll::shared_library> loadSharedLibrary(
const std::filesystem::path& plugin_library_path)
{
if (!std::filesystem::exists(plugin_library_path)) {
Expand Down