21#include <unordered_map>
25#include <gemc/gbase/gbase.h>
52 [[nodiscard]]
virtual void*
Create() = 0;
77 explicit GFactory(
const std::shared_ptr<GOptions>& gopts)
79 static_assert(std::is_constructible_v<T, const std::shared_ptr<GOptions>&>,
80 "T must be constructible from const std::shared_ptr<GOptions>&");
87 [[nodiscard]]
void*
Create()
override {
return static_cast<void*
>(
new T(gopts_)); }
91 std::shared_ptr<GOptions> gopts_;
160 template <
class Derived>
170 template <
class Derived>
183 template <
class Base>
184 [[nodiscard]] Base*
CreateObject(std::string_view name)
const;
200 const std::shared_ptr<GOptions>& gopts);
215 void registerDL(std::string_view name);
218 std::unordered_map<std::
string, std::unique_ptr<
GFactoryBase>> factoryMap_;
221 std::unordered_map<std::
string, std::shared_ptr<
DynamicLib>> dlMap_;
237inline void GManager::registerDL(std::string_view name) {
238 const std::string basename = std::string{name} +
".gplugin";
242 std::string filename = basename;
245 if (searchPath.empty()) {
246 if (
const char* env = std::getenv(
"GEMC_PLUGIN_PATH")) { searchPath = env; }
248 if (!searchPath.empty()) {
249 std::istringstream ss(searchPath);
251 while (std::getline(ss, dir,
':')) {
252 const std::string candidate = dir +
"/" + basename;
253 if (std::filesystem::exists(candidate)) {
254 filename = candidate;
261 dlMap_.emplace(std::string{name},
262 std::make_shared<DynamicLib>(
log, filename));
263 log->
debug(NORMAL,
"Loading DL ", name,
" (resolved: ", filename,
")");
266template <
class Derived>
269 factoryMap_.emplace(std::string{name}, std::make_unique<GFactory<Derived>>());
273template <
class Derived>
275 factoryMap_.emplace(std::string{name}, std::make_unique<GFactory<Derived>>(gopts));
281 auto it = factoryMap_.find(std::string{name});
282 if (it == factoryMap_.end()) {
284 "Couldn't find factory <", name,
"> in factory map.");
289 return static_cast<Base*
>(it->second->Create());
294 const std::shared_ptr<GOptions>& gopts) {
296 auto pluginName = std::string{name};
297 auto pluginLib = dlMap_.at(pluginName);
299 if (pluginLib && pluginLib->handle) {
301 T* raw = T::instantiate(pluginLib->handle, gopts);
302 if (raw ==
nullptr) {
307 raw->set_loggers(gopts);
311 return std::shared_ptr<T>(raw, [pluginLib](T* ptr) {
317 const char* envPath = std::getenv(
"GEMC_PLUGIN_PATH");
319 "Plugin ", name,
".gplugin could not be loaded.\n",
320 " GEMC_PLUGIN_PATH = ", (envPath ? envPath :
"(not set)"),
"\n",
321 " Hint: set GEMC_PLUGIN_PATH or use -plugin_path=<dir> to point to the directory ",
322 "containing *.gplugin files.");
std::shared_ptr< GLogger > log
Type-erased factory interface used by GManager.
virtual void * Create()=0
Instantiate the concrete product.
virtual ~GFactoryBase()=default
Virtual destructor for safe deletion through base pointer.
Concrete factory that creates objects of type T.
GFactory(const std::shared_ptr< GOptions > &gopts)
Construct a factory bound to a specific configuration/options instance.
void * Create() override
Allocate a new instance of T.
void debug(debug_type type, Args &&... args) const
void error(int exit_code, Args &&... args) const
Factory registry and dynamic-library manager for run-time creation of plugin objects.
GManager(const std::shared_ptr< GOptions > &gopt)
Construct a manager instance.
GManager(GManager &&) noexcept=default
Allow move for container support.
std::shared_ptr< T > LoadAndRegisterObjectFromLibrary(std::string_view name, const std::shared_ptr< GOptions > &gopts)
Load a plugin library and instantiate an object from it.
GManager(const GManager &)=delete
No copy – the manager owns unique resources (factory objects and loaded libraries).
Base * CreateObject(std::string_view name) const
Create an instance of a previously registered factory.
GManager & operator=(const GManager &)=delete
void clearDLMap() noexcept
Release all loaded dynamic libraries.
void RegisterObjectFactory(std::string_view name)
Register a concrete factory under a string key.
std::string getScalarString(const std::string &tag) const
#define ERR_FACTORYNOTFOUND
#define ERR_DLHANDLENOTFOUND
constexpr const char * PLUGIN_LOGGER
Logger channel used by the gfactory module and plugins loaded through it.
Helper that loads a shared library and holds its POSIX handle.