Qt: Central log controller
Jeffrey Pfau jeffrey@endrift.com
Sat, 04 Jul 2015 00:16:26 -0700
7 files changed,
229 insertions(+),
145 deletions(-)
M
src/platform/qt/CMakeLists.txt
→
src/platform/qt/CMakeLists.txt
@@ -63,6 +63,7 @@ GamepadButtonEvent.cpp
InputController.cpp KeyEditor.cpp LoadSaveState.cpp + LogController.cpp LogView.cpp MemoryModel.cpp MemoryView.cpp
A
src/platform/qt/LogController.cpp
@@ -0,0 +1,77 @@
+/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * 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 "LogController.h" + +using namespace QGBA; + +LogController::LogController(int levels, QObject* parent) + : QObject(parent) + , m_logLevel(levels) +{ +} + +void LogController::postLog(int level, const QString& string) { + if (!(m_logLevel & level)) { + return; + } + emit logPosted(level, string); +} + +void LogController::setLevels(int levels) { + m_logLevel = levels; + emit levelsSet(levels); +} + +void LogController::enableLevels(int levels) { + m_logLevel |= levels; + emit levelsEnabled(levels); +} + +void LogController::disableLevels(int levels) { + m_logLevel &= ~levels; + emit levelsDisabled(levels); +} + +QString LogController::toString(int level) { + switch (level) { + case GBA_LOG_DEBUG: + return tr("DEBUG"); + case GBA_LOG_STUB: + return tr("STUB"); + case GBA_LOG_INFO: + return tr("INFO"); + case GBA_LOG_WARN: + return tr("WARN"); + case GBA_LOG_ERROR: + return tr("ERROR"); + case GBA_LOG_FATAL: + return tr("FATAL"); + case GBA_LOG_GAME_ERROR: + return tr("GAME ERROR"); + case GBA_LOG_SWI: + return tr("SWI"); + case GBA_LOG_STATUS: + return tr("STATUS"); + case GBA_LOG_SIO: + return tr("SIO"); + } + return QString(); +} + +LogController::Stream::Stream(LogController* controller, int level) + : m_log(controller) + , m_level(level) +{ +} + +LogController::Stream::~Stream() { + m_log->postLog(m_level, m_queue.join(" ")); +} + +LogController::Stream& LogController::Stream::operator<<(const QString& string) { + m_queue.append(string); + return *this; +}
A
src/platform/qt/LogController.h
@@ -0,0 +1,63 @@
+/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * 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 QGBA_LOG_CONTROLLER +#define QGBA_LOG_CONTROLLER + +#include <QObject> +#include <QStringList> + +extern "C" { +#include "gba/gba.h" +} + +namespace QGBA { + +class LogController : public QObject { +Q_OBJECT + +private: + class Stream { + public: + Stream(LogController* controller, int level); + ~Stream(); + + Stream& operator<<(const QString&); + + private: + int m_level; + LogController* m_log; + + QStringList m_queue; + }; + +public: + LogController(int levels, QObject* parent = nullptr); + + int levels() const { return m_logLevel; } + + Stream operator()(int level); + + static QString toString(int level); + +signals: + void logPosted(int level, const QString& log); + void levelsSet(int levels); + void levelsEnabled(int levels); + void levelsDisabled(int levels); + +public slots: + void postLog(int level, const QString& string); + void setLevels(int levels); + void enableLevels(int levels); + void disableLevels(int levels); + +private: + int m_logLevel; +}; + +} + +#endif
M
src/platform/qt/LogView.cpp
→
src/platform/qt/LogView.cpp
@@ -5,38 +5,71 @@ * 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 "LogView.h" +#include "LogController.h" + #include <QTextBlock> #include <QTextCursor> using namespace QGBA; -LogView::LogView(QWidget* parent) +LogView::LogView(LogController* log, QWidget* parent) : QWidget(parent) - , m_logLevel(0) , m_lines(0) , m_lineLimit(DEFAULT_LINE_LIMIT) { m_ui.setupUi(this); - connect(m_ui.levelDebug, SIGNAL(toggled(bool)), this, SLOT(setLevelDebug(bool))); - connect(m_ui.levelStub, SIGNAL(toggled(bool)), this, SLOT(setLevelStub(bool))); - connect(m_ui.levelInfo, SIGNAL(toggled(bool)), this, SLOT(setLevelInfo(bool))); - connect(m_ui.levelWarn, SIGNAL(toggled(bool)), this, SLOT(setLevelWarn(bool))); - connect(m_ui.levelError, SIGNAL(toggled(bool)), this, SLOT(setLevelError(bool))); - connect(m_ui.levelFatal, SIGNAL(toggled(bool)), this, SLOT(setLevelFatal(bool))); - connect(m_ui.levelGameError, SIGNAL(toggled(bool)), this, SLOT(setLevelGameError(bool))); - connect(m_ui.levelSWI, SIGNAL(toggled(bool)), this, SLOT(setLevelSWI(bool))); - connect(m_ui.levelStatus, SIGNAL(toggled(bool)), this, SLOT(setLevelStatus(bool))); - connect(m_ui.levelSIO, SIGNAL(toggled(bool)), this, SLOT(setLevelSIO(bool))); + connect(m_ui.levelDebug, &QAbstractButton::toggled, [this](bool set) { + setLevel(GBA_LOG_DEBUG, set); + }); + connect(m_ui.levelStub, &QAbstractButton::toggled, [this](bool set) { + setLevel(GBA_LOG_STUB, set); + }); + connect(m_ui.levelInfo, &QAbstractButton::toggled, [this](bool set) { + setLevel(GBA_LOG_INFO, set); + }); + connect(m_ui.levelWarn, &QAbstractButton::toggled, [this](bool set) { + setLevel(GBA_LOG_WARN, set); + }); + connect(m_ui.levelError, &QAbstractButton::toggled, [this](bool set) { + setLevel(GBA_LOG_ERROR, set); + }); + connect(m_ui.levelFatal, &QAbstractButton::toggled, [this](bool set) { + setLevel(GBA_LOG_FATAL, set); + }); + connect(m_ui.levelGameError, &QAbstractButton::toggled, [this](bool set) { + setLevel(GBA_LOG_GAME_ERROR, set); + }); + connect(m_ui.levelSWI, &QAbstractButton::toggled, [this](bool set) { + setLevel(GBA_LOG_SWI, set); + }); + connect(m_ui.levelStatus, &QAbstractButton::toggled, [this](bool set) { + setLevel(GBA_LOG_STATUS, set); + }); + connect(m_ui.levelSIO, &QAbstractButton::toggled, [this](bool set) { + setLevel(GBA_LOG_SIO, set); + }); connect(m_ui.clear, SIGNAL(clicked()), this, SLOT(clear())); connect(m_ui.maxLines, SIGNAL(valueChanged(int)), this, SLOT(setMaxLines(int))); m_ui.maxLines->setValue(DEFAULT_LINE_LIMIT); + + connect(log, SIGNAL(logPosted(int, const QString&)), this, SLOT(postLog(int, const QString&))); + connect(log, SIGNAL(levelsSet(int)), this, SLOT(setLevels(int))); + connect(log, &LogController::levelsEnabled, [this](int level) { + bool s = blockSignals(true); + setLevel(level, true); + blockSignals(s); + }); + connect(log, &LogController::levelsDisabled, [this](int level) { + bool s = blockSignals(true); + setLevel(level, false); + blockSignals(s); + }); + connect(this, SIGNAL(levelsEnabled(int)), log, SLOT(enableLevels(int))); + connect(this, SIGNAL(levelsDisabled(int)), log, SLOT(disableLevels(int))); } void LogView::postLog(int level, const QString& log) { - if (!(level & m_logLevel)) { - return; - } - m_ui.view->appendPlainText(QString("%1:\t%2").arg(toString(level)).arg(log)); + m_ui.view->appendPlainText(QString("%1:\t%2").arg(LogController::toString(level)).arg(log)); ++m_lines; if (m_lines > m_lineLimit) { clearLine();@@ -49,8 +82,6 @@ m_lines = 0;
} void LogView::setLevels(int levels) { - m_logLevel = levels; - m_ui.levelDebug->setCheckState(levels & GBA_LOG_DEBUG ? Qt::Checked : Qt::Unchecked); m_ui.levelStub->setCheckState(levels & GBA_LOG_STUB ? Qt::Checked : Qt::Unchecked); m_ui.levelInfo->setCheckState(levels & GBA_LOG_INFO ? Qt::Checked : Qt::Unchecked);@@ -61,87 +92,44 @@ m_ui.levelGameError->setCheckState(levels & GBA_LOG_GAME_ERROR ? Qt::Checked : Qt::Unchecked);
m_ui.levelSWI->setCheckState(levels & GBA_LOG_SWI ? Qt::Checked : Qt::Unchecked); m_ui.levelStatus->setCheckState(levels & GBA_LOG_STATUS ? Qt::Checked : Qt::Unchecked); m_ui.levelSIO->setCheckState(levels & GBA_LOG_SIO ? Qt::Checked : Qt::Unchecked); - - emit levelsSet(levels); } -void LogView::setLevelDebug(bool set) { - if (set) { - setLevel(GBA_LOG_DEBUG); - } else { - clearLevel(GBA_LOG_DEBUG); +void LogView::setLevel(int level, bool set) { + if (level & GBA_LOG_DEBUG) { + m_ui.levelDebug->setCheckState(set ? Qt::Checked : Qt::Unchecked); } -} - -void LogView::setLevelStub(bool set) { - if (set) { - setLevel(GBA_LOG_STUB); - } else { - clearLevel(GBA_LOG_STUB); + if (level & GBA_LOG_STUB) { + m_ui.levelStub->setCheckState(set ? Qt::Checked : Qt::Unchecked); } -} - -void LogView::setLevelInfo(bool set) { - if (set) { - setLevel(GBA_LOG_INFO); - } else { - clearLevel(GBA_LOG_INFO); + if (level & GBA_LOG_INFO) { + m_ui.levelInfo->setCheckState(set ? Qt::Checked : Qt::Unchecked); } -} - -void LogView::setLevelWarn(bool set) { - if (set) { - setLevel(GBA_LOG_WARN); - } else { - clearLevel(GBA_LOG_WARN); + if (level & GBA_LOG_WARN) { + m_ui.levelWarn->setCheckState(set ? Qt::Checked : Qt::Unchecked); + } + if (level & GBA_LOG_ERROR) { + m_ui.levelError->setCheckState(set ? Qt::Checked : Qt::Unchecked); } -} - -void LogView::setLevelError(bool set) { - if (set) { - setLevel(GBA_LOG_ERROR); - } else { - clearLevel(GBA_LOG_ERROR); + if (level & GBA_LOG_FATAL) { + m_ui.levelFatal->setCheckState(set ? Qt::Checked : Qt::Unchecked); } -} - -void LogView::setLevelFatal(bool set) { - if (set) { - setLevel(GBA_LOG_FATAL); - } else { - clearLevel(GBA_LOG_FATAL); + if (level & GBA_LOG_GAME_ERROR) { + m_ui.levelGameError->setCheckState(set ? Qt::Checked : Qt::Unchecked); } -} - -void LogView::setLevelGameError(bool set) { - if (set) { - setLevel(GBA_LOG_GAME_ERROR); - } else { - clearLevel(GBA_LOG_GAME_ERROR); + if (level & GBA_LOG_SWI) { + m_ui.levelSWI->setCheckState(set ? Qt::Checked : Qt::Unchecked); } -} - -void LogView::setLevelSWI(bool set) { - if (set) { - setLevel(GBA_LOG_SWI); - } else { - clearLevel(GBA_LOG_SWI); + if (level & GBA_LOG_STATUS) { + m_ui.levelStatus->setCheckState(set ? Qt::Checked : Qt::Unchecked); } -} - -void LogView::setLevelStatus(bool set) { - if (set) { - setLevel(GBA_LOG_STATUS); - } else { - clearLevel(GBA_LOG_STATUS); + if (level & GBA_LOG_SIO) { + m_ui.levelSIO->setCheckState(set ? Qt::Checked : Qt::Unchecked); } -} -void LogView::setLevelSIO(bool set) { if (set) { - setLevel(GBA_LOG_SIO); + emit levelsEnabled(level); } else { - clearLevel(GBA_LOG_SIO); + emit levelsDisabled(level); } }@@ -150,42 +138,6 @@ m_lineLimit = limit;
while (m_lines > m_lineLimit) { clearLine(); } -} - -QString LogView::toString(int level) { - switch (level) { - case GBA_LOG_DEBUG: - return tr("DEBUG"); - case GBA_LOG_STUB: - return tr("STUB"); - case GBA_LOG_INFO: - return tr("INFO"); - case GBA_LOG_WARN: - return tr("WARN"); - case GBA_LOG_ERROR: - return tr("ERROR"); - case GBA_LOG_FATAL: - return tr("FATAL"); - case GBA_LOG_GAME_ERROR: - return tr("GAME ERROR"); - case GBA_LOG_SWI: - return tr("SWI"); - case GBA_LOG_STATUS: - return tr("STATUS"); - case GBA_LOG_SIO: - return tr("SIO"); - } - return QString(); -} - -void LogView::setLevel(int level) { - m_logLevel |= level; - emit levelsEnabled(level); -} - -void LogView::clearLevel(int level) { - m_logLevel &= ~level; - emit levelsDisabled(level); } void LogView::clearLine() {
M
src/platform/qt/LogView.h
→
src/platform/qt/LogView.h
@@ -16,14 +16,15 @@ }
namespace QGBA { +class LogController; + class LogView : public QWidget { Q_OBJECT public: - LogView(QWidget* parent = nullptr); + LogView(LogController* log, QWidget* parent = nullptr); signals: - void levelsSet(int levels); void levelsEnabled(int levels); void levelsDisabled(int levels);@@ -32,30 +33,17 @@ void postLog(int level, const QString& log);
void setLevels(int levels); void clear(); - void setLevelDebug(bool); - void setLevelStub(bool); - void setLevelInfo(bool); - void setLevelWarn(bool); - void setLevelError(bool); - void setLevelFatal(bool); - void setLevelGameError(bool); - void setLevelSWI(bool); - void setLevelStatus(bool); - void setLevelSIO(bool); - +private slots: void setMaxLines(int); private: static const int DEFAULT_LINE_LIMIT = 1000; Ui::LogView m_ui; - int m_logLevel; int m_lines; int m_lineLimit; - static QString toString(int level); - void setLevel(int level); - void clearLevel(int level); + void setLevel(int level, bool); void clearLine(); };
M
src/platform/qt/Window.cpp
→
src/platform/qt/Window.cpp
@@ -47,7 +47,8 @@ #endif
Window::Window(ConfigController* config, int playerId, QWidget* parent) : QMainWindow(parent) - , m_logView(new LogView()) + , m_log(0) + , m_logView(new LogView(&m_log)) , m_stateWindow(nullptr) , m_screenWidget(new WindowBackground()) , m_logo(":/res/mgba-1024.png")@@ -110,16 +111,16 @@ #endif
connect(m_controller, SIGNAL(gamePaused(GBAThread*)), &m_inputController, SLOT(resumeScreensaver())); connect(m_controller, SIGNAL(gameUnpaused(GBAThread*)), m_display, SLOT(unpauseDrawing())); connect(m_controller, SIGNAL(gameUnpaused(GBAThread*)), &m_inputController, SLOT(suspendScreensaver())); - connect(m_controller, SIGNAL(postLog(int, const QString&)), m_logView, SLOT(postLog(int, const QString&))); + connect(m_controller, SIGNAL(postLog(int, const QString&)), &m_log, SLOT(postLog(int, const QString&))); connect(m_controller, SIGNAL(frameAvailable(const uint32_t*)), this, SLOT(recordFrame())); connect(m_controller, SIGNAL(frameAvailable(const uint32_t*)), m_display, SLOT(framePosted(const uint32_t*))); connect(m_controller, SIGNAL(gameCrashed(const QString&)), this, SLOT(gameCrashed(const QString&))); connect(m_controller, SIGNAL(gameFailed()), this, SLOT(gameFailed())); connect(m_controller, SIGNAL(unimplementedBiosCall(int)), this, SLOT(unimplementedBiosCall(int))); connect(m_controller, SIGNAL(statusPosted(const QString&)), m_display, SLOT(showMessage(const QString&))); - connect(m_logView, SIGNAL(levelsSet(int)), m_controller, SLOT(setLogLevel(int))); - connect(m_logView, SIGNAL(levelsEnabled(int)), m_controller, SLOT(enableLogLevel(int))); - connect(m_logView, SIGNAL(levelsDisabled(int)), m_controller, SLOT(disableLogLevel(int))); + connect(&m_log, SIGNAL(levelsSet(int)), m_controller, SLOT(setLogLevel(int))); + connect(&m_log, SIGNAL(levelsEnabled(int)), m_controller, SLOT(enableLogLevel(int))); + connect(&m_log, SIGNAL(levelsDisabled(int)), m_controller, SLOT(disableLogLevel(int))); connect(this, SIGNAL(startDrawing(GBAThread*)), m_display, SLOT(startDrawing(GBAThread*)), Qt::QueuedConnection); connect(this, SIGNAL(shutdown()), m_display, SLOT(stopDrawing())); connect(this, SIGNAL(shutdown()), m_controller, SLOT(closeGame()));@@ -128,7 +129,7 @@ connect(this, SIGNAL(audioBufferSamplesChanged(int)), m_controller, SLOT(setAudioBufferSamples(int)));
connect(this, SIGNAL(fpsTargetChanged(float)), m_controller, SLOT(setFPSTarget(float))); connect(&m_fpsTimer, SIGNAL(timeout()), this, SLOT(showFPS())); - m_logView->setLevels(GBA_LOG_WARN | GBA_LOG_ERROR | GBA_LOG_FATAL | GBA_LOG_STATUS); + m_log.setLevels(GBA_LOG_WARN | GBA_LOG_ERROR | GBA_LOG_FATAL | GBA_LOG_STATUS); m_fpsTimer.setInterval(FPS_TIMER_INTERVAL); m_shortcutController->setConfigController(m_config);@@ -173,7 +174,7 @@
void Window::loadConfig() { const GBAOptions* opts = m_config->options(); - m_logView->setLevels(opts->logLevel); + m_log.setLevels(opts->logLevel); m_controller->setOptions(opts); m_display->lockAspectRatio(opts->lockAspectRatio);
M
src/platform/qt/Window.h
→
src/platform/qt/Window.h
@@ -20,6 +20,7 @@
#include "GDBController.h" #include "InputController.h" #include "LoadSaveState.h" +#include "LogController.h" struct GBAOptions; struct GBAArguments;@@ -140,6 +141,7 @@
GameController* m_controller; Display* m_display; QList<QAction*> m_gameActions; + LogController m_log; LogView* m_logView; LoadSaveState* m_stateWindow; WindowBackground* m_screenWidget;