new position independent plugin cache

This commit is contained in:
Patrick von Reth 2014-01-12 15:04:41 +01:00
parent 4375ddd81a
commit 8f9160ec44
8 changed files with 136 additions and 81 deletions

View File

@ -6,7 +6,6 @@ set ( SnoreNotify_SRCS ${SnoreNotify_SRCS}
PARENT_SCOPE)
set ( Plugins_HDR
plugincontainer.h
plugins.h
snorefrontend.h
snorebackend.h

View File

@ -17,7 +17,7 @@
along with SnoreNotify. If not, see <http://www.gnu.org/licenses/>.
*/
#include "plugincontainer.h"
#include "../snore.h"
#include "../snore_p.h"
#include "plugins.h"
@ -32,22 +32,14 @@ using namespace Snore;
QHash<QString,PluginContainer*> PluginContainer::s_pluginCache = QHash<QString,PluginContainer*>() ;
QSettings &PluginContainer::cacheFile(){
#if defined(Q_OS_LINUX) || defined(Q_OS_OSX)
static QSettings cache("TheOneRing","libsnore");
#else
static QSettings cache(SnoreCorePrivate::pluginDir().absoluteFilePath("plugin.cache"),QSettings::IniFormat);
#endif
return cache;
}
PluginContainer::PluginContainer(QString fileName, QString pluginName, PluginContainer::PluginType type):
PluginContainer::PluginContainer(QString fileName, QString pluginName, SnorePlugin::PluginType type):
m_pluginFile(fileName),
m_pluginName(pluginName),
m_pluginType(type),
m_loader(SnoreCorePrivate::pluginDir().absoluteFilePath(file()))
{
}
PluginContainer::~PluginContainer()
@ -80,25 +72,25 @@ const QString & PluginContainer::name()
return m_pluginName;
}
PluginContainer::PluginType PluginContainer::type()
SnorePlugin::PluginType PluginContainer::type()
{
return m_pluginType;
}
PluginContainer::PluginType PluginContainer::typeFromString(const QString &t)
SnorePlugin::PluginType PluginContainer::typeFromString(const QString &t)
{
PluginContainer::PluginType type = PLUGIN;
SnorePlugin::PluginType type = SnorePlugin::PLUGIN;
if(t == QLatin1String("backend"))
{
type = BACKEND;
type = SnorePlugin::BACKEND;
}
else if(t == QLatin1String("secondary_backend"))
{
type = SECONDARY_BACKEND;
type = SnorePlugin::SECONDARY_BACKEND;
}
else if(t == QLatin1String("frontend"))
{
type = FRONTEND;
type = SnorePlugin::FRONTEND;
}
return type;
}
@ -117,16 +109,16 @@ const QStringList &PluginContainer::types()
void PluginContainer::updatePluginCache(){
QSettings &cache = cacheFile();
qDebug() << "Updating plugin cache" << cache.fileName();
qDebug() << "Updating plugin cache";
s_pluginCache.clear();
cache.clear();
clear();
foreach(const QString &type,PluginContainer::types()){
QDir plPath(SnoreCorePrivate::pluginDir().absoluteFilePath(type));
qDebug() << "Searching for plugins in" << plPath.path();
foreach (QString fileName, plPath.entryList(QDir::Files)) {
foreach (QString fileName, plPath.entryList(QDir::Files))
{
QString filepath(plPath.absoluteFilePath(fileName));
qDebug() << "adding" << filepath;
QPluginLoader loader(filepath);
@ -148,42 +140,43 @@ void PluginContainer::updatePluginCache(){
}
qDebug()<<s_pluginCache.keys();
cache.setValue("version",Version::revision());
cache.setValue("buildtime",Version::buildTime());
cache.setValue("pluginPath",SnoreCorePrivate::pluginDir().path());
setValue("version",Version::revision());
setValue("buildtime",Version::buildTime());
setValue("pluginPath",SnoreCorePrivate::pluginDir().absolutePath());
QList<PluginContainer*> plugins = s_pluginCache.values();
cache.beginWriteArray("plugins");
beginWriteArray("plugins");
for(int i=0;i< plugins.size();++i) {
cache.setArrayIndex(i);
cache.setValue("fileName",plugins[i]->file());
cache.setValue("name", plugins[i]->name());
cache.setValue("type",(int)plugins[i]->type());
setArrayIndex(i);
setValue("fileName",plugins[i]->file());
setValue("name", plugins[i]->name());
setValue("type",(int)plugins[i]->type());
}
cache.endArray();
endArray();
}
QHash<QString, PluginContainer *> PluginContainer::pluginCache(){
if(!s_pluginCache.isEmpty())
return s_pluginCache;
QSettings &cache = cacheFile();
QString version = cache.value("version").toString();
QString path = cache.value("pluginPath").toString();
QString buildTime = cache.value("buildtime").toString();
int size = cache.beginReadArray("plugins");
QString version = value("version").toString();
QString buildTime = value("buildtime").toString();
int size = beginReadArray("plugins");
if(size == 0 ||
version != Version::revision() ||
buildTime != Version::buildTime() ||
path != SnoreCorePrivate::pluginDir().path()){
cache.endArray();
buildTime != Version::buildTime())
{
endArray();
updatePluginCache();
}else{
for(int i=0;i<size;++i) {
cache.setArrayIndex(i);
PluginContainer::PluginType type = (PluginContainer::PluginType)cache.value("type").toInt();
PluginContainer *info = new PluginContainer(cache.value("fileName").toString(),cache.value("name").toString(),type);
}
else
{
for(int i=0;i<size;++i)
{
setArrayIndex(i);
SnorePlugin::PluginType type = (SnorePlugin::PluginType)value("type").toInt();
PluginContainer *info = new PluginContainer(value("fileName").toString(),value("name").toString(),type);
s_pluginCache.insert(info->name(),info);
}
cache.endArray();
endArray();
}
return s_pluginCache;

View File

@ -20,11 +20,14 @@
#ifndef PLUGINCONTAINER_H
#define PLUGINCONTAINER_H
#include "../snore_exports.h"
#include "../snore_p.h"
#include <QPointer>
#include <QSettings>
#include <QFlag>
#include <QPluginLoader>
#include <QCryptographicHash>
namespace Snore{
@ -36,43 +39,90 @@ class SnoreSecondaryBackend;
class SNORE_EXPORT PluginContainer{
public:
enum PluginType{
ALL = 0x0,//for loading plugins
BACKEND = 0x1,
SECONDARY_BACKEND = 0x2,
FRONTEND = 0x4,
PLUGIN = 0x8
};
Q_DECLARE_FLAGS(PluginTypes, PluginType)
static QHash<QString,PluginContainer*> pluginCache();
PluginContainer(QString fileName,QString pluginName,PluginType type);
PluginContainer(QString fileName,QString pluginName,SnorePlugin::PluginType type);
~PluginContainer();
SnorePlugin *load();
void unload();
const QString &file();
const QString &name();
PluginContainer::PluginType type();
SnorePlugin::PluginType type();
static PluginContainer::PluginType typeFromString(const QString &t);
static SnorePlugin::PluginType typeFromString(const QString &t);
static const QStringList &types();
private:
static void updatePluginCache();
static QSettings &cacheFile();
protected:
static inline QVariant value(const QString &key, const QVariant &defaultValue = QVariant())
{
return cache().value(pluginPathHash(key), defaultValue);
}
static inline void setValue(const QString &key, const QVariant &value)
{
cache().setValue(pluginPathHash(key), value);
}
static inline void clear()
{
cache().remove(pluginPathHash());
}
static inline void setArrayIndex(int i)
{
cache().setArrayIndex(i);
}
static inline void beginWriteArray(const QString &prefix, int size = -1)
{
cache().beginWriteArray(pluginPathHash(prefix), size);
}
static inline int beginReadArray(const QString &prefix)
{
return cache().beginReadArray(pluginPathHash(prefix));
}
static inline void endArray()
{
cache().endArray();
}
private:
void static updatePluginCache();
static QHash<QString,PluginContainer*> s_pluginCache;
static inline QString pluginPathHash(const QString &key = QString())
{
static QString s;
if(s.isEmpty())
{
QCryptographicHash h(QCryptographicHash::Md5);
h.addData(SnoreCorePrivate::pluginDir().absolutePath().toLatin1());
s = h.result().toHex();
}
if(key.isEmpty())
{
return QString("%1/").arg(s);
}
else
{
return QString("%1/%2").arg(s, key);
}
}
static inline QSettings &cache()
{
static QSettings cache("SnoreNotify","libsnore");
return cache;
}
QString m_pluginFile;
QString m_pluginName;
PluginContainer::PluginType m_pluginType;
SnorePlugin::PluginType m_pluginType;
QPluginLoader m_loader;
};
}
Q_DECLARE_OPERATORS_FOR_FLAGS(Snore::PluginContainer::PluginTypes)
#endif//PLUGINCONTAINER_H

View File

@ -25,7 +25,6 @@
#include <QHash>
#include <QTimer>
#include <QtPlugin>
#include <QPluginLoader>
namespace Snore{
class Application;
@ -36,6 +35,15 @@ class SNORE_EXPORT SnorePlugin : public QObject
{
Q_OBJECT
public:
enum PluginType{
ALL = 0x0,//for loading plugins
BACKEND = 0x1,
SECONDARY_BACKEND = 0x2,
FRONTEND = 0x4,
PLUGIN = 0x8
};
Q_DECLARE_FLAGS(PluginTypes, PluginType)
SnorePlugin ( const QString &name);
virtual ~SnorePlugin();
virtual bool init( SnoreCore *snore );
@ -58,6 +66,8 @@ private:
};
Q_DECLARE_OPERATORS_FOR_FLAGS(Snore::SnorePlugin::PluginTypes)
}
Q_DECLARE_INTERFACE ( Snore::SnorePlugin,

View File

@ -51,23 +51,23 @@ SnoreCore::~SnoreCore()
d->deleteLater();
}
void SnoreCore::loadPlugins( PluginContainer::PluginTypes types )
void SnoreCore::loadPlugins( SnorePlugin::PluginTypes types )
{
Q_D(SnoreCore);
qDebug() << "PluginInfo" << PluginContainer::pluginCache().keys();
foreach ( PluginContainer *info, PluginContainer::pluginCache().values())
{
if(types == PluginContainer::ALL || types.testFlag(info->type()))
if(types == SnorePlugin::ALL || types.testFlag(info->type()))
{
switch(info->type())
{
case PluginContainer::BACKEND:
case SnorePlugin::BACKEND:
{
qDebug() << info->name() << "is a Notification_Backend";
d->m_notificationBackends.append( info->name());
break;
}
case PluginContainer::SECONDARY_BACKEND:
case SnorePlugin::SECONDARY_BACKEND:
{
if(!info->load()->init( this )){
info->unload();
@ -76,7 +76,7 @@ void SnoreCore::loadPlugins( PluginContainer::PluginTypes types )
d->m_secondaryNotificationBackends.append(info->name());
break;
}
case PluginContainer::FRONTEND:
case SnorePlugin::FRONTEND:
{
qDebug() << info->name() << "is a Notification_Frontend";
if(!info->load()->init( this )){
@ -86,7 +86,7 @@ void SnoreCore::loadPlugins( PluginContainer::PluginTypes types )
d->m_Frontends.append(info->name());
break;
}
case PluginContainer::PLUGIN:
case SnorePlugin::PLUGIN:
{
qDebug() <<info->name()<<"is a SnorePlugin";
if(!info->load()->init(this)){

View File

@ -22,8 +22,8 @@
#include "snore_exports.h"
#include "application.h"
#include "plugins/plugincontainer.h"
#include "notification/notification.h"
#include "plugins/plugins.h"
#include "hint.h"
#include <QStringList>
@ -43,7 +43,7 @@ class SNORE_EXPORT SnoreCore : public QObject
public:
SnoreCore (QSystemTrayIcon *trayIcon = NULL );
~SnoreCore();
void loadPlugins ( PluginContainer::PluginTypes types );
void loadPlugins ( SnorePlugin::PluginTypes types );
void broadcastNotification( Notification notification );
@ -84,16 +84,17 @@ private:
};
static inline QString toPlainText ( const QString &string)
{
if(Qt::mightBeRichText(string))
{
return QTextDocumentFragment::fromHtml(string).toPlainText();
}
else
{
return string;
}
if(Qt::mightBeRichText(string))
{
return QTextDocumentFragment::fromHtml(string).toPlainText();
}
else
{
return string;
}
}
}

View File

@ -22,8 +22,10 @@
#define SNORECOREPRIVATE_H
#include "snore.h"
#include "plugins/snorebackend.h"
#include <QDir>
#include <QPointer>
namespace Snore
{

View File

@ -41,7 +41,7 @@ SnoreNotify::SnoreNotify():
qApp->setOrganizationName("TheOneRing");
m_trayIcon = new TrayIcon();
m_snore = new SnoreCore(m_trayIcon->trayIcon());
m_snore->loadPlugins(PluginContainer::ALL);
m_snore->loadPlugins(SnorePlugin::ALL);
load();
m_trayIcon->initConextMenu(m_snore);