IgANet
IgANets - Isogeometric Analysis Networks
Loading...
Searching...
No Matches
modelmanager.hpp
Go to the documentation of this file.
1
15#pragma once
16
17#include <exception>
18#include <filesystem>
19#include <map>
20
21#if defined(_WIN32)
22#include <direct.h>
23#include <windows.h>
24#else
25#include <dlfcn.h>
26#include <sys/stat.h>
27#endif
28
29#include <model.hpp>
30#include <webapps_config.hpp>
31
32namespace iganet {
33
38public:
40 ModelHandler() = delete;
42 ModelHandler(const ModelHandler &) = delete;
43
45 ModelHandler(const char *filename, int flags = RTLD_NOW) {
46#if defined(_WIN32)
47 static_cast<void>(flags);
49 if (!dl)
50 throw std::runtime_error("LoadLibrary - error: " + GetLastError());
51 handle.reset(dl, FreeLibrary);
52#elif defined(__APPLE__) || defined(__linux__) || defined(__unix)
53 void *dl = ::dlopen(filename, flags);
54 if (!dl)
55 throw std::runtime_error(::dlerror());
56 handle.reset(dl, ::dlclose);
57#else
58#error("Unsupported operating system")
59#endif
60 }
61
63 void *getSymbol(const char *name) const {
64 if (!handle)
65 throw std::runtime_error(
66 "An error occured while accessing the dynamic library");
67
68 void *symbol = NULL;
69#if defined(_WIN32)
70 *(void **)(&symbol) = (void *)GetProcAddress(handle.get(), name);
71#elif defined(__APPLE__) || defined(__linux__) || defined(__unix)
72 *(void **)(&symbol) = ::dlsym(handle.get(), name);
73#endif
74 if (!symbol)
75 throw std::runtime_error(
76 "An error occured while getting the symbol from the dynamic library");
77
78 return symbol;
79 }
80
82 operator bool() const { return (bool)handle; }
83
84private:
86#if defined(_WIN32)
87 std::shared_ptr<std::remove_pointer<HMODULE>::type> handle;
88#elif defined(__APPLE__) || defined(__linux__) || defined(__unix)
89 std::shared_ptr<void> handle;
90#endif
91};
92
97private:
99 std::map<std::string, std::shared_ptr<ModelHandler>> models;
100
101public:
103 ModelManager() = delete;
104
107 ModelManager(const std::string &path)
108 : ModelManager(std::vector<std::string>({path})) {}
109
110 ModelManager(const std::vector<std::string> &paths) { addModelPath(paths); }
112
114 inline void addModelPath(const std::string &path) {
115 addModelPath(std::vector<std::string>({path}));
116 }
117
119 inline void addModelPath(const std::vector<std::string> &paths) {
120 for (const auto &path : paths) {
121 try {
122 const std::filesystem::path fspath{path};
123 if (std::filesystem::exists(fspath)) {
124 for (const auto &entry :
125 std::filesystem::directory_iterator{fspath}) {
126 if (entry.path().extension() == ".dll" ||
127 entry.path().extension() == ".dylib" ||
128 entry.path().extension() == ".so") {
129 try {
130 auto handler =
131 std::make_shared<ModelHandler>(entry.path().c_str());
132 std::shared_ptr<Model<iganet::real_t>> (*create)(
133 const nlohmann::json &);
134 create =
135 reinterpret_cast<std::shared_ptr<Model<iganet::real_t>> (*)(
136 const nlohmann::json &)>(handler->getSymbol("create"));
137 models[create({})->getName()] = handler;
138 } catch (...) {
139 std::clog << "Unable to create model " << entry << std::endl;
140 }
141 }
142 }
143 }
144 } catch (...) {
145 std::clog << "Unable to open path " << path << std::endl;
146 }
147 }
148 }
149
152 inline std::shared_ptr<Model<iganet::real_t>>
153 create(const std::string &name, const nlohmann::json &json = NULL) const {
154 try {
155 auto model = models.find(name);
156 if (model == models.end())
157 throw InvalidModelException();
158 std::shared_ptr<Model<iganet::real_t>> (*create)(const nlohmann::json &);
159 create = reinterpret_cast<std::shared_ptr<Model<iganet::real_t>> (*)(
160 const nlohmann::json &)>(model->second->getSymbol("create"));
161 return create(json);
162 } catch (...) {
163 throw InvalidModelException();
164 }
165 }
166
169 inline std::shared_ptr<Model<iganet::real_t>>
170 load(const nlohmann::json &json) const {
171
172 for (auto &model : models) {
173 try {
174 std::shared_ptr<Model<iganet::real_t>> (*load)(const nlohmann::json &);
175 load = reinterpret_cast<std::shared_ptr<Model<iganet::real_t>> (*)(
176 const nlohmann::json &)>(model.second->getSymbol("load"));
177 return load(json);
178 } catch (...) { /* try next model */
179 }
180 }
181
182 // No working model found, through exception and quit load request
183 throw InvalidModelException();
184 }
185
187 inline nlohmann::json getModels() const {
188 auto data = nlohmann::json::array();
189 for (auto const &model : models)
190 data.push_back(create(model.first)->getModel());
191 return data;
192 }
193
195 inline virtual void
196 pretty_print(std::ostream &os = std::cout) const noexcept override {
197 os << name();
198 }
199};
200
202inline std::ostream &operator<<(std::ostream &os, const ModelManager &obj) {
203 obj.pretty_print(os);
204 return os;
205}
206
207} // namespace iganet
Model handler.
Definition modelmanager.hpp:37
ModelHandler(const char *filename, int flags=RTLD_NOW)
Constructor from file.
Definition modelmanager.hpp:45
void * getSymbol(const char *name) const
Gets symbol from dynamic library.
Definition modelmanager.hpp:63
ModelHandler(const ModelHandler &)=delete
ModelHandler(ModelHandler &&)=delete
ModelHandler()=delete
Default constructor deleted.
Model manager.
Definition modelmanager.hpp:96
std::map< std::string, std::shared_ptr< ModelHandler > > models
List of models.
Definition modelmanager.hpp:99
ModelManager(const std::vector< std::string > &paths)
Constructor from filesystem.
Definition modelmanager.hpp:110
ModelManager(const std::string &path)
Constructor from filesystem.
Definition modelmanager.hpp:107
std::shared_ptr< Model< iganet::real_t > > load(const nlohmann::json &json) const
Returns a new model instance from binary data stream throws an exception if model cannot be created.
Definition modelmanager.hpp:170
void addModelPath(const std::string &path)
Adds models from given path.
Definition modelmanager.hpp:114
void addModelPath(const std::vector< std::string > &paths)
Adds models from list of directories.
Definition modelmanager.hpp:119
virtual void pretty_print(std::ostream &os=std::cout) const noexcept override
Returns a string representation of the model manager object.
Definition modelmanager.hpp:196
std::shared_ptr< Model< iganet::real_t > > create(const std::string &name, const nlohmann::json &json=NULL) const
Returns a new instance of the requested model and throws an exception if model cannot be found.
Definition modelmanager.hpp:153
nlohmann::json getModels() const
Serializes the list of models to JSON.
Definition modelmanager.hpp:187
ModelManager()=delete
Default constructor deleted.
Full qualified name descriptor.
Definition fqn.hpp:26
virtual const std::string & name() const noexcept
Returns the full qualified name of the object.
Definition fqn.hpp:31
Model capabilities.
Definition boundary.hpp:22
constexpr bool is_SplineType_v
Alias to the value of is_SplineType.
Definition bspline.hpp:3243
std::ostream & operator<<(std::ostream &os, const Boundary< Spline > &obj)
Print (as string) a Boundary object.
Definition boundary.hpp:1978
STL namespace.
InvalidModel exception.
Definition model.hpp:37