Loading...
Searching...
No Matches
PluginLoader.h
Go to the documentation of this file.
1/*
2** This file is part of eOn.
3**
4** SPDX-License-Identifier: BSD-3-Clause
5**
6** Copyright (c) 2010--present, eOn Development Team
7** All rights reserved.
8**
9** Repo:
10** https://github.com/TheochemUI/eOn
11*/
12#pragma once
13
30
31#include "eon/DynLib.h"
32
33#include <mutex>
34#include <stdexcept>
35#include <string>
36#include <unordered_map>
37#include <vector>
38
39namespace eonc {
40
41// ---------------------------------------------------------------------------
42// IPluginLoader: injectable ABI. Production uses PluginLoader::instance().
43// ---------------------------------------------------------------------------
45public:
49 virtual void add_config_paths(const std::string &colon_paths) = 0;
50
54 [[nodiscard]] virtual bool lib_present(const char *lib_base) const = 0;
55
57 [[nodiscard]] virtual const std::vector<std::string> &
58 search_paths() const noexcept = 0;
59
61 [[noreturn]] virtual void throw_not_found(const char *lib_base,
62 const char *description) const = 0;
63
68 template <typename Fn>
69 Fn load_sym(const char *lib_base, const char *sym_name) {
70 dynlib::Handle h = open_lib(lib_base);
71 if (!h)
72 return nullptr;
73 return dynlib::loadSym<Fn>(h, sym_name);
74 }
75
76 virtual ~IPluginLoader() = default;
77
78 IPluginLoader(const IPluginLoader &) = delete;
80
81protected:
82 IPluginLoader() = default;
83 virtual dynlib::Handle open_lib(const char *lib_base) = 0;
84};
85
86// ---------------------------------------------------------------------------
87// PluginLoader: process-default search path + dlopen cache (Meyer's
88// singleton).
89// ---------------------------------------------------------------------------
91public:
93 static PluginLoader &instance();
94
95 void add_config_paths(const std::string &colon_paths) override;
96
97 [[nodiscard]] bool lib_present(const char *lib_base) const override;
98
99 [[nodiscard]] const std::vector<std::string> &
100 search_paths() const noexcept override {
101 return m_search_paths;
102 }
103
104 [[noreturn]] void throw_not_found(const char *lib_base,
105 const char *description) const override;
106
107 ~PluginLoader() override;
108 PluginLoader(const PluginLoader &) = delete;
110
111private:
112 PluginLoader();
113 friend class Runtime;
114
115 dynlib::Handle open_lib(const char *lib_base) override;
116 std::vector<std::string> lib_names(const char *lib_base) const;
117 void append_paths(const std::string &path_str, char sep);
118
119 std::vector<std::string> m_search_paths;
120 mutable std::mutex m_mutex;
121 std::unordered_map<std::string, dynlib::Handle> m_handles;
123 std::string m_last_load_error;
125};
126
127} // namespace eonc
IPluginLoader()=default
virtual ~IPluginLoader()=default
virtual void throw_not_found(const char *lib_base, const char *description) const =0
Throw a descriptive error for a missing potential library.
Fn load_sym(const char *lib_base, const char *sym_name)
Load a symbol from a named potential library.
IPluginLoader & operator=(const IPluginLoader &)=delete
virtual const std::vector< std::string > & search_paths() const noexcept=0
Get the current search paths (for diagnostics).
virtual dynlib::Handle open_lib(const char *lib_base)=0
virtual void add_config_paths(const std::string &colon_paths)=0
Inject search paths from the eOn config file.
IPluginLoader(const IPluginLoader &)=delete
virtual bool lib_present(const char *lib_base) const =0
Filesystem probe: a matching library file is on the configured search path.
void throw_not_found(const char *lib_base, const char *description) const override
Throw a descriptive error for a missing potential library.
std::vector< std::string > m_search_paths
void add_config_paths(const std::string &colon_paths) override
Inject search paths from the eOn config file.
dynlib::Handle open_lib(const char *lib_base) override
static PluginLoader & instance()
Thread-safe singleton accessor (Meyer's pattern).
void append_paths(const std::string &path_str, char sep)
std::string m_last_load_error
Last dynlib::error() from a failed open (for throw_not_found).
PluginLoader(const PluginLoader &)=delete
std::vector< std::string > lib_names(const char *lib_base) const
bool lib_present(const char *lib_base) const override
Filesystem probe: a matching library file is on the configured search path.
friend class Runtime
std::unordered_map< std::string, dynlib::Handle > m_handles
const std::vector< std::string > & search_paths() const noexcept override
Get the current search paths (for diagnostics).
~PluginLoader() override
PluginLoader & operator=(const PluginLoader &)=delete
void * Handle
Definition DynLib.h:60
Fn loadSym(Handle h, const char *name) noexcept
Load a symbol and cast to a function pointer type.
Definition DynLib.h:99
RAII resource manager for the ARTn C library with global synchronization.