TerraForge3D  2.3.1
3D Terrain And Landscape Generator
ModuleManager.cpp
1#include "Modules/ModuleManager.h"
2#include "Utils/Utils.h"
3#include "Data/ApplicationState.h"
4#include "Platform.h"
5
6#include "zip.h"
7#include "imgui.h"
8#include "json.hpp"
9
10#include <filesystem>
11
12#ifdef TERR3D_WIN32
13#define MODULE_EXT ".dll"
14#include "windows.h"
15typedef Module* (__stdcall *GetModuleFunc)(char*, ApplicationState*);
16#else
17#define MODULE_EXT ".so"
18#include <dlfcn.h>
19typedef Module* (*GetModuleFunc)(char*, ApplicationState*);
20#endif
21
22ModuleManager::ModuleManager(ApplicationState *appState)
23{
24 this->appState = appState;
25 LoadModules();
26}
27
28void ModuleManager::UnloadModules()
29{
30 for(Module *module : loadedModules)
31 {
32 module->OnUnload();
33 #ifdef TERR3D_WIN32
34 FreeLibrary((HMODULE)module->nativeHandle);
35 #else
36 dlclose(module->nativeHandle);
37 #endif
38 delete module;
39 }
40 loadedModules.clear();
41}
42
43void ModuleManager::LoadModules()
44{
45 UnloadModules();
46 // iterate through all directories in the modules folder
47 std::string modulesFolder = appState->constants.modulesDir + PATH_SEPARATOR;
48 for (auto &p : std::filesystem::directory_iterator(modulesFolder))
49 {
50 std::string path = p.path().string();
51 if (p.is_directory() && FileExists(path + PATH_SEPARATOR "module" MODULE_EXT ))
52 {
53 LoadModule(path + PATH_SEPARATOR "module" MODULE_EXT);
54 }
55 }
56}
57
58void ModuleManager::LoadModule(std::string path)
59{
60#ifdef TERR3D_WIN32
61 HINSTANCE dll = LoadLibrary(s2ws(path).c_str());
62
63 if(!dll)
64 {
65 std::cout << "Failed to load module: " << path << std::endl;
66 return;
67 }
68
69 GetModuleFunc getModule = (GetModuleFunc)GetProcAddress(dll, "GetModule");
70
71 if(!getModule)
72 {
73 std::cout << "Failed to get module function: " << path << std::endl;
74 FreeLibrary(dll);
75 return;
76 }
77
78 std::string uid = GenerateId(32);
79 Module *module = getModule(uid.data(), appState);
80
81 module->nativeHandle = dll;
82
83#else
84 void *handle;
85 handle = dlopen(path.data(), RTLD_LAZY);
86 if (!handle)
87 {
88 std::cout << "Failed to load module: " << path << std::endl;
89 return;
90 }
91 dlerror();
92 GetModuleFunc getModule = (GetModuleFunc)dlsym(handle, "GetModule");
93 if (!getModule)
94 {
95 std::cout << "Failed to get module function: " << path << std::endl;
96 dlclose(handle);
97 return;
98 }
99
100 std::string uid = GenerateId(32);
101 Module *module = getModule(uid.data(), appState);
102 module->nativeHandle = handle;
103
104#endif
105}
106
107
108ModuleManager::~ModuleManager()
109{
110 UnloadModules();
111}
112
113void ModuleManager::InstallModule(std::string path)
114{
115 // extract zip file to modules folder
116 zip_extract(path.data(), (appState->constants.modulesDir + PATH_SEPARATOR + GenerateId(32)).data(), [](const char* f, void* arg){return 1;}, 0);
117 // load module
118 LoadModule(appState->constants.modulesDir + PATH_SEPARATOR + GenerateId(32) + PATH_SEPARATOR "module" MODULE_EXT);
119}
120
121void ModuleManager::UninstallModule(std::string uid)
122{
123 if(modules.find(uid) == modules.end())
124 {
125 return;
126 }
127
128 Module *module = modules[uid];
129 modules.erase(modules.find(uid));
130 loadedModules.erase(std::find(loadedModules.begin(), loadedModules.end(), module));
131
132 if(!module)
133 {
134 return;
135 }
136
137 module->OnUninstall();
138}
139
140void ModuleManager::ShowSettings(bool *pOpen)
141{
142 ImGui::Begin("Module Manager##TerraForge3DModuleManager", pOpen);
143 ImGui::Text("Currently Installed Modules : %d", loadedModules.size());
144
145 for(Module *module : loadedModules)
146 {
147 ImGui::PushID(module->uid.data());
148
149 if(ImGui::CollapsingHeader(module->info.name.data()))
150 {
151 ImGui::Text("Name : %s", module->info.name.data());
152 ImGui::Text("Author : %s", module->info.authorName.data());
153 ImGui::Text("Version : %s", module->info.versionString.data());
154 ImGui::Text("Website : %s", module->info.website.data());
155 ImGui::Text("Contact : %s", module->info.contact.data());
156 ImGui::Checkbox("Enabled", &module->isEnabled);
157 ImGui::Text(module->info.description.data());
158 }
159
160 ImGui::PopID();
161 ImGui::Separator();
162 }
163
164 ImGui::End();
165 void *imguiContext = static_cast<void *>(ImGui::GetCurrentContext());
166
167 for(Module *module : loadedModules)
168 {
169 module->RenderImGui(imguiContext);
170 }
171}
172
173void ModuleManager::UpdateModules()
174{
175 for(Module *module : loadedModules)
176 {
177 module->Update();
178 }
179}
void Update()
Module Update Function.
Definition: Module.cpp:18
void RenderImGui(void *imguiContext)
Module ImGui Render Function.
Definition: Module.cpp:23
void * nativeHandle
Definition: Module.h:109
bool isEnabled
Definition: Module.h:110
virtual void OnUninstall()
OnUninstall.
Definition: Module.cpp:33
std::string uid
Definition: Module.h:106
ModuleInfo info
Definition: Module.h:107
Module Info.
Definition: Module.h:40
std::string contact
Definition: Module.h:21
std::string versionString
Definition: Module.h:18
std::string website
Definition: Module.h:20
std::string description
Definition: Module.h:22
std::string name
Definition: Module.h:16
std::string authorName
Definition: Module.h:17