From 75d973d60ad7f6b56818c0df5b9c67a046fa1330 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Thu, 26 Mar 2009 15:27:26 -0400 Subject: Add Sigmod support to PluginLoading and the Model --- sigtools/PluginLoader.cpp | 104 ++++++++++++++++++++++++++++++++++++------- sigtools/PluginLoader.h | 6 +++ sigtools/PluginLoader_p.h | 6 +++ sigtools/PluginTreeModel.cpp | 20 +++++++-- 4 files changed, 118 insertions(+), 18 deletions(-) (limited to 'sigtools') diff --git a/sigtools/PluginLoader.cpp b/sigtools/PluginLoader.cpp index 96068d62..dc2608ab 100644 --- a/sigtools/PluginLoader.cpp +++ b/sigtools/PluginLoader.cpp @@ -24,10 +24,18 @@ #include #include +// Sigmod includes +#include + // KDE includes #include #include +#include + +// Qt includes +#include +using namespace Sigmod; using namespace Sigscript; using namespace Sigencore; using namespace Sigencore::Plugins; @@ -47,6 +55,11 @@ KService::Ptr PluginLoader::service(const QString& type, const QString& name) return loader->service(type, name); } +Game* PluginLoader::game(const QString& name) +{ + return loader->game(name); +} + PluginBase* PluginLoader::plugin(const QString& type, const QString& name) { return loader->factory(type, name); @@ -84,29 +97,81 @@ void PluginLoader::Private::refresh(const QString& type) foreach (const Service& service, curServices) delete service.second; m_available[type].clear(); + if (type == "Sigmod") + { + QList games = m_games.values(); + foreach (Game* game, games) + delete game; + m_games.clear(); + } + // TODO: Progress dialog? KService::List services = KServiceTypeTrader::self()->query(QString("Sigen/%1").arg(type), "[X-Sigen-MinVersion] <= 000101"); foreach (KService::Ptr service, services) { - KPluginLoader loader(service->library()); - KPluginFactory *factory = loader.factory(); - if (factory) + if (type == "Sigmod") { - PluginBase* plugin = NULL; - if (type == "Arena") - plugin = factory->create(this); - else if (type == "Canvas") - plugin = factory->create(this); - else - KMessageBox::information(NULL, QString("The plugin type \"Sigen/%1\" is not supported.").arg(type), "Unsupported plugin type"); - if (plugin) + const QString name = service->property("X-Sigen-Sigmod-Name", QVariant::String).toString(); + const QStringList version = service->property("X-Sigen-Sigmod-Version", QVariant::StringList).toStringList(); + const QString variant = service->property("X-Sigen-Sigmod-Variant", QVariant::String).toString(); + const QStringList variantVersion = service->property("X-Sigen-Sigmod-VariantVersion", QVariant::StringList).toStringList(); + QString fullName; + QString varPath; + if (!variant.isEmpty()) + varPath = QString("/%1/%2").arg(variant).arg(variantVersion.join("-")); + fullName = QString("%1/%2%3").arg(name).arg(version.join("-")).arg(varPath); + QString fileName = KStandardDirs::locate("sigmod", QString("%1.smod").arg(fullName)); + if (!fileName.isEmpty()) { - QStringList classes = plugin->classList(); - foreach (const QString& className, classes) - m_available[type][className] = Service(service, plugin); + QFile file(fileName); + Game* game = NULL; + if (file.open(QIODevice::ReadOnly)) + { + QDomDocument xml; + QString error; + int line; + int column; + if (xml.setContent(&file, &error, &line, &column)) + { + if (xml.doctype().name() == "Sigmod") + game = new Game(xml.documentElement()); + else + KMessageBox::error(NULL, "The file is not a Sigmod.", "Invalid Sigmod"); + } + else + KMessageBox::error(NULL, QString("%1 at line %2, column %3").arg(error).arg(line).arg(column), "XML Error"); + } + file.close(); + // TODO: validate + if (game) + { + m_available[type][fullName] = Service(service, NULL); + m_games[fullName] = game; + } } } else - KMessageBox::error(NULL, QString("The plugin of type \"Sigen/%1\" with name \"%2\" is not a valid Sigen plugin. The error was:\n%3").arg(type).arg(service->name()).arg(loader.errorString()), "Plugin loading error"); + { + KPluginLoader loader(service->library()); + KPluginFactory *factory = loader.factory(); + if (factory) + { + PluginBase* plugin = NULL; + if (type == "Arena") + plugin = factory->create(this); + else if (type == "Canvas") + plugin = factory->create(this); + else + KMessageBox::information(NULL, QString("The plugin type \"Sigen/%1\" is not supported.").arg(type), "Unsupported plugin type"); + if (plugin) + { + QStringList classes = plugin->classList(); + foreach (const QString& className, classes) + m_available[type][className] = Service(service, plugin); + } + } + else + KMessageBox::error(NULL, QString("The plugin of type \"Sigen/%1\" with name \"%2\" is not a valid Sigen plugin. The error was:\n%3").arg(type).arg(service->name()).arg(loader.errorString()), "Plugin loading error"); + } } } @@ -136,3 +201,12 @@ PluginBase* PluginLoader::Private::factory(const QString& type, const QString& n return m_available[type][name].second; return NULL; } + +Game* PluginLoader::Private::game(const QString& name) +{ + if (!m_games.contains(name)) + refresh("Sigmod"); + if (m_games.contains(name)) + return m_games[name]; + return NULL; +} diff --git a/sigtools/PluginLoader.h b/sigtools/PluginLoader.h index 17e092f6..fb000361 100644 --- a/sigtools/PluginLoader.h +++ b/sigtools/PluginLoader.h @@ -42,6 +42,10 @@ namespace Sigscript class Config; class GameWrapper; } +namespace Sigmod +{ +class Game; +} namespace Sigtools { @@ -50,6 +54,8 @@ namespace PluginLoader SIGTOOLS_EXPORT QStringList availablePlugins(const QString& type, const bool forceLookup = false); SIGTOOLS_EXPORT KService::Ptr service(const QString& type, const QString& name); + SIGTOOLS_EXPORT Sigmod::Game* game(const QString& name); + SIGTOOLS_EXPORT Sigencore::Plugins::PluginBase* plugin(const QString& type, const QString& name); SIGTOOLS_EXPORT Sigencore::Plugins::ArenaPlugin* pluginForArena(const QString& arena); SIGTOOLS_EXPORT Sigencore::Plugins::CanvasPlugin* pluginForCanvas(const QString& canvas); diff --git a/sigtools/PluginLoader_p.h b/sigtools/PluginLoader_p.h index fa11988d..5597a45a 100644 --- a/sigtools/PluginLoader_p.h +++ b/sigtools/PluginLoader_p.h @@ -36,6 +36,10 @@ namespace Plugins class PluginBase; } } +namespace Sigmod +{ +class Game; +} namespace Sigtools { @@ -50,10 +54,12 @@ class SIGTOOLS_NO_EXPORT Private : public QObject QStringList services(const QString& type); KService::Ptr service(const QString& type, const QString& name); Sigencore::Plugins::PluginBase* factory(const QString& type, const QString& name); + Sigmod::Game* game(const QString& name); protected: typedef QPair Service; typedef QMap PluginList; QMap m_available; + QMap m_games; }; } } diff --git a/sigtools/PluginTreeModel.cpp b/sigtools/PluginTreeModel.cpp index fda0a822..bd4f6bef 100644 --- a/sigtools/PluginTreeModel.cpp +++ b/sigtools/PluginTreeModel.cpp @@ -28,6 +28,7 @@ // KDE includes #include +#include // Qt includes #include @@ -47,12 +48,25 @@ void PluginTreeModel::setTypes(const QStringList& types) const QStringList names = PluginLoader::availablePlugins(type); foreach (const QString& name, names) { - PluginBase* plugin = PluginLoader::plugin(type, name); ClassData data; data.m_type = type; data.m_name = name; - data.m_description = plugin->description(name); - data.m_icon = plugin->icon(name); + if (type == "Sigmod") + { + KService::Ptr service = PluginLoader::service(type, name); + const QString category = service->property("X-Sigen-Sigmod-Category", QVariant::String).toString(); + if (!category.isEmpty()) + data.m_type.append(QString("/%1").arg(category)); + data.m_name.replace('/', " - "); + data.m_description = service->property("X-Sigen-Sigmod-Description", QVariant::String).toString(); + data.m_icon = KIcon(service->icon()); + } + else + { + PluginBase* plugin = PluginLoader::plugin(type, name); + data.m_description = plugin->description(name); + data.m_icon = plugin->icon(name); + } beginInsertRows(QModelIndex(), m_entries.size(), m_entries.size()); m_entries.append(data); endInsertRows(); -- cgit