[xswiftbus] Make xswiftbus completely Qt free

This commit is contained in:
Roland Winklmeier
2018-03-25 16:10:54 +02:00
parent b0a8fcaa45
commit 6a8ae67e06
13 changed files with 525 additions and 429 deletions

View File

@@ -14,12 +14,12 @@
#include <XPLM/XPLMPlugin.h>
#include <XPLM/XPLMProcessing.h>
#include <XPLM/XPLMUtilities.h>
#include <QCoreApplication>
#include <QSharedPointer>
#include <vector>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <clocale>
#include <string>
/*!
* \file
@@ -28,58 +28,58 @@
/*!
* Install a Qt message handler which outputs to the X-Plane debug log.
*/
class QXPlaneMessageHandler
{
static void handler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QByteArray localMsg = msg.toLocal8Bit();
QByteArray file(context.file);
if (file.isEmpty()) file = "<unknown>";
//class QXPlaneMessageHandler
//{
// static void handler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
// {
// QByteArray localMsg = msg.toLocal8Bit();
// QByteArray file(context.file);
// if (file.isEmpty()) file = "<unknown>";
int line = context.line;
// int line = context.line;
char *buffer = new char[64 + localMsg.size() + file.size()];
switch (type) {
case QtDebugMsg:
std::sprintf(buffer, "%s:%d: Debug: %s\n", file.constData(), line, localMsg.constData());
XPLMDebugString(buffer);
break;
case QtInfoMsg:
std::sprintf(buffer, "%s:%d: Info: %s\n", file.constData(), line, localMsg.constData());
XPLMDebugString(buffer);
break;
case QtWarningMsg:
std::sprintf(buffer, "%s:%d: Warning: %s\n", file.constData(), line, localMsg.constData());
XPLMDebugString(buffer);
break;
default:
case QtCriticalMsg:
std::sprintf(buffer, "%s:%d: Error: %s\n", file.constData(), line, localMsg.constData());
XPLMDebugString(buffer);
break;
case QtFatalMsg:
std::sprintf(buffer, "%s:%d: Fatal: %s\n", file.constData(), line, localMsg.constData());
XPLMDebugString(buffer);
std::abort();
}
delete[] buffer;
}
// char *buffer = new char[64 + localMsg.size() + file.size()];
// switch (type) {
// case QtDebugMsg:
// std::sprintf(buffer, "%s:%d: Debug: %s\n", file.constData(), line, localMsg.constData());
// XPLMDebugString(buffer);
// break;
// case QtInfoMsg:
// std::sprintf(buffer, "%s:%d: Info: %s\n", file.constData(), line, localMsg.constData());
// XPLMDebugString(buffer);
// break;
// case QtWarningMsg:
// std::sprintf(buffer, "%s:%d: Warning: %s\n", file.constData(), line, localMsg.constData());
// XPLMDebugString(buffer);
// break;
// default:
// case QtCriticalMsg:
// std::sprintf(buffer, "%s:%d: Error: %s\n", file.constData(), line, localMsg.constData());
// XPLMDebugString(buffer);
// break;
// case QtFatalMsg:
// std::sprintf(buffer, "%s:%d: Fatal: %s\n", file.constData(), line, localMsg.constData());
// XPLMDebugString(buffer);
// std::abort();
// }
// delete[] buffer;
// }
public:
/*!
* Install the handler.
*/
static void install()
{
qInstallMessageHandler(handler);
}
//public:
// /*!
// * Install the handler.
// */
// static void install()
// {
// qInstallMessageHandler(handler);
// }
//! Not copyable.
//! @{
QXPlaneMessageHandler(const QXPlaneMessageHandler &) = delete;
QXPlaneMessageHandler &operator =(const QXPlaneMessageHandler &) = delete;
//! @}
};
// //! Not copyable.
// //! @{
// QXPlaneMessageHandler(const QXPlaneMessageHandler &) = delete;
// QXPlaneMessageHandler &operator =(const QXPlaneMessageHandler &) = delete;
// //! @}
//};
/*!
* QApplication subclass used by XSwiftBus.
@@ -89,101 +89,134 @@ public:
* Qt framework, they can simply copy & paste this class into their project
* and both X-Plane plugins will be able to share a single QApplication safely.
*/
class QSharedApplication : public QCoreApplication
{
Q_OBJECT
//class QSharedApplication : public QCoreApplication
//{
// Q_OBJECT
QWeakPointer<QCoreApplication> m_weakptr;
// QWeakPointer<QCoreApplication> m_weakptr;
QSharedApplication(QSharedPointer<QCoreApplication> &ptr, int &argc, char **argv) : QCoreApplication(argc, argv)
{
ptr.reset(this);
m_weakptr = ptr;
}
// QSharedApplication(QSharedPointer<QCoreApplication> &ptr, int &argc, char **argv) : QCoreApplication(argc, argv)
// {
// ptr.reset(this);
// m_weakptr = ptr;
// }
static char *strdup(const char *s) { auto s2 = static_cast<char *>(std::malloc(std::strlen(s) + 1)); return std::strcpy(s2, s); }
// static char *strdup(const char *s) { auto s2 = static_cast<char *>(std::malloc(std::strlen(s) + 1)); return std::strcpy(s2, s); }
public:
/*!
* Returns a shared pointer to the QApplication.
*
* The QApplication will not be destroyed while this shared pointer exists.
*/
static QSharedPointer<QCoreApplication> sharedInstance()
{
QSharedPointer<QCoreApplication> ptr;
if (! instance())
{
static int argc = 1;
static char *argv[] = { strdup("X-Plane") };
//public:
// /*!
// * Returns a shared pointer to the QApplication.
// *
// * The QApplication will not be destroyed while this shared pointer exists.
// */
// static QSharedPointer<QCoreApplication> sharedInstance()
// {
// QSharedPointer<QCoreApplication> ptr;
// if (! instance())
// {
// static int argc = 1;
// static char *argv[] = { strdup("X-Plane") };
#ifdef Q_OS_UNIX
/* Workaround for #362 */
char* xplocale = setlocale(LC_ALL, nullptr);
#endif
//#ifdef Q_OS_UNIX
// /* Workaround for #362 */
// char* xplocale = setlocale(LC_ALL, nullptr);
//#endif
new QSharedApplication(ptr, argc, argv);
// new QSharedApplication(ptr, argc, argv);
#ifdef Q_OS_UNIX
setlocale(LC_ALL, xplocale);
#endif
}
if (! instance()->inherits("QSharedApplication"))
{
qFatal("There is an unshared QCoreApplication in another plugin");
}
return static_cast<QSharedApplication*>(instance())->m_weakptr;
}
};
//#ifdef Q_OS_UNIX
// setlocale(LC_ALL, xplocale);
//#endif
// }
// if (! instance()->inherits("QSharedApplication"))
// {
// qFatal("There is an unshared QCoreApplication in another plugin");
// }
// return static_cast<QSharedApplication*>(instance())->m_weakptr;
// }
//};
/*!
* Runs the Qt event loop inside the X-Plane event loop.
*/
class QXPlaneEventLoop : public QObject
{
Q_OBJECT
///*!
// * Runs the Qt event loop inside the X-Plane event loop.
// */
//class QXPlaneEventLoop : public QObject
//{
// Q_OBJECT
QXPlaneEventLoop(QObject *parent) : QObject(parent)
{
XPLMRegisterFlightLoopCallback(callback, -1, nullptr);
}
// QXPlaneEventLoop(QObject *parent) : QObject(parent)
// {
// XPLMRegisterFlightLoopCallback(callback, -1, nullptr);
// }
~QXPlaneEventLoop()
{
XPLMUnregisterFlightLoopCallback(callback, nullptr);
}
// ~QXPlaneEventLoop()
// {
// XPLMUnregisterFlightLoopCallback(callback, nullptr);
// }
static float callback(float, float, int, void *)
{
QCoreApplication::processEvents();
QCoreApplication::sendPostedEvents();
return -1;
}
// static float callback(float, float, int, void *)
// {
// QCoreApplication::processEvents();
// QCoreApplication::sendPostedEvents();
// return -1;
// }
public:
/*!
* Registers the X-Plane callback which calls into the Qt event loop,
* unless one was already registered.
*/
static void exec()
{
if (! QCoreApplication::instance()->findChild<QXPlaneEventLoop *>())
{
new QXPlaneEventLoop(QCoreApplication::instance());
}
}
};
//public:
// /*!
// * Registers the X-Plane callback which calls into the Qt event loop,
// * unless one was already registered.
// */
// static void exec()
// {
// if (! QCoreApplication::instance()->findChild<QXPlaneEventLoop *>())
// {
// new QXPlaneEventLoop(QCoreApplication::instance());
// }
// }
//};
namespace XSwiftBus
{
//! Absolute xplane path
extern QString g_xplanePath;
extern std::string g_xplanePath;
//! Platform specific dir separator
extern QString g_sep;
extern std::string g_sep;
//! Init global xplane path
void initXPlanePath();
//! Returns the directory name of a given file path
std::string getDirName(const std::string &filePath);
//! Returns the filename (including extension) of a given file path
std::string getFileName(const std::string &filePath);
//! Returns the filename without extension of a given file path
std::string getBaseName(const std::string &filePath);
//! Splits the given string maximal maxSplitCount times and returns the tokens
//! The size of the returned vector is up to maxSplitCount + 1 or less
std::vector<std::string> split(const std::string &str, size_t maxSplitCount = 0);
//! Simple logger class.
//! Don't use it directly, but the _LOG macros instead
class Logger
{
public:
//! Message type
enum MsgType { DebugMsg, WarningMsg, FatalMsg, InfoMsg };
Logger() = delete;
//! Print message to X-Plane log
static void print(const std::string &filePath, int line, MsgType type, const std::string &message);
};
//! Logger convenience macros
//! @{
#define DEBUG_LOG(msg) Logger::print(__FILE__, __LINE__, Logger::DebugMsg, msg)
#define INFO_LOG(msg) Logger::print(__FILE__, __LINE__, Logger::InfoMsg, msg)
//! @}
}
#endif // guard