* Final changes to plugin interface

* Added doxygen comments to plugin manager and plugin loader
dev-ui
erihel 2012-08-12 18:37:11 +02:00
parent f01296690e
commit 62b545128f
9 changed files with 153 additions and 23 deletions

View File

@ -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;
};

View File

@ -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());

View File

@ -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();

View File

@ -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;
}

View File

@ -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:

View File

@ -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();

View File

@ -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;
}

View File

@ -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();

View File

@ -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