initial commit
This commit is contained in:
commit
9d20827c46
2469 changed files with 470994 additions and 0 deletions
286
iris-legacy/iris/irisnet/irisnetglobal.cpp
Normal file
286
iris-legacy/iris/irisnet/irisnetglobal.cpp
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "irisnetglobal_p.h"
|
||||
|
||||
#include "irisnetplugin.h"
|
||||
|
||||
namespace XMPP {
|
||||
|
||||
// built-in providers
|
||||
extern IrisNetProvider *irisnet_createUnixNetProvider();
|
||||
extern IrisNetProvider *irisnet_createJDnsProvider();
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// internal
|
||||
//----------------------------------------------------------------------------
|
||||
class PluginInstance
|
||||
{
|
||||
private:
|
||||
QPluginLoader *_loader;
|
||||
QObject *_instance;
|
||||
bool _ownInstance;
|
||||
|
||||
PluginInstance()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
static PluginInstance *fromFile(const QString &fname)
|
||||
{
|
||||
QPluginLoader *loader = new QPluginLoader(fname);
|
||||
if(!loader->load())
|
||||
{
|
||||
delete loader;
|
||||
return 0;
|
||||
}
|
||||
QObject *obj = loader->instance();
|
||||
if(!obj)
|
||||
{
|
||||
loader->unload();
|
||||
delete loader;
|
||||
return 0;
|
||||
}
|
||||
PluginInstance *i = new PluginInstance;
|
||||
i->_loader = loader;
|
||||
i->_instance = obj;
|
||||
i->_ownInstance = true;
|
||||
return i;
|
||||
}
|
||||
|
||||
static PluginInstance *fromStatic(QObject *obj)
|
||||
{
|
||||
PluginInstance *i = new PluginInstance;
|
||||
i->_loader = 0;
|
||||
i->_instance = obj;
|
||||
i->_ownInstance = false;
|
||||
return i;
|
||||
}
|
||||
|
||||
static PluginInstance *fromInstance(QObject *obj)
|
||||
{
|
||||
PluginInstance *i = new PluginInstance;
|
||||
i->_loader = 0;
|
||||
i->_instance = obj;
|
||||
i->_ownInstance = true;
|
||||
return i;
|
||||
}
|
||||
|
||||
~PluginInstance()
|
||||
{
|
||||
if(_ownInstance)
|
||||
delete _instance;
|
||||
|
||||
if(_loader)
|
||||
{
|
||||
_loader->unload();
|
||||
delete _loader;
|
||||
}
|
||||
}
|
||||
|
||||
void claim()
|
||||
{
|
||||
if(_loader)
|
||||
_loader->moveToThread(0);
|
||||
if(_ownInstance)
|
||||
_instance->moveToThread(0);
|
||||
}
|
||||
|
||||
QObject *instance()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
bool sameType(const PluginInstance *other)
|
||||
{
|
||||
if(!_instance || !other->_instance)
|
||||
return false;
|
||||
|
||||
if(qstrcmp(_instance->metaObject()->className(), other->_instance->metaObject()->className()) != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class PluginManager
|
||||
{
|
||||
public:
|
||||
bool builtin_done;
|
||||
QStringList paths;
|
||||
QList<PluginInstance*> plugins;
|
||||
QList<IrisNetProvider*> providers;
|
||||
|
||||
PluginManager()
|
||||
{
|
||||
builtin_done = false;
|
||||
}
|
||||
|
||||
~PluginManager()
|
||||
{
|
||||
unload();
|
||||
}
|
||||
|
||||
bool tryAdd(PluginInstance *i, bool lowPriority = false)
|
||||
{
|
||||
// is it the right kind of plugin?
|
||||
IrisNetProvider *p = qobject_cast<IrisNetProvider*>(i->instance());
|
||||
if(!p)
|
||||
return false;
|
||||
|
||||
// make sure we don't have it already
|
||||
for(int n = 0; n < plugins.count(); ++n)
|
||||
{
|
||||
if(i->sameType(plugins[n]))
|
||||
return false;
|
||||
}
|
||||
|
||||
i->claim();
|
||||
plugins += i;
|
||||
if(lowPriority)
|
||||
providers.append(p);
|
||||
else
|
||||
providers.prepend(p);
|
||||
return true;
|
||||
}
|
||||
|
||||
void addBuiltIn(IrisNetProvider *p)
|
||||
{
|
||||
PluginInstance *i = PluginInstance::fromInstance(p);
|
||||
if(!tryAdd(i, true))
|
||||
delete i;
|
||||
}
|
||||
|
||||
void scan()
|
||||
{
|
||||
if(!builtin_done)
|
||||
{
|
||||
addBuiltIn(irisnet_createUnixNetProvider());
|
||||
addBuiltIn(irisnet_createJDnsProvider());
|
||||
builtin_done = true;
|
||||
}
|
||||
|
||||
QObjectList list = QPluginLoader::staticInstances();
|
||||
for(int n = 0; n < list.count(); ++n)
|
||||
{
|
||||
PluginInstance *i = PluginInstance::fromStatic(list[n]);
|
||||
if(!tryAdd(i))
|
||||
delete i;
|
||||
}
|
||||
for(int n = 0; n < paths.count(); ++n)
|
||||
{
|
||||
QDir dir(paths[n]);
|
||||
if(!dir.exists())
|
||||
continue;
|
||||
|
||||
QStringList entries = dir.entryList();
|
||||
for(int k = 0; k < entries.count(); ++k)
|
||||
{
|
||||
QFileInfo fi(dir.filePath(entries[k]));
|
||||
if(!fi.exists())
|
||||
continue;
|
||||
QString fname = fi.filePath();
|
||||
PluginInstance *i = PluginInstance::fromFile(fname);
|
||||
if(!i)
|
||||
continue;
|
||||
|
||||
if(!tryAdd(i))
|
||||
delete i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void unload()
|
||||
{
|
||||
qDeleteAll(plugins);
|
||||
plugins.clear();
|
||||
providers.clear();
|
||||
}
|
||||
};
|
||||
|
||||
class IrisNetGlobal
|
||||
{
|
||||
public:
|
||||
QMutex m;
|
||||
PluginManager pluginManager;
|
||||
QList<IrisNetCleanUpFunction> cleanupList;
|
||||
};
|
||||
|
||||
Q_GLOBAL_STATIC(QMutex, global_mutex)
|
||||
static IrisNetGlobal *global = 0;
|
||||
|
||||
static void deinit();
|
||||
|
||||
static void init()
|
||||
{
|
||||
QMutexLocker locker(global_mutex());
|
||||
if(global)
|
||||
return;
|
||||
|
||||
global = new IrisNetGlobal;
|
||||
qAddPostRoutine(deinit);
|
||||
}
|
||||
|
||||
void deinit()
|
||||
{
|
||||
if(!global)
|
||||
return;
|
||||
|
||||
while(!global->cleanupList.isEmpty())
|
||||
(global->cleanupList.takeFirst())();
|
||||
|
||||
delete global;
|
||||
global = 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Global
|
||||
//----------------------------------------------------------------------------
|
||||
void irisNetSetPluginPaths(const QStringList &paths)
|
||||
{
|
||||
init();
|
||||
|
||||
QMutexLocker locker(&global->m);
|
||||
global->pluginManager.paths = paths;
|
||||
}
|
||||
|
||||
void irisNetCleanup()
|
||||
{
|
||||
deinit();
|
||||
}
|
||||
|
||||
void irisNetAddPostRoutine(IrisNetCleanUpFunction func)
|
||||
{
|
||||
init();
|
||||
|
||||
QMutexLocker locker(&global->m);
|
||||
global->cleanupList.prepend(func);
|
||||
}
|
||||
|
||||
QList<IrisNetProvider*> irisNetProviders()
|
||||
{
|
||||
init();
|
||||
|
||||
QMutexLocker locker(&global->m);
|
||||
global->pluginManager.scan();
|
||||
return global->pluginManager.providers;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in a new issue