-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathnative_library.cpp
More file actions
74 lines (66 loc) · 2 KB
/
Copy pathnative_library.cpp
File metadata and controls
74 lines (66 loc) · 2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include "framework.h"
#include "native_library.h"
#include "options_manager.h"
namespace shelllet {
typedef void (*Initialize)(v8::Isolate*, const v8::Local<v8::ObjectTemplate>&);
typedef const char* (*Name)();
}
bool shelllet::library::NativeLibrary::initialize(v8::Isolate* isolate, const v8::Local<v8::Context>& context)
{
std::filesystem::path exe = options::options_manager::get_const_instance().options.modules_path;
try
{
for (auto& p : std::filesystem::directory_iterator(exe))
{
if (!p.is_regular_file())
continue;
auto& path = p.path();
LOG_DEBUG("engine") << "# modules: " << path;
if (path.extension() != options::options_manager::get_const_instance().options.extension)
continue;
std::unique_ptr< QLibrary> lib = std::make_unique<QLibrary>(QString::fromStdString(path.string()));
v8::Local<v8::ObjectTemplate> proto = v8::ObjectTemplate::New(isolate);
if (!lib->load()) {
// qCDebug(shelllet_engine) << "# initialize " << library->fileName();
return false;
}
auto initialize = (Initialize)lib->resolve("initialize");
if (!initialize) {
return false;
}
initialize(isolate, proto);
auto instance = proto->NewInstance(context);
if (instance.IsEmpty()) {
return false;
}
auto name = (Name)lib->resolve("name");
if (auto result = context->Global()->Set(context, V8_NEW_STRING_VAR(isolate, name()), instance.ToLocalChecked()); result.IsNothing())
return false;
libraries.push_back(std::move(lib));
}
}
catch (const std::exception& err)
{
LOG_WARN("engine") << "# modules loaded: " << QString::fromLocal8Bit(err.what()).toStdString() << std::endl;
}
return true;
}
void shelllet::library::NativeLibrary::cleanup()
{
for (auto& lib : libraries)
{
typedef void (*CleanupFunction)();
CleanupFunction cleanup = nullptr;
if (lib->isLoaded()) {
auto cleanup = (CleanupFunction)lib->resolve("cleanup");
if (cleanup) {
cleanup();
}
lib->unload();
}
}
}
shelllet::library::NativeLibrary::~NativeLibrary()
{
cleanup();
}