PeriDyno 1.0.0
Loading...
Searching...
No Matches
PluginManager.cpp
Go to the documentation of this file.
1#include "PluginManager.h"
2
3#include <ghc/fs_std.hpp>
4
5#include <iostream>
6
7namespace dyno
8{
9 std::shared_ptr<Plugin> Plugin::load(std::string file)
10 {
11 std::shared_ptr<Plugin> plugin = std::make_shared<Plugin>();
12 plugin->mFile = file;
13
14#if !defined(_WIN32)
15 plugin->mHnd = ::dlopen(file.c_str(), RTLD_LAZY);
16#else
17 plugin->mHnd = (void*) ::LoadLibraryA(file.c_str());
18#endif
19 if (plugin->mHnd == nullptr) {
20 return nullptr;
21 }
22
23 plugin->mIsLoaded = true;
24#if !defined(_WIN32)
25 auto dllEntryPoint =
26 reinterpret_cast<PluginEntryFunc>(dlsym(plugin->mHnd, PluginEntryName));
27#else
28 auto dllEntryPoint =
29 reinterpret_cast<PluginEntryFunc>(GetProcAddress((HMODULE)plugin->mHnd, PluginEntryName));
30#endif
31 if (dllEntryPoint == nullptr) {
32 return nullptr;
33 }
34 // Retrieve plugin metadata from DLL entry-point function
35 plugin->mEntryPoint = dllEntryPoint();
36
37 return plugin;
38 }
39
41 {
42 mIsLoaded = std::move(rhs.mIsLoaded);
43 mHnd = std::move(rhs.mHnd);
44 mFile = std::move(rhs.mFile);
45 mEntryPoint = std::move(rhs.mEntryPoint);
46 }
47
49 {
50 return mEntryPoint;
51 }
52
53 bool Plugin::isLoaded() const
54 {
55 return mIsLoaded;
56 }
57
59 {
60 if (mHnd != nullptr) {
61#if !defined(_WIN32)
62 ::dlclose(mHnd);
63#else
64 ::FreeLibrary((HMODULE)mHnd);
65#endif
66 mHnd = nullptr;
67 mIsLoaded = false;
68 }
69 }
70
72 {
73 std::swap(rhs.mIsLoaded, mIsLoaded);
74 std::swap(rhs.mHnd, mHnd);
75 std::swap(rhs.mFile, mFile);
76 std::swap(rhs.mEntryPoint, mEntryPoint);
77 return *this;
78 }
79
81 {
82 this->unload();
83 }
84
85 std::atomic<PluginManager*> PluginManager::pInstance;
86 std::mutex PluginManager::mMutex;
87
89 {
90 PluginManager* ins = pInstance.load(std::memory_order_acquire);
91 if (!ins) {
92 std::lock_guard<std::mutex> tLock(mMutex);
93 ins = pInstance.load(std::memory_order_relaxed);
94 if (!ins) {
95 ins = new PluginManager();
96 pInstance.store(ins, std::memory_order_release);
97 }
98 }
99
100 return ins;
101 }
102
103 std::string PluginManager::getExtension() const
104 {
105 std::string ext;
106#if defined (_WIN32)
107 ext = ".dll"; // Windows
108#elif defined(__unix__) && !defined(__apple__)
109 ext = ".so"; // Linux, BDS, Solaris and so on.
110#elif defined(__apple__)
111 ext = ".dylib"; // MacOSX
112#else
113#error "Not implemented for this platform"
114#endif
115 return ext;
116 }
117
118 bool PluginManager::loadPlugin(const std::string& pluginName)
119 {
120 auto plugin = Plugin::load(pluginName);
121 if (plugin != nullptr)
122 {
123 std::cout << "\033[32m\033[1m" << "[Plugin]: loading " << pluginName << " in success " << "\033[0m" << std::endl;
124 mPlugins[pluginName] = plugin;
125
126 return true;
127 }
128 else
129 {
130 std::cout << "\033[31m\033[1m" << "[Plugin]: loading " << pluginName << " in failure " << "\033[0m" << std::endl;
131
132 return false;
133 }
134 }
135
136 void PluginManager::loadPluginByPath(const std::string& pathName)
137 {
138 fs::path file_path(pathName);
139
140 std::error_code error;
141 auto file_status = fs::status(file_path, error);
142 if (!fs::exists(file_status)) {
143 std::cout << "Plugin path do not exist !" << std::endl;
144 return;
145 }
146
147 for (const auto& entry : fs::directory_iterator(pathName))
148 {
149 std::string name = entry.path().filename().string();
150 if (entry.path().extension() == getExtension() && name.find("plugin-") != std::string::npos)
151 {
152 loadPlugin(entry.path().string());
153 }
154 }
155 }
156
157 std::shared_ptr<Plugin> PluginManager::getPlugin(const char* pluginName)
158 {
159 auto it = mPlugins.find(pluginName);
160 if (it == mPlugins.end())
161 return nullptr;
162
163 return it->second;
164 }
165}
static std::shared_ptr< Plugin > load(std::string file)
bool isLoaded() const
std::string mFile
Shared library file name.
bool mIsLoaded
Flag to indicate whether plugin (shared library) is loaded into current process.
PluginEntry * mEntryPoint
Pointer to shared library factory class returned by the DLL entry-point function.
PluginEntry * getInfo() const
Plugin & operator=(const Plugin &)=delete
PluginEntry *(*)() PluginEntryFunc
Function pointer to DLL entry-point.
static constexpr const char * PluginEntryName
Name of DLL entry point that a Plugin should export.
void * mHnd
Shared library handle.
static PluginManager * instance()
bool loadPlugin(const std::string &pluginName)
void loadPluginByPath(const std::string &pathName)
std::shared_ptr< Plugin > getPlugin(const char *pluginName)
static std::atomic< PluginManager * > pInstance
static std::mutex mMutex
std::string getExtension() const
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
Definition PluginEntry.h:14