plugins: refactor class member vars (#10257)

This commit is contained in:
davc0n 2025-05-03 16:06:24 +02:00 committed by GitHub
parent d9cad5e1b6
commit 2d6ca96e07
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 128 additions and 129 deletions

View file

@ -74,20 +74,20 @@ std::expected<CPlugin*, std::string> CPluginSystem::loadPluginInternal(const std
return std::unexpected("Cannot load a plugin twice!");
}
auto* const PLUGIN = m_vLoadedPlugins.emplace_back(makeUnique<CPlugin>()).get();
auto* const PLUGIN = m_loadedPlugins.emplace_back(makeUnique<CPlugin>()).get();
PLUGIN->path = path;
PLUGIN->m_path = path;
HANDLE MODULE = dlopen(path.c_str(), RTLD_LAZY);
if (!MODULE) {
std::string strerr = dlerror();
Debug::log(ERR, " [PluginSystem] Plugin {} could not be loaded: {}", path, strerr);
m_vLoadedPlugins.pop_back();
m_loadedPlugins.pop_back();
return std::unexpected(std::format("Plugin {} could not be loaded: {}", path, strerr));
}
PLUGIN->m_pHandle = MODULE;
PLUGIN->m_handle = MODULE;
PPLUGIN_API_VERSION_FUNC apiVerFunc = (PPLUGIN_API_VERSION_FUNC)dlsym(MODULE, PLUGIN_API_VERSION_FUNC_STR);
PPLUGIN_INIT_FUNC initFunc = (PPLUGIN_INIT_FUNC)dlsym(MODULE, PLUGIN_INIT_FUNC_STR);
@ -95,7 +95,7 @@ std::expected<CPlugin*, std::string> CPluginSystem::loadPluginInternal(const std
if (!apiVerFunc || !initFunc) {
Debug::log(ERR, " [PluginSystem] Plugin {} could not be loaded. (No apiver/init func)", path);
dlclose(MODULE);
m_vLoadedPlugins.pop_back();
m_loadedPlugins.pop_back();
return std::unexpected(std::format("Plugin {} could not be loaded: {}", path, "missing apiver/init func"));
}
@ -104,33 +104,33 @@ std::expected<CPlugin*, std::string> CPluginSystem::loadPluginInternal(const std
if (PLUGINAPIVER != HYPRLAND_API_VERSION) {
Debug::log(ERR, " [PluginSystem] Plugin {} could not be loaded. (API version mismatch)", path);
dlclose(MODULE);
m_vLoadedPlugins.pop_back();
m_loadedPlugins.pop_back();
return std::unexpected(std::format("Plugin {} could not be loaded: {}", path, "API version mismatch"));
}
PLUGIN_DESCRIPTION_INFO PLUGINDATA;
try {
if (!setjmp(m_jbPluginFaultJumpBuf)) {
m_bAllowConfigVars = true;
PLUGINDATA = initFunc(MODULE);
if (!setjmp(m_pluginFaultJumpBuf)) {
m_allowConfigVars = true;
PLUGINDATA = initFunc(MODULE);
} else {
// this module crashed.
throw std::runtime_error("received a fatal signal");
}
} catch (std::exception& e) {
m_bAllowConfigVars = false;
m_allowConfigVars = false;
Debug::log(ERR, " [PluginSystem] Plugin {} (Handle {:x}) crashed in init. Unloading.", path, (uintptr_t)MODULE);
unloadPlugin(PLUGIN, true); // Plugin could've already hooked/done something
return std::unexpected(std::format("Plugin {} could not be loaded: plugin crashed/threw in main: {}", path, e.what()));
}
m_bAllowConfigVars = false;
m_allowConfigVars = false;
PLUGIN->author = PLUGINDATA.author;
PLUGIN->description = PLUGINDATA.description;
PLUGIN->version = PLUGINDATA.version;
PLUGIN->name = PLUGINDATA.name;
PLUGIN->m_author = PLUGINDATA.author;
PLUGIN->m_description = PLUGINDATA.description;
PLUGIN->m_version = PLUGINDATA.version;
PLUGIN->m_name = PLUGINDATA.name;
g_pEventLoopManager->doLater([] { g_pConfigManager->reload(); });
@ -145,42 +145,42 @@ void CPluginSystem::unloadPlugin(const CPlugin* plugin, bool eject) {
return;
if (!eject) {
PPLUGIN_EXIT_FUNC exitFunc = (PPLUGIN_EXIT_FUNC)dlsym(plugin->m_pHandle, PLUGIN_EXIT_FUNC_STR);
PPLUGIN_EXIT_FUNC exitFunc = (PPLUGIN_EXIT_FUNC)dlsym(plugin->m_handle, PLUGIN_EXIT_FUNC_STR);
if (exitFunc)
exitFunc();
}
for (auto const& [k, v] : plugin->registeredCallbacks) {
for (auto const& [k, v] : plugin->m_registeredCallbacks) {
if (const auto SHP = v.lock())
g_pHookSystem->unhook(SHP);
}
const auto ls = plugin->registeredLayouts;
const auto ls = plugin->m_registeredLayouts;
for (auto const& l : ls)
g_pLayoutManager->removeLayout(l);
g_pFunctionHookSystem->removeAllHooksFrom(plugin->m_pHandle);
g_pFunctionHookSystem->removeAllHooksFrom(plugin->m_handle);
const auto rd = plugin->registeredDecorations;
const auto rd = plugin->m_registeredDecorations;
for (auto const& d : rd)
HyprlandAPI::removeWindowDecoration(plugin->m_pHandle, d);
HyprlandAPI::removeWindowDecoration(plugin->m_handle, d);
const auto rdi = plugin->registeredDispatchers;
const auto rdi = plugin->m_registeredDispatchers;
for (auto const& d : rdi)
HyprlandAPI::removeDispatcher(plugin->m_pHandle, d);
HyprlandAPI::removeDispatcher(plugin->m_handle, d);
const auto rhc = plugin->registeredHyprctlCommands;
const auto rhc = plugin->m_registeredHyprctlCommands;
for (auto const& c : rhc)
HyprlandAPI::unregisterHyprCtlCommand(plugin->m_pHandle, c);
HyprlandAPI::unregisterHyprCtlCommand(plugin->m_handle, c);
g_pConfigManager->removePluginConfig(plugin->m_pHandle);
g_pConfigManager->removePluginConfig(plugin->m_handle);
// save these two for dlclose and a log,
// as erase_if will kill the pointer
const auto PLNAME = plugin->name;
const auto PLHANDLE = plugin->m_pHandle;
const auto PLNAME = plugin->m_name;
const auto PLHANDLE = plugin->m_handle;
std::erase_if(m_vLoadedPlugins, [&](const auto& other) { return other->m_pHandle == PLHANDLE; });
std::erase_if(m_loadedPlugins, [&](const auto& other) { return other->m_handle == PLHANDLE; });
dlclose(PLHANDLE);
@ -191,24 +191,24 @@ void CPluginSystem::unloadPlugin(const CPlugin* plugin, bool eject) {
}
void CPluginSystem::unloadAllPlugins() {
for (auto const& p : m_vLoadedPlugins | std::views::reverse)
for (auto const& p : m_loadedPlugins | std::views::reverse)
unloadPlugin(p.get(), false); // Unload remaining plugins gracefully
}
void CPluginSystem::updateConfigPlugins(const std::vector<std::string>& plugins, bool& changed) {
// unload all plugins that are no longer present
for (auto const& p : m_vLoadedPlugins | std::views::reverse) {
if (!p->m_bLoadedWithConfig || std::ranges::find(plugins, p->path) != plugins.end())
for (auto const& p : m_loadedPlugins | std::views::reverse) {
if (!p->m_loadedWithConfig || std::ranges::find(plugins, p->m_path) != plugins.end())
continue;
Debug::log(LOG, "Unloading plugin {} which is no longer present in config", p->path);
Debug::log(LOG, "Unloading plugin {} which is no longer present in config", p->m_path);
unloadPlugin(p.get(), false);
changed = true;
}
// load all new plugins
for (auto const& path : plugins) {
if (std::ranges::find_if(m_vLoadedPlugins, [&](const auto& other) { return other->path == path; }) != m_vLoadedPlugins.end())
if (std::ranges::find_if(m_loadedPlugins, [&](const auto& other) { return other->m_path == path; }) != m_loadedPlugins.end())
continue;
Debug::log(LOG, "Loading plugin {} which is now present in config", path);
@ -223,7 +223,7 @@ void CPluginSystem::updateConfigPlugins(const std::vector<std::string>& plugins,
return;
}
result->result()->m_bLoadedWithConfig = true;
result->result()->m_loadedWithConfig = true;
Debug::log(LOG, "CPluginSystem::updateConfigPlugins: loaded {}", path);
});
@ -231,8 +231,8 @@ void CPluginSystem::updateConfigPlugins(const std::vector<std::string>& plugins,
}
CPlugin* CPluginSystem::getPluginByPath(const std::string& path) {
for (auto const& p : m_vLoadedPlugins) {
if (p->path == path)
for (auto const& p : m_loadedPlugins) {
if (p->m_path == path)
return p.get();
}
@ -240,8 +240,8 @@ CPlugin* CPluginSystem::getPluginByPath(const std::string& path) {
}
CPlugin* CPluginSystem::getPluginByHandle(HANDLE handle) {
for (auto const& p : m_vLoadedPlugins) {
if (p->m_pHandle == handle)
for (auto const& p : m_loadedPlugins) {
if (p->m_handle == handle)
return p.get();
}
@ -249,18 +249,18 @@ CPlugin* CPluginSystem::getPluginByHandle(HANDLE handle) {
}
std::vector<CPlugin*> CPluginSystem::getAllPlugins() {
std::vector<CPlugin*> results(m_vLoadedPlugins.size());
for (size_t i = 0; i < m_vLoadedPlugins.size(); ++i)
results[i] = m_vLoadedPlugins[i].get();
std::vector<CPlugin*> results(m_loadedPlugins.size());
for (size_t i = 0; i < m_loadedPlugins.size(); ++i)
results[i] = m_loadedPlugins[i].get();
return results;
}
size_t CPluginSystem::pluginCount() {
return m_vLoadedPlugins.size();
return m_loadedPlugins.size();
}
void CPluginSystem::sigGetPlugins(CPlugin** data, size_t len) {
for (size_t i = 0; i < std::min(m_vLoadedPlugins.size(), len); i++) {
data[i] = m_vLoadedPlugins[i].get();
for (size_t i = 0; i < std::min(m_loadedPlugins.size(), len); i++) {
data[i] = m_loadedPlugins[i].get();
}
}