Qt: Central log controller

This commit is contained in:
Jeffrey Pfau 2015-07-04 00:16:26 -07:00
parent 4e6ed63848
commit 3c9433b74c
7 changed files with 229 additions and 145 deletions

View File

@ -63,6 +63,7 @@ set(SOURCE_FILES
InputController.cpp
KeyEditor.cpp
LoadSaveState.cpp
LogController.cpp
LogView.cpp
MemoryModel.cpp
MemoryView.cpp

View File

@ -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;
}

View File

@ -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

View File

@ -5,38 +5,71 @@
* 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 @@ void LogView::clear() {
}
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 @@ void LogView::setLevels(int levels) {
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);
}
}
void LogView::setLevelError(bool set) {
if (set) {
setLevel(GBA_LOG_ERROR);
} else {
clearLevel(GBA_LOG_ERROR);
if (level & GBA_LOG_ERROR) {
m_ui.levelError->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_FATAL) {
m_ui.levelFatal->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_GAME_ERROR) {
m_ui.levelGameError->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_SWI) {
m_ui.levelSWI->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_STATUS) {
m_ui.levelStatus->setCheckState(set ? Qt::Checked : Qt::Unchecked);
}
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);
}
}
@ -152,42 +140,6 @@ void LogView::setMaxLines(int limit) {
}
}
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() {
QTextCursor cursor(m_ui.view->document());
cursor.setPosition(0);

View File

@ -16,14 +16,15 @@ extern "C" {
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 @@ public slots:
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();
};

View File

@ -47,7 +47,8 @@ using std::isnan;
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 @@ Window::Window(ConfigController* config, int playerId, QWidget* parent)
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 @@ Window::Window(ConfigController* config, int playerId, QWidget* parent)
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::setConfig(ConfigController* config) {
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);

View File

@ -20,6 +20,7 @@ extern "C" {
#include "GDBController.h"
#include "InputController.h"
#include "LoadSaveState.h"
#include "LogController.h"
struct GBAOptions;
struct GBAArguments;
@ -140,6 +141,7 @@ private:
GameController* m_controller;
Display* m_display;
QList<QAction*> m_gameActions;
LogController m_log;
LogView* m_logView;
LoadSaveState* m_stateWindow;
WindowBackground* m_screenWidget;