summaryrefslogtreecommitdiffstats
path: root/sigtools/PluginLoader.cpp
blob: e7d787b6b9c3b3a00b8b8b5a08f98645732d4be5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
 * Copyright 2009 Ben Boeckel <MathStuf@gmail.com>
 * 
 * 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 3 of the License, or
 * (at your option) any later version.
 * 
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

// Header include
#include "PluginLoader.h"
#include "PluginLoader_p.h"

// Sigencore plugin includes
#include <sigencore/plugins/PluginBase.h>
#include <sigencore/plugins/ArenaPlugin.h>
#include <sigencore/plugins/CanvasPlugin.h>

// KDE includes
#include <KMessageBox>
#include <KServiceTypeTrader>

using namespace Sigscript;
using namespace Sigencore;
using namespace Sigencore::Plugins;
using namespace Sigtools;

K_GLOBAL_STATIC(PluginLoader::Private, loader)

QStringList PluginLoader::availablePlugins(const QString& type, const bool forceLookup)
{
    if (forceLookup || !loader->m_available.contains(type))
        loader->refresh(type);
    return loader->m_available[type].keys();
}

KService::Ptr PluginLoader::service(const QString& type, const QString& name)
{
    return loader->service(type, name);
}

PluginBase* PluginLoader::plugin(const QString& type, const QString& name)
{
    return loader->factory(type, name);
}

ArenaPlugin* PluginLoader::pluginForArena(const QString& arena)
{
    return qobject_cast<ArenaPlugin*>(loader->factory("Arena", arena));
}

CanvasPlugin* PluginLoader::pluginForCanvas(const QString& canvas)
{
    return qobject_cast<CanvasPlugin*>(loader->factory("canvasa", canvas));
}

Arena* PluginLoader::loadArena(const QString& name, GameWrapper* game, Config* parent)
{
    ArenaPlugin* plugin = pluginForArena(name);
    if (plugin)
        return plugin->getArena(name, game, parent);
    return NULL;
}

Canvas* PluginLoader::loadCanvas(const QString& name, GameWrapper* game, Config* parent)
{
    CanvasPlugin* plugin = pluginForCanvas(name);
    if (plugin)
        return plugin->getCanvas(name, game, parent);
    return NULL;
}

void PluginLoader::Private::refresh(const QString& type)
{
    QList<Service> curServices = m_available[type].values();
    foreach (const Service& service, curServices)
        delete service.second;
    m_available[type].clear();
    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)
        {
            PluginBase* plugin;
            if (type == "Arena")
                plugin = factory->create<ArenaPlugin>(this);
            else if (type == "Canvas")
                plugin = factory->create<CanvasPlugin>(this);
            else
                KMessageBox::information(NULL, QString("The plugin type \"Sigen/%1\" is not supported.").arg(type), "Unsupported plugin type");
            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");
    }
}

KService::Ptr PluginLoader::Private::service(const QString& type, const QString& name)
{
    if (!m_available.contains(type))
        refresh(type);
    if (m_available[type].contains(name))
        return m_available[type][name].first;
    return KService::Ptr();
}

PluginBase* PluginLoader::Private::factory(const QString& type, const QString& name)
{
    if (!m_available.contains(type))
        refresh(type);
    if (m_available[type].contains(name))
        return m_available[type][name].second;
    return NULL;
}