I am working on a plugin platform using dynamically loaded shared libraries, which is based on the Eclipse (and probally other) extension model. All plugins have similar properties (name, identifier, version, etc.), and each plugin can theoretically satisfy any extension point. The actual processing of the plugin (i.e. Dll) is controlled by another library, and all I do is manage the collection of interfaces for the application.
I started by using enum PluginTypeto distinguish between different interfaces, but I quickly realized that using template functions made the code much cleaner and left grunt working up to the compiler, instead of forcing me to use a lot switch {...}.
The only problem is where I need to specify as functionality for class members. The most obvious example is the default plugin, which provides a specific interface. The class Settingshandles all settings, including the default plugin for the interface.
ie Skin newSkin = settings.GetDefault<ISkin>();
How to save the default ISkinin the container without resorting to any other means of identifying the interface?
As I mentioned above, I am currently using a member std::map<PluginType, IPlugin> Settings::defaultsto achieve this goal (where IPluginis the abstract base class from which all plugins are derived. Then I can dynamic_caston the desired interface, but it really smells like a bad design for me and does more harm. than i think.
will welcome any advice
edit:
typedef boost::shared_ptr<ISkin> Skin;
typedef boost::shared_ptr<IPlugin> Plugin;
enum PluginType
{
skin,
...,
...
}
class Settings
{
public:
void SetDefault(const PluginType type, boost::shared_ptr<IPlugin> plugin) {
m_default[type] = plugin;
}
boost::shared_ptr<IPlugin> GetDefault(const PluginType type) {
return m_default[type];
}
private:
std::map<PluginType, boost::shared_ptr<IPlugin> m_default;
};
SkinManager::Initialize()
{
Plugin thedefault = g_settings.GetDefault(skinplugin);
Skin defaultskin = boost::dynamic_pointer_cast<ISkin>(theskin);
defaultskin->Initialize();
}
getdefault : . .
template<>
Skin Settings::GetDefault<ISkin>()
{
return boost::dynamic_pointer_cast<ISkin>(m_default(skin));
}