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;
244 std::string searchPath = gopts_->getOptionalScalarString(
"plugin_path").value_or(
"");
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 %1 (resolved: %2)", name, filename);
266template <
class Derived>
269 factoryMap_.emplace(std::string{name}, std::make_unique<GFactory<Derived>>());
270 log->debug(
NORMAL,
"Registering %1 into factory map", name);
273template <
class Derived>
275 factoryMap_.emplace(std::string{name}, std::make_unique<GFactory<Derived>>(gopts));
276 log->debug(
NORMAL,
"Registering %1 into factory map", name);
281 auto it = factoryMap_.find(std::string{name});
282 if (it == factoryMap_.end()) {
285 log->debug(
NORMAL,
"Creating instance of <%1> factory.", name);
288 return static_cast<Base*
>(it->second->Create());
293 const std::shared_ptr<GOptions>& gopts) {
295 auto pluginName = std::string{name};
296 auto pluginLib = dlMap_.at(pluginName);
298 if (pluginLib && pluginLib->handle) {
300 T* raw = T::instantiate(pluginLib->handle, gopts);
301 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");
320 "Plugin %1.gplugin could not be loaded.\n GEMC_PLUGIN_PATH = %2\n Hint: set GEMC_PLUGIN_PATH or "
321 "use -plugin_path=<dir> to point to the directory containing *.gplugin files.", name,
322 (envPath ? envPath :
"(not set)"));
GBase(const std::shared_ptr< GOptions > &gopt, std::string logger_name="")
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.
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.
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.
constexpr const char * PLUGIN_LOGGER
Logger channel used by the gfactory module and plugins loaded through it.
constexpr int ERR_FACTORYNOTFOUND
constexpr int ERR_DLHANDLENOTFOUND
Helper that loads a shared library and holds its POSIX handle.