diff options
-rw-r--r-- | src/plugins/plugininterface.h | 34 | ||||
-rw-r--r-- | src/plugins/pluginloader.cpp | 17 | ||||
-rw-r--r-- | src/plugins/pluginloader.h | 42 | ||||
-rw-r--r-- | src/plugins/pluginmanager.cpp | 22 | ||||
-rw-r--r-- | src/plugins/pluginmanager.h | 33 | ||||
-rw-r--r-- | src/plugins/test/manager_test.cpp | 7 | ||||
-rw-r--r-- | src/sound/plugins/oalsound/alsound.cpp | 9 | ||||
-rw-r--r-- | src/sound/plugins/oalsound/alsound.h | 4 | ||||
-rw-r--r-- | src/sound/sound.h | 8 |
9 files changed, 153 insertions, 23 deletions
diff --git a/src/plugins/plugininterface.h b/src/plugins/plugininterface.h index bf4e040..b8adddc 100644 --- a/src/plugins/plugininterface.h +++ b/src/plugins/plugininterface.h @@ -16,22 +16,50 @@ // plugininterface.h +/** + * @file plugin/plugininterface.h + * @brief Generic plugin interface + */ #pragma once +#include <string> #define PLUGIN_INTERFACE(class_type) \ static class_type* Plugin##class_type; \ extern "C" void InstallPluginEntry() { Plugin##class_type = new class_type(); Plugin##class_type->InstallPlugin(); } \ - extern "C" void UninstallPluginEntry() { Plugin##class_type->UninstallPlugin(); delete Plugin##class_type; } \ + extern "C" bool UninstallPluginEntry(std::string &reason) { bool result = Plugin##class_type->UninstallPlugin(reason); \ + if (!result) \ + return false; \ + delete Plugin##class_type; \ + return true; } \ extern "C" CPluginInterface* GetPluginInterfaceEntry() { return static_cast<CPluginInterface*>(Plugin##class_type); } +/** +* @class CPluginInterface +* +* @brief Generic plugin interface. All plugins that will be managed by plugin manager have to derive from this class. +* +*/ class CPluginInterface { public: - virtual char* PluginName() = 0; + /** Function to get plugin name or description + * @return returns plugin name + */ + virtual std::string PluginName() = 0; + + /** Function to get plugin version. 1 means version 0.01, 2 means 0.02 etc. + * @return number indicating plugin version + */ virtual int PluginVersion() = 0; + + /** Function to initialize plugin + */ virtual void InstallPlugin() = 0; - virtual void UninstallPlugin() = 0; + + /** Function called before removing plugin + */ + virtual bool UninstallPlugin(std::string &) = 0; }; diff --git a/src/plugins/pluginloader.cpp b/src/plugins/pluginloader.cpp index 8893b56..fd8ce74 100644 --- a/src/plugins/pluginloader.cpp +++ b/src/plugins/pluginloader.cpp @@ -28,11 +28,11 @@ CPluginLoader::CPluginLoader(std::string filename) } -char* CPluginLoader::GetName() +std::string CPluginLoader::GetName() { if (mLoaded) return mInterface->PluginName(); - return nullptr; + return "(not loaded)"; } @@ -57,12 +57,18 @@ bool CPluginLoader::UnloadPlugin() return true; } - void (*uninstall)() = (void (*)()) lt_dlsym(mHandle, "UninstallPluginEntry"); + bool (*uninstall)(std::string &) = (bool (*)(std::string &)) lt_dlsym(mHandle, "UninstallPluginEntry"); if (!uninstall) { GetLogger()->Error("Error getting UninstallPluginEntry for plugin %s: %s\n", mFilename.c_str(), lt_dlerror()); return false; } + std::string reason; + if (!uninstall(reason)) { + GetLogger()->Error("Could not unload plugin %s: %s\n", mFilename.c_str(), reason.c_str()); + return false; + } + lt_dlclose(mHandle); mLoaded = false; return true; @@ -71,6 +77,11 @@ bool CPluginLoader::UnloadPlugin() bool CPluginLoader::LoadPlugin() { + if (mFilename.length() == 0) { + GetLogger()->Warn("No plugin filename specified.\n"); + return false; + } + mHandle = lt_dlopenext(mFilename.c_str()); if (!mHandle) { GetLogger()->Error("Error loading plugin %s: %s\n", mFilename.c_str(), lt_dlerror()); diff --git a/src/plugins/pluginloader.h b/src/plugins/pluginloader.h index 873d30a..40b19da 100644 --- a/src/plugins/pluginloader.h +++ b/src/plugins/pluginloader.h @@ -16,6 +16,10 @@ // pluginloader.h +/** + * @file plugin/pluginloader.h + * @brief Plugin loader interface + */ #pragma once @@ -27,16 +31,52 @@ #include "plugininterface.h" +/** +* @class CPluginLoader +* +* @brief Plugin loader interface. Plugin manager uses this class to load plugins. +* +*/ class CPluginLoader { public: + /** Class contructor + * @param std::string plugin filename + */ CPluginLoader(std::string); - char* GetName(); + /** Function to get plugin name or description + * @return returns plugin name + */ + std::string GetName(); + + /** Function to get plugin version + * @return returns plugin version + */ int GetVersion(); + + /** Function to unload plugin + * @return returns true on success + */ bool UnloadPlugin(); + + /** Function to load plugin + * @return returns true on success + */ bool LoadPlugin(); + + /** Function to check if plugin is loaded + * @return returns true if plugin is loaded + */ bool IsLoaded(); + + /** Function to set plugin filename + * @return returns true on success. Action can fail if plugin was loaded and cannot be unloaded + */ bool SetFilename(std::string); + + /** Function to get plugin filename + * @return returns plugin filename + */ std::string GetFilename(); diff --git a/src/plugins/pluginmanager.cpp b/src/plugins/pluginmanager.cpp index ab9d8ad..470ac2f 100644 --- a/src/plugins/pluginmanager.cpp +++ b/src/plugins/pluginmanager.cpp @@ -60,7 +60,7 @@ bool CPluginManager::LoadPlugin(std::string filename) loader->SetFilename(dir + "/" + filename); result = loader->LoadPlugin(); if (result) { - GetLogger()->Info("Plugin %s (%s) version %0.2f loaded!\n", filename.c_str(), loader->GetName(), loader->GetVersion() / 100.0f); + GetLogger()->Info("Plugin %s (%s) version %0.2f loaded!\n", filename.c_str(), loader->GetName().c_str(), loader->GetVersion() / 100.0f); m_plugins.push_back(loader); break; } @@ -102,13 +102,23 @@ bool CPluginManager::RemoveSearchDirectory(std::string dir) bool CPluginManager::UnloadAllPlugins() { - for (CPluginLoader *plugin : m_plugins) { - GetLogger()->Info("Trying to unload plugin %s (%s)...\n", plugin->GetFilename().c_str(), plugin->GetName()); - plugin->UnloadPlugin(); + bool allOk = true; + std::vector<CPluginLoader *>::iterator it; + for (it = m_plugins.begin(); it != m_plugins.end(); it++) { + CPluginLoader *plugin = *it; + bool result; + + GetLogger()->Info("Trying to unload plugin %s (%s)...\n", plugin->GetFilename().c_str(), plugin->GetName().c_str()); + result = plugin->UnloadPlugin(); + if (!result) { + allOk = false; + continue; + } delete plugin; + m_plugins.erase(it); } - m_plugins.clear(); - return true; + + return allOk; } diff --git a/src/plugins/pluginmanager.h b/src/plugins/pluginmanager.h index d267238..e425c62 100644 --- a/src/plugins/pluginmanager.h +++ b/src/plugins/pluginmanager.h @@ -16,6 +16,10 @@ // pluginmanager.h +/** + * @file plugin/pluginmanager.h + * @brief Plugin manager class. + */ #pragma once @@ -31,19 +35,48 @@ #include "pluginloader.h" +/** +* @class CPluginManager +* +* @brief Plugin manager class. Plugin manager can load plugins from colobot.ini or manually specified files. +* +*/ class CPluginManager : public CSingleton<CPluginManager> { public: CPluginManager(); ~CPluginManager(); + /** Function loads plugin list and path list from profile file + */ void LoadFromProfile(); + /** Function loads specified plugin + * @param std::string plugin filename + * @return returns true on success + */ bool LoadPlugin(std::string); + + /** Function unloads specified plugin + * @param std::string plugin filename + * @return returns true on success + */ bool UnloadPlugin(std::string); + /** Function adds path to be checked when searching for plugin file. If path was already added it will be ignored + * @param std::string plugin search path + * @return returns true on success + */ bool AddSearchDirectory(std::string); + + /** Function removes path from list + * @param std::string plugin search path + * @return returns true on success + */ bool RemoveSearchDirectory(std::string); + /** Function tries to unload all plugins + * @return returns true on success + */ bool UnloadAllPlugins(); private: diff --git a/src/plugins/test/manager_test.cpp b/src/plugins/test/manager_test.cpp index 9b3f472..d921c1d 100644 --- a/src/plugins/test/manager_test.cpp +++ b/src/plugins/test/manager_test.cpp @@ -15,8 +15,15 @@ int main() { GetLogger()->Error("Config not found!\n"); return 1; } + mgr->LoadFromProfile(); CSoundInterface *sound = static_cast<CSoundInterface*>(CInstanceManager::GetInstancePointer()->SearchInstance(CLASS_SOUND)); + + if (!sound) { + GetLogger()->Error("Sound not loaded!\n"); + return 2; + } + sound->Create(true); mgr->UnloadAllPlugins(); diff --git a/src/sound/plugins/oalsound/alsound.cpp b/src/sound/plugins/oalsound/alsound.cpp index a1d4801..8cd8221 100644 --- a/src/sound/plugins/oalsound/alsound.cpp +++ b/src/sound/plugins/oalsound/alsound.cpp @@ -27,15 +27,15 @@ PLUGIN_INTERFACE(ALSound)
-char* ALSound::PluginName()
+std::string ALSound::PluginName()
{
- return const_cast<char *>("Sound plugin using OpenAL library to play sounds.");
+ return "Sound plugin using OpenAL library to play sounds.";
}
int ALSound::PluginVersion()
{
- return 1;
+ return 2;
}
@@ -47,12 +47,13 @@ void ALSound::InstallPlugin() }
-void ALSound::UninstallPlugin()
+bool ALSound::UninstallPlugin(std::string &reason)
{
auto pointer = CInstanceManager::GetInstancePointer();
if (pointer != nullptr)
CInstanceManager::GetInstancePointer()->DeleteInstance(CLASS_SOUND, this);
CleanUp();
+ return true;
}
diff --git a/src/sound/plugins/oalsound/alsound.h b/src/sound/plugins/oalsound/alsound.h index 9265e2c..c1cdb81 100644 --- a/src/sound/plugins/oalsound/alsound.h +++ b/src/sound/plugins/oalsound/alsound.h @@ -74,10 +74,10 @@ class ALSound : public CSoundInterface bool IsPlayingMusic();
// plugin interface
- char* PluginName();
+ std::string PluginName();
int PluginVersion();
void InstallPlugin();
- void UninstallPlugin();
+ bool UninstallPlugin(std::string &);
private:
void CleanUp();
diff --git a/src/sound/sound.h b/src/sound/sound.h index f18a76a..45ec7e1 100644 --- a/src/sound/sound.h +++ b/src/sound/sound.h @@ -15,10 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// soundinterface.h +// sound.h /** - * @file sound/soundinterface.h + * @file sound/sound.h * @brief Sound plugin interface */ @@ -39,7 +39,7 @@ /** * \public - * \enum Sound sound/soundinterface.h + * \enum Sound sound/sound.h * \brief Sound enum representing sound file **/ enum Sound @@ -131,7 +131,7 @@ enum Sound /** * \public - * \enum SoundNext sound/soundinterface.h + * \enum SoundNext sound/sound.h * \brief Enum representing operation that will be performend on a sound at given time **/ enum SoundNext |