gfactory
gfactory.h
Go to the documentation of this file.
1 #pragma once
9 #include <memory>
10 #include <string>
11 #include <string_view>
12 #include <unordered_map>
13 
14 #include "gdl.h"
15 #include "glogger.h"
16 
17 
22 class GFactoryBase {
23 public:
24  virtual ~GFactoryBase() = default;
26  [[nodiscard]] virtual void* Create() = 0;
27 };
28 
33 template <class T>
34 class GFactory final : public GFactoryBase {
35 public:
36  [[nodiscard]] void* Create() override { return new T(); }
37 };
38 
53 class GManager {
54 public:
56  explicit GManager(std::shared_ptr<GLogger> logger, std::string description = "");
57 
59  GManager(const GManager&) = delete;
60  GManager& operator=(const GManager&) = delete;
62  GManager(GManager&&) noexcept = default;
63  GManager& operator=(GManager&&) noexcept = default;
64 
65  ~GManager();
66 
68  template <class Derived>
69  void RegisterObjectFactory(std::string_view name);
70 
72  template <class Base>
73  [[nodiscard]] Base* CreateObject(std::string_view name) const;
74 
76  template <class T>
77  [[nodiscard]] T* LoadAndRegisterObjectFromLibrary(std::string_view name, GOptions *gopts);
78 
80  void clearDLMap() noexcept;
81 
82 private:
83  void registerDL(std::string_view name);
84 
85  std::unordered_map<std::string, std::unique_ptr<GFactoryBase>> factoryMap_;
86  std::unordered_map<std::string, std::unique_ptr<DynamicLib>> dlMap_;
87 
88  std::string gname;
89  std::shared_ptr<GLogger> log;
90 };
91 
92 
93 inline GManager::GManager(std::shared_ptr<GLogger> logger, std::string description)
94  : log(logger) {
95  gname = log->get_verbosity_name() + description;
96  log->debug(CONSTRUCTOR, gname);
97 }
98 
100  log->debug(DESTRUCTOR, gname);
101  clearDLMap();
102 }
103 
104 inline void GManager::clearDLMap() noexcept { dlMap_.clear(); }
105 
106 inline void GManager::registerDL(std::string_view name) {
107  const std::string filename = std::string{name} + ".gplugin";
108  dlMap_.emplace(std::string{name},
109  std::make_unique<DynamicLib>(log, filename));
110  log->debug(NORMAL, "Loading DL ", name);
111 }
112 
113 template <class Derived>
114 void GManager::RegisterObjectFactory(std::string_view name) {
115  factoryMap_.emplace(std::string{name}, std::make_unique<GFactory<Derived>>());
116  log->debug(NORMAL, "Registering ", name, " into factory map");
117 }
118 
119 template <class Base>
120 Base* GManager::CreateObject(std::string_view name) const {
121  auto it = factoryMap_.find(std::string{name});
122  if (it == factoryMap_.end()) {
123  log->error(ERR_FACTORYNOTFOUND,
124  "Couldn't find factory <", name, "> in factory map.");
125  }
126  log->debug(NORMAL, "Creating instance of <", name, "> factory.");
127  return static_cast<Base*>(it->second->Create());
128 }
129 
130 template <class T>
131 T* GManager::LoadAndRegisterObjectFromLibrary(std::string_view name, GOptions *gopts) {
132  registerDL(name);
133  auto& dynamicLib = dlMap_.at(std::string{name});
134  if (dynamicLib && dynamicLib->handle) {
135  auto factory = T::instantiate(dynamicLib->handle);
136  // in c++20 it is possible to use introspection with concept thuse removing the
137  // need of having to define a set_loggers function
138  // it didn't work on 5/21/2025 so for now the function is required
139  factory->set_loggers(gopts);
140  return factory;
141  }
142  log->error(ERR_DLHANDLENOTFOUND, "Plugin ", name, " could not be loaded.");
143 }
Abstract creator used by GManager through type‑erased pointers.
Definition: gfactory.h:22
virtual ~GFactoryBase()=default
virtual void * Create()=0
Pure virtual instantiation hook implemented by the templated concrete factory.
Concrete factory that creates objects of type T.
Definition: gfactory.h:34
void * Create() override
Pure virtual instantiation hook implemented by the templated concrete factory.
Definition: gfactory.h:36
Owns factories and dynamically‑loaded libraries, providing run‑time creation.
Definition: gfactory.h:53
GManager & operator=(const GManager &)=delete
GManager(GManager &&) noexcept=default
Allow move for container support.
GManager(const GManager &)=delete
No copy – the manager owns unique resources.
Base * CreateObject(std::string_view name) const
Create an instance of previously registered factory as Base*.
Definition: gfactory.h:120
GManager(std::shared_ptr< GLogger > logger, std::string description="")
Construct with logger and a human‑readable name.
Definition: gfactory.h:93
T * LoadAndRegisterObjectFromLibrary(std::string_view name, GOptions *gopts)
Load a shared library, look up its instantiate symbol, and return object.
Definition: gfactory.h:131
~GManager()
Definition: gfactory.h:99
void clearDLMap() noexcept
Explicit cleanup (also called by destructor) – idempotent.
Definition: gfactory.h:104
void RegisterObjectFactory(std::string_view name)
Register a concrete factory under name.
Definition: gfactory.h:114
#define ERR_FACTORYNOTFOUND
Definition: gdl.h:23
#define ERR_DLHANDLENOTFOUND
Definition: gdl.h:24
Structure to load dynamically symbols from a shared library.
Definition: gdl.h:31