You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdesdk/umbrello/umbrello/pluginloader.cpp

178 lines
4.7 KiB

/***************************************************************************
begin : Mon Jan 13 2003
copyright : (C) 2003 by Andrew Sutton
email : ansutton@kent.edu
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
// own header
#include "pluginloader.h"
// TQt includes
#include <tqstring.h>
// KDE includes
#include <kdebug.h>
#include <klibloader.h>
// u2 includes
#include "plugin.h"
using namespace Umbrello;
// static data
PluginLoader *PluginLoader::_instance = NULL;
PluginLoader::PluginLoader() :
_plugins(),
_categories()
{
// preseed the categories
_categories["metamodel"] = PluginList();
_categories["storage"] = PluginList();
_categories["visual"] = PluginList();
}
PluginLoader::~PluginLoader()
{
}
PluginLoader *
PluginLoader::instance()
{
if(!_instance) _instance = new PluginLoader;
return _instance;
}
Plugin *
PluginLoader::loadPlugin(const TQString &name)
{
KLibrary *lib = NULL;
KLibFactory *factory = NULL;
Plugin *plugin = NULL;
PluginMap::iterator it;
bool success = true;
// if the plugin has already been loaded, increment
// its reference and return.
if((it = _plugins.find(name)) != _plugins.end()) {
plugin = it.data();
plugin->ref();
return plugin;
}
// use KLibLoader to get a reference to the library
lib = KLibLoader::self()->library(name.latin1());
if(!lib) {
kdError() << "failed loading plugin library " << name << endl;
success = false;
}
// get the factory from the library
if(success) {
factory = lib->factory();
if(!factory) {
kdError() << "failed to find factory for " << name << endl;
success = false;
}
}
// use the factory to create the plugin
if(success) {
plugin = dynamic_cast<Plugin *>(factory->create((TQObject*)0, name.latin1()));
if(!plugin) {
kdError() << "failed to create a plugin object for " << name << endl;
success = false;
}
else {
// we have to register the plugin here, otherwise, we can get
// recursive loads
_plugins[name] = plugin;
_categories[plugin->category()].append(plugin);
}
}
// initialize the plugin
if(success && plugin) {
success = plugin->init();
if(!success) {
// on failure, delete the plugin. this should cause the
// library to unload.
kdError() << "failure initializing " << name << endl;
_categories[plugin->category()].remove(plugin);
_plugins.remove(name);
delete plugin;
}
}
// finally, finally connect to the destroyed signal and keep a
// reference to it
if(success) {
plugin->ref();
connect(plugin, TQT_SIGNAL(destroyed(TQObject *)), TQT_SLOT(slotDestroyed(TQObject *)));
}
return plugin;
}
Plugin *
PluginLoader::findPlugin(const TQString &name)
{
Plugin *ret = NULL;
PluginMap::iterator it = _plugins.find(name);
if(it != _plugins.end()) {
ret = it.data();
}
return ret;
}
void
PluginLoader::unloadPlugin(const TQString &name)
{
KLibLoader::self()->unloadLibrary(name.latin1());
}
const PluginLoader::PluginMap &
PluginLoader::plugins() const
{
return _plugins;
}
const PluginLoader::CategoryMap &
PluginLoader::categories() const
{
return _categories;
}
void
PluginLoader::slotDestroyed(TQObject *obj)
{
Plugin *plugin = static_cast<Plugin *>(obj);
// we can't just use the name because its already been destroyed
// at this point. we have to iterate thru and find the reference
// by hand.
PluginMap::iterator end(_plugins.end());
for(PluginMap::iterator i = _plugins.begin(); i != end; ++i) {
Plugin *p = i.data();
if(p == plugin) {
kdDebug() << "unloading plugin " << i.key() << endl;
// remove it from the mapping
_plugins.remove(i);
break;
}
}
}
#include "pluginloader.moc"