mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 23:05:36 +08:00
@@ -34,8 +34,6 @@ contains(BLACK_CONFIG, XPlane) {
|
||||
|
||||
contains(BLACK_CONFIG, Samples) {
|
||||
SUBDIRS += samples/cli_client/sample_cli_client.pro
|
||||
SUBDIRS += samples/plugin/sample_plugin.pro
|
||||
SUBDIRS += samples/pluginmgr/sample_pluginmgr.pro
|
||||
SUBDIRS += samples/blackmiscvectorgeo/sample_vector_geo.pro
|
||||
SUBDIRS += samples/blackmiscquantities/sample_quantities_aviation.pro
|
||||
SUBDIRS += samples/blackmiscdbus/sample_blackmisc_dbus.pro
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
FILE(GLOB SRC *.cpp)
|
||||
SET(HEADERS server.h)
|
||||
|
||||
QT4_WRAP_CPP(HEADERS_MOC ${HEADERS})
|
||||
|
||||
ADD_LIBRARY(sample_plugin MODULE ${SRC} ${HEADERS_MOC})
|
||||
|
||||
TARGET_LINK_LIBRARIES(sample_plugin blackmisc ${QT_LIBRARIES})
|
||||
SET_TARGET_PROPERTIES(sample_plugin PROPERTIES PROJECT_LABEL "Samples - Plugin")
|
||||
@@ -1,21 +0,0 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "plugin.h"
|
||||
#include <iostream>
|
||||
|
||||
CPlugin::CPlugin(BlackMisc::IPluginFactory &factory, BlackMisc::IContext &context)
|
||||
: m_ctorOK(false),
|
||||
m_factory(factory),
|
||||
m_context(context)
|
||||
{
|
||||
std::cout << "Sample plugin constructor" << std::endl;
|
||||
m_ctorOK = true;
|
||||
}
|
||||
|
||||
CPlugin::~CPlugin()
|
||||
{
|
||||
std::cout << "Sample plugin destructor" << std::endl;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef SAMPLE_PLUGIN_H
|
||||
#define SAMPLE_PLUGIN_H
|
||||
|
||||
#include "blackmisc/plugins.h"
|
||||
|
||||
class CPlugin : public BlackMisc::IPlugin
|
||||
{
|
||||
public:
|
||||
CPlugin(BlackMisc::IPluginFactory &factory, BlackMisc::IContext &context);
|
||||
|
||||
virtual ~CPlugin();
|
||||
|
||||
virtual bool isValid() const override { return m_ctorOK; }
|
||||
|
||||
virtual BlackMisc::IPluginFactory &getFactory() override { return m_factory; }
|
||||
|
||||
private:
|
||||
bool m_ctorOK;
|
||||
BlackMisc::IPluginFactory &m_factory;
|
||||
BlackMisc::IContext &m_context;
|
||||
};
|
||||
|
||||
// This needs to be in the header so that Qt's "moc" processor can see it.
|
||||
class CPluginFactory : public QObject, public BlackMisc::IPluginFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(BlackMisc::IPluginFactory)
|
||||
Q_PLUGIN_METADATA(IID BLACKMISC_IPLUGINFACTORY_IID)
|
||||
BLACKMISC_IMPLEMENT_IPLUGINFACTORY(CPlugin, "sample_plugin", "An example minimal plugin")
|
||||
};
|
||||
|
||||
#endif //SAMPLE_PLUGIN_H
|
||||
@@ -1,25 +0,0 @@
|
||||
include (../../config.pri)
|
||||
include (../../build.pri)
|
||||
|
||||
QT += core
|
||||
QT -= gui
|
||||
|
||||
TARGET = sample_plugin
|
||||
TEMPLATE = lib
|
||||
|
||||
CONFIG += plugin
|
||||
CONFIG += blackmisc blackcore
|
||||
|
||||
|
||||
DEPENDPATH += . ../../src
|
||||
INCLUDEPATH += . ../../src
|
||||
|
||||
SOURCES += *.cpp
|
||||
HEADERS += *.h
|
||||
|
||||
win32:!win32-g++*: PRE_TARGETDEPS += ../../lib/blackmisc.lib
|
||||
else: PRE_TARGETDEPS += ../../lib/libblackmisc.a
|
||||
|
||||
DESTDIR = ../../bin
|
||||
|
||||
include (../../libraries.pri)
|
||||
@@ -1,6 +0,0 @@
|
||||
FILE(GLOB SRC *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(sample_pluginmgr ${SRC})
|
||||
|
||||
TARGET_LINK_LIBRARIES(sample_pluginmgr blackmisc ${QT_LIBRARIES})
|
||||
SET_TARGET_PROPERTIES(sample_pluginmgr PROPERTIES PROJECT_LABEL "Samples - Plugin Manager")
|
||||
@@ -1,52 +0,0 @@
|
||||
#include "blackcore/pluginmgr.h"
|
||||
#include "blackmisc/plugins.h"
|
||||
#include "blackmisc/context.h"
|
||||
#include <QCoreApplication>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication a(argc, argv);
|
||||
|
||||
BlackMisc::CApplicationContext ctx;
|
||||
BlackMisc::IContext::setInstance(ctx);
|
||||
|
||||
{
|
||||
const QString pluginPath = "../../build/bin";
|
||||
|
||||
std::cout << "Loading plugins from " << pluginPath.toStdString() << std::endl;
|
||||
|
||||
BlackCore::CPluginManager pluginmgr;
|
||||
pluginmgr.loadAllPlugins(pluginPath);
|
||||
size_t count = pluginmgr.getPluginCount();
|
||||
|
||||
std::cout << count << " plugins loaded" << std::endl << std::endl;
|
||||
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
std::cout << "Plugin " << i << ": " << pluginmgr.getName(i).toStdString()
|
||||
<< ": " << pluginmgr.getDescription(i).toStdString() << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
std::vector<BlackMisc::IPlugin*> plugins;
|
||||
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
std::cout << "Constructing plugin " << i << std::endl;
|
||||
|
||||
plugins.push_back(pluginmgr.constructPlugin(i));
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
for (std::vector<BlackMisc::IPlugin*>::iterator it = plugins.begin(); it != plugins.end(); ++it, ++i)
|
||||
{
|
||||
std::cout << "Destroying plugin " << i << std::endl;
|
||||
|
||||
(*it)->getFactory().destroy(*it);
|
||||
}
|
||||
}
|
||||
|
||||
//return a.exec();
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
include (../../config.pri)
|
||||
include (../../build.pri)
|
||||
|
||||
QT += core
|
||||
QT -= gui
|
||||
|
||||
TARGET = sample_pluginmgr
|
||||
TEMPLATE = app
|
||||
|
||||
CONFIG += console
|
||||
CONFIG -= app_bundle
|
||||
CONFIG += blackmisc blackcore
|
||||
|
||||
DEPENDPATH += . ../../src
|
||||
INCLUDEPATH += . ../../src
|
||||
|
||||
SOURCES += *.cpp
|
||||
|
||||
win32:!win32-g++*: PRE_TARGETDEPS += ../../lib/blackmisc.lib \
|
||||
../../lib/blackcore.lib
|
||||
else: PRE_TARGETDEPS += ../../lib/libblackmisc.a \
|
||||
../../lib/libblackcore.a
|
||||
|
||||
DESTDIR = ../../bin
|
||||
|
||||
include (../../libraries.pri)
|
||||
@@ -1,105 +0,0 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "blackcore/pluginmgr.h"
|
||||
#include "blackmisc/plugins.h"
|
||||
#include "blackmisc/context.h"
|
||||
#include <QDirIterator>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
|
||||
CPluginManager::~CPluginManager()
|
||||
{
|
||||
for (QVector<PluginEntry>::iterator it = m_plugins.begin(); it != m_plugins.end(); ++it)
|
||||
{
|
||||
Q_ASSERT_X(it->loader, "Plugin manager", "Previously loaded plugin's loader ptr is null");
|
||||
|
||||
it->loader->unload();
|
||||
}
|
||||
}
|
||||
|
||||
void CPluginManager::loadAllPlugins(const QString &pluginsPath)
|
||||
{
|
||||
//TODO should we use a custom extension, so we don't attempt to load non-plugin .dll/.so files?
|
||||
#ifdef Q_OS_WIN
|
||||
static const QStringList pluginsFilter("*.dll");
|
||||
#else
|
||||
static const QStringList pluginsFilter("*.so");
|
||||
#endif
|
||||
|
||||
QDirIterator iter (pluginsPath, pluginsFilter, QDir::Files);
|
||||
while (iter.hasNext())
|
||||
{
|
||||
QString filename = iter.next();
|
||||
|
||||
QSharedPointer<QPluginLoader> loader (new QPluginLoader (filename));
|
||||
try
|
||||
{
|
||||
if (! loader->load())
|
||||
{
|
||||
throw std::runtime_error(QString("Failed loading plugin from %1").arg(filename).toStdString());
|
||||
}
|
||||
|
||||
PluginEntry entry;
|
||||
entry.loader = loader;
|
||||
entry.factory = qobject_cast<BlackMisc::IPluginFactory*>(loader->instance());
|
||||
|
||||
if (! entry.factory)
|
||||
{
|
||||
throw std::runtime_error(QString("Plugin loaded from %1 is not compatible").arg(filename).toStdString());
|
||||
}
|
||||
|
||||
m_plugins.push_back(entry);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
//TODO warning?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const CPluginManager::PluginEntry &CPluginManager::getEntry(int index) const
|
||||
{
|
||||
Q_ASSERT_X(index < getPluginCount(), "Plugin manager", "Plugin index out of bounds");
|
||||
|
||||
const PluginEntry &entry = m_plugins[index];
|
||||
|
||||
Q_ASSERT_X(entry.factory, "Plugin manager", "Previously loaded plugin's factory ptr is null");
|
||||
Q_ASSERT_X(entry.loader, "Plugin manager", "Previously loaded plugin's loader ptr is null");
|
||||
|
||||
if (! entry.loader->isLoaded())
|
||||
{
|
||||
//TODO throw plugin loader unexpectedly unloaded
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
const QString CPluginManager::getName(int index) const
|
||||
{
|
||||
return getFactory(index)->getName();
|
||||
}
|
||||
|
||||
const QString CPluginManager::getDescription(int index) const
|
||||
{
|
||||
return getFactory(index)->getDescription();
|
||||
}
|
||||
|
||||
BlackMisc::IPlugin *CPluginManager::constructPlugin(int index)
|
||||
{
|
||||
BlackMisc::IPlugin *plugin = getFactory(index)->create(BlackMisc::IContext::getInstance());
|
||||
if (! plugin->isValid())
|
||||
{
|
||||
delete plugin;
|
||||
plugin = 0;
|
||||
//TODO throw plugin construction failed
|
||||
}
|
||||
return plugin;
|
||||
}
|
||||
|
||||
} // namespace BlackCore
|
||||
@@ -1,136 +0,0 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*!
|
||||
\file
|
||||
*/
|
||||
|
||||
#ifndef BLACKCORE_PLUGINMGR_H
|
||||
#define BLACKCORE_PLUGINMGR_H
|
||||
|
||||
#include <QPluginLoader>
|
||||
#include <QVector>
|
||||
#include <QSharedPointer>
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
class IPlugin;
|
||||
class IPluginFactory;
|
||||
}
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
|
||||
/*!
|
||||
Plugin manager.
|
||||
Loads plugins and allows them to be queried and instantiated.
|
||||
*/
|
||||
class CPluginManager
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
Destructor.
|
||||
*/
|
||||
virtual ~CPluginManager();
|
||||
|
||||
/*!
|
||||
Attempt to load all plugins found at the given path.
|
||||
\param pluginsPath
|
||||
*/
|
||||
void loadAllPlugins(const QString &pluginsPath);
|
||||
|
||||
/*!
|
||||
Return the total number of plugins loaded so far.
|
||||
\return
|
||||
*/
|
||||
int getPluginCount() const
|
||||
{
|
||||
return m_plugins.size();
|
||||
}
|
||||
|
||||
/*!
|
||||
Return the name of a plugin.
|
||||
\param index the plugin's index in the vector of plugins.
|
||||
\return
|
||||
*/
|
||||
const QString getName(int index) const;
|
||||
|
||||
/*!
|
||||
Return the description of a plugin.
|
||||
\param index the plugin's index in the vector of plugins.
|
||||
\return
|
||||
*/
|
||||
const QString getDescription(int index) const;
|
||||
|
||||
/*!
|
||||
Construct a plugin.
|
||||
\param index the plugin's index in the vector of plugins.
|
||||
\return a pointer to the newly created plugin.
|
||||
\warning You must release this pointer with IPluginFactory::destroy().
|
||||
*/
|
||||
BlackMisc::IPlugin *constructPlugin(int index);
|
||||
|
||||
/*!
|
||||
Direct access to the factory. You don't usually need this.
|
||||
\param index
|
||||
\return
|
||||
*/
|
||||
BlackMisc::IPluginFactory *getFactory(int index)
|
||||
{
|
||||
return const_cast<BlackMisc::IPluginFactory*>(static_cast<const CPluginManager*>(this)->getFactory(index));
|
||||
}
|
||||
|
||||
/*!
|
||||
Direct access to the factory. You don't usually need this.
|
||||
\param index
|
||||
\return
|
||||
*/
|
||||
const BlackMisc::IPluginFactory *getFactory(int index) const
|
||||
{
|
||||
return getEntry(index).factory;
|
||||
}
|
||||
|
||||
/*!
|
||||
Direct access to the QPluginLoader. You don't usually need this.
|
||||
\param index
|
||||
\return
|
||||
*/
|
||||
QPluginLoader *getLoader(int index)
|
||||
{
|
||||
return const_cast<QPluginLoader*>(static_cast<const CPluginManager*>(this)->getLoader(index));
|
||||
}
|
||||
|
||||
/*!
|
||||
Direct access to the QPluginLoader. You don't usually need this.
|
||||
\param index
|
||||
\return
|
||||
*/
|
||||
const QPluginLoader *getLoader(int index) const
|
||||
{
|
||||
return getEntry(index).loader.data();
|
||||
}
|
||||
|
||||
private:
|
||||
class PluginEntry
|
||||
{
|
||||
public:
|
||||
PluginEntry() : factory(0) {}
|
||||
BlackMisc::IPluginFactory *factory;
|
||||
QSharedPointer<QPluginLoader> loader;
|
||||
};
|
||||
|
||||
QVector<PluginEntry> m_plugins;
|
||||
|
||||
PluginEntry &getEntry(int index)
|
||||
{
|
||||
return const_cast<PluginEntry&>(static_cast<const CPluginManager*>(this)->getEntry(index));
|
||||
}
|
||||
|
||||
const PluginEntry &getEntry(int index) const;
|
||||
};
|
||||
|
||||
} // namespace BlackCore
|
||||
|
||||
#endif //BLACKCORE_PLUGINMGR_H
|
||||
@@ -1,124 +0,0 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*!
|
||||
\file
|
||||
*/
|
||||
|
||||
#ifndef BLACKMISC_PLUGINS_H
|
||||
#define BLACKMISC_PLUGINS_H
|
||||
|
||||
#include <QtPlugin>
|
||||
#include <QObject>
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
|
||||
class IContext;
|
||||
class IPluginFactory;
|
||||
|
||||
/*!
|
||||
The interface implemented by the main worker class in a plugin.
|
||||
Constructed by a factory implementing IPluginFactory and
|
||||
accessible to the application through the CPluginManager.
|
||||
*/
|
||||
class IPlugin
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
Destructor.
|
||||
*/
|
||||
virtual ~IPlugin() {}
|
||||
|
||||
/*!
|
||||
Exceptions are not allowed to leave plugins, so we use this function
|
||||
to test whether the plugin was constructed successfully.
|
||||
\return False if an error occurred during plugin construction.
|
||||
*/
|
||||
virtual bool isValid() const = 0;
|
||||
|
||||
/*!
|
||||
Return the factory used to construct this object.
|
||||
This is usually passed to the plugin's constructor by the factory itself.
|
||||
\return
|
||||
*/
|
||||
virtual IPluginFactory &getFactory() = 0;
|
||||
};
|
||||
|
||||
/*!
|
||||
The root interface for classes exported from plugins.
|
||||
This is a factory pattern for creating and destroying instances of IPlugin.
|
||||
You usually don't need to worry about this, if you use the
|
||||
MAKE_BLACK_PLUGIN macro to define your factory.
|
||||
*/
|
||||
class IPluginFactory
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
Destructor.
|
||||
*/
|
||||
virtual ~IPluginFactory() {}
|
||||
|
||||
/*!
|
||||
Construct an instance of the plugin.
|
||||
\param context The application context.
|
||||
\return a pointer to the newly created plugin.
|
||||
\warning You must release this pointer with IPluginFactory::destroy().
|
||||
*/
|
||||
virtual IPlugin *create(IContext &context) = 0;
|
||||
|
||||
/*!
|
||||
Destroy a plugin which was created by this factory.
|
||||
*/
|
||||
virtual void destroy(IPlugin *plugin) = 0;
|
||||
|
||||
/*!
|
||||
Return the plugin's short name.
|
||||
\return
|
||||
*/
|
||||
virtual const char *getName() const = 0;
|
||||
|
||||
/*!
|
||||
Return the plugin's description.
|
||||
\return
|
||||
*/
|
||||
virtual const char *getDescription() const = 0;
|
||||
};
|
||||
|
||||
/*!
|
||||
Custom deleter for QScopedPointer.
|
||||
*/
|
||||
struct TPluginDeleter
|
||||
{
|
||||
//! Delete a plugin
|
||||
static void cleanup(IPlugin *plugin)
|
||||
{
|
||||
if (plugin) {
|
||||
plugin->getFactory().destroy(plugin);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace BlackMisc
|
||||
|
||||
//! Qt interface ID for IPluginFactory.
|
||||
#define BLACKMISC_IPLUGINFACTORY_IID "net.vatsim.client.BlackMisc.IPluginFactory"
|
||||
|
||||
Q_DECLARE_INTERFACE(BlackMisc::IPluginFactory, BLACKMISC_IPLUGINFACTORY_IID)
|
||||
|
||||
/*!
|
||||
Macro to put inside an IPluginFactory subclass to help with implementation.
|
||||
\param CLASS The plugin class which this factory constructs.
|
||||
\param NAME A string literal, the plugin's short name.
|
||||
\param DESCRIPTION A string literal, a brief description of the plugin.
|
||||
*/
|
||||
#define BLACKMISC_IMPLEMENT_IPLUGINFACTORY(CLASS, NAME, DESCRIPTION) \
|
||||
public: \
|
||||
BlackMisc::IPlugin *create(BlackMisc::IContext &context) { return new CLASS(*this, context); } \
|
||||
void destroy(BlackMisc::IPlugin *plugin) { if (plugin) delete plugin; } \
|
||||
const char *getName() const { return NAME; } \
|
||||
const char *getDescription() const { return DESCRIPTION; }
|
||||
|
||||
#endif //BLACKMISC_PLUGINS_H
|
||||
Reference in New Issue
Block a user