Files
EVEngine/src/modules/plugins/Plugins.cpp
T
sunxfancyandCursor 8e0221c552 feat: enhance build system and documentation for SDK installation and shader support
- Updated .gitignore to include new build and output directories for SDK packaging.
- Modified CMakeLists.txt to include installation script for SDK.
- Enhanced Makefile to support new SDK targets for various platforms.
- Improved documentation to reflect new shader capabilities and 3D model support.
- Added new shader functions and updated rendering systems to utilize custom shaders.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-06 21:08:47 +08:00

112 lines
3.0 KiB
C++

#include "plugins/Plugins.h"
#include "common/Exception.h"
#include <simplesquirrel/simplesquirrel.hpp>
#if defined(_WIN32)
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#else
# include <dlfcn.h>
#endif
namespace eve::plugins {
using PluginInitFn = int (*)();
Module_IMPL(Plugins, new Plugins());
Plugins::Plugins() = default;
Plugins::~Plugins() {
for (auto& kv : loaded_) {
#if defined(_WIN32)
if (kv.second.native)
FreeLibrary(static_cast<HMODULE>(kv.second.native));
#else
if (kv.second.native)
dlclose(kv.second.native);
#endif
}
loaded_.clear();
}
bool Plugins::load(const std::string& path) {
if (path.empty())
throw Exception("plugins.load: empty path");
if (loaded_.count(path))
return true;
#if defined(_WIN32)
HMODULE mod = LoadLibraryA(path.c_str());
if (!mod)
throw Exception("plugins.load: LoadLibrary failed for '%s' (err=%lu)", path.c_str(),
GetLastError());
auto init = reinterpret_cast<PluginInitFn>(GetProcAddress(mod, "eve_plugin_init"));
if (!init) {
FreeLibrary(mod);
throw Exception("plugins.load: missing eve_plugin_init in '%s'", path.c_str());
}
int rc = init();
if (rc != 0) {
FreeLibrary(mod);
throw Exception("plugins.load: eve_plugin_init returned %d for '%s'", rc, path.c_str());
}
loaded_[path] = Handle{mod, path};
#else
void* mod = dlopen(path.c_str(), RTLD_NOW | RTLD_GLOBAL);
if (!mod)
throw Exception("plugins.load: dlopen failed for '%s': %s", path.c_str(), dlerror());
dlerror();
auto init = reinterpret_cast<PluginInitFn>(dlsym(mod, "eve_plugin_init"));
const char* err = dlerror();
if (err != nullptr || !init) {
dlclose(mod);
throw Exception("plugins.load: missing eve_plugin_init in '%s'%s%s", path.c_str(),
err ? ": " : "", err ? err : "");
}
int rc = init();
if (rc != 0) {
dlclose(mod);
throw Exception("plugins.load: eve_plugin_init returned %d for '%s'", rc, path.c_str());
}
loaded_[path] = Handle{mod, path};
#endif
if (ModuleManager::expose_pending() < 0)
throw Exception("plugins.load: expose_pending failed after loading '%s'", path.c_str());
return true;
}
bool Plugins::unload(const std::string& path) {
auto it = loaded_.find(path);
if (it == loaded_.end())
return false;
#if defined(_WIN32)
FreeLibrary(static_cast<HMODULE>(it->second.native));
#else
dlclose(it->second.native);
#endif
loaded_.erase(it);
return true;
}
bool Plugins::isLoaded(const std::string& path) const {
return loaded_.count(path) > 0;
}
void Plugins::expose(ssq::Table& table) {
auto cls = table.addClass(name, Plugins::create, false);
expose(cls);
}
void Plugins::expose(ssq::Class& cls) {
cls.addFunc("getName", &Plugins::getName);
cls.addFunc("load", &Plugins::load);
cls.addFunc("unload", &Plugins::unload);
cls.addFunc("isLoaded", &Plugins::isLoaded);
}
} // namespace eve::plugins