gfactory
Loading...
Searching...
No Matches
gfactory.h
Go to the documentation of this file.
1#pragma once
9// C++
10#include <memory>
11#include <string>
12#include <string_view>
13#include <unordered_map>
14
15// gfactory
16#include "gdl.h"
17#include "gbase.h"
18#include "gfactory_options.h"
19
25public:
26 virtual ~GFactoryBase() = default;
28 [[nodiscard]] virtual void* Create() = 0;
29};
30
35template <class T>
36class GFactory final : public GFactoryBase {
37public:
38 explicit GFactory(const std::shared_ptr<GOptions>& gopts)
39 : gopts_(gopts) {
40 static_assert(std::is_constructible_v<T, const std::shared_ptr<GOptions>&>,
41 "T must be constructible from const std::shared_ptr<GOptions>&");
42 }
43
44 [[nodiscard]] void* Create() override { return static_cast<void*>(new T(gopts_)); }
45
46private:
47 std::shared_ptr<GOptions> gopts_;
48};
49
64class GManager : public GBase<GManager> {
65public:
67 explicit GManager(const std::shared_ptr<GOptions>& gopt) : GBase(gopt, PLUGIN_LOGGER) {
68 }
69
71 GManager(const GManager&) = delete;
72 GManager& operator=(const GManager&) = delete;
74 GManager(GManager&&) noexcept = default;
75 GManager& operator=(GManager&&) noexcept = default;
76
77 ~GManager() override { clearDLMap(); }
78
80 template <class Derived>
81 void RegisterObjectFactory(std::string_view name);
82
83 template <class Derived>
84 void RegisterObjectFactory(std::string_view name, const std::shared_ptr<GOptions>& gopts);
85
87 template <class Base>
88 [[nodiscard]] Base* CreateObject(std::string_view name) const;
89
91 template <class T>
92 [[nodiscard]] std::shared_ptr<T> LoadAndRegisterObjectFromLibrary(std::string_view name, const std::shared_ptr<GOptions>& gopts);
93
95 void clearDLMap() noexcept;
96
97private:
98 void registerDL(std::string_view name);
99
100 std::unordered_map<std::string, std::unique_ptr<GFactoryBase>> factoryMap_;
101 std::unordered_map<std::string, std::shared_ptr<DynamicLib>> dlMap_;
102
103 std::string gname;
104};
105
106
107inline void GManager::clearDLMap() noexcept { dlMap_.clear(); }
108
109inline void GManager::registerDL(std::string_view name) {
110 const std::string filename = std::string{name} + ".gplugin";
111 dlMap_.emplace(std::string{name},
112 std::make_shared<DynamicLib>(log, filename));
113 log->debug(NORMAL, "Loading DL ", name);
114}
115
116template <class Derived>
117void GManager::RegisterObjectFactory(std::string_view name) {
118 factoryMap_.emplace(std::string{name}, std::make_unique<GFactory<Derived>>());
119 log->debug(NORMAL, "Registering ", name, " into factory map");
120}
121
122template <class Derived>
123void GManager::RegisterObjectFactory(std::string_view name, const std::shared_ptr<GOptions>& gopts) {
124 factoryMap_.emplace(std::string{name}, std::make_unique<GFactory<Derived>>(gopts));
125 log->debug(NORMAL, "Registering ", name, " into factory map");
126}
127
128template <class Base>
129Base* GManager::CreateObject(std::string_view name) const {
130 auto it = factoryMap_.find(std::string{name});
131 if (it == factoryMap_.end()) {
132 log->error(ERR_FACTORYNOTFOUND,
133 "Couldn't find factory <", name, "> in factory map.");
134 }
135 log->debug(NORMAL, "Creating instance of <", name, "> factory.");
136 return static_cast<Base*>(it->second->Create());
137}
138
139template <class T>
140std::shared_ptr<T> GManager::LoadAndRegisterObjectFromLibrary(std::string_view name, const std::shared_ptr<GOptions>& gopts) {
141 registerDL(name);
142 auto pluginName = std::string{name};
143 auto pluginLib = dlMap_.at(pluginName); // shared_ptr<DynamicLib>
144
145 if (pluginLib && pluginLib->handle) {
146 T* raw = T::instantiate(pluginLib->handle, gopts);
147 raw->set_loggers(gopts);
148
149 // return shared_ptr<T> with deleter that captures pluginLib
150 return std::shared_ptr<T>(raw, [pluginLib](T* ptr) {
151 delete ptr;
152 // pluginLib keeps .so alive until ptr is destroyed
153 });
154 }
155
156 log->error(ERR_DLHANDLENOTFOUND, "Plugin ", name, " could not be loaded.");
157}
Abstract creator used by GManager through type‑erased pointers.
Definition gfactory.h:24
virtual void * Create()=0
Pure virtual instantiation hook implemented by the templated concrete factory.
virtual ~GFactoryBase()=default
Concrete factory that creates objects of type T.
Definition gfactory.h:36
GFactory(const std::shared_ptr< GOptions > &gopts)
Definition gfactory.h:38
void * Create() override
Pure virtual instantiation hook implemented by the templated concrete factory.
Definition gfactory.h:44
Owns factories and dynamically‑loaded libraries, providing run‑time creation.
Definition gfactory.h:64
GManager(const std::shared_ptr< GOptions > &gopt)
Construct with logger and a human‑readable name.
Definition gfactory.h:67
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 shared library, look up its instantiate symbol, and return object.
Definition gfactory.h:140
GManager(const GManager &)=delete
No copy – the manager owns unique resources.
Base * CreateObject(std::string_view name) const
Create an instance of the previously registered factory.
Definition gfactory.h:129
GManager & operator=(const GManager &)=delete
void clearDLMap() noexcept
Explicit cleanup (also called by destructor) – idempotent.
Definition gfactory.h:107
void RegisterObjectFactory(std::string_view name)
Register a concrete factory under a name.
Definition gfactory.h:117
#define ERR_FACTORYNOTFOUND
Definition gdl.h:23
#define ERR_DLHANDLENOTFOUND
Definition gdl.h:24
constexpr const char * PLUGIN_LOGGER
Structure to load dynamically symbols from a shared library.
Definition gdl.h:31