src/platform/qt/LogController.cpp (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "LogController.h"
7
8#include "ConfigController.h"
9
10using namespace QGBA;
11
12LogController LogController::s_global(mLOG_ALL);
13
14LogController::LogController(int levels, QObject* parent)
15 : QObject(parent)
16{
17 mLogFilterInit(&m_filter);
18 mLogFilterSet(&m_filter, "gba.bios", mLOG_STUB | mLOG_FATAL);
19 mLogFilterSet(&m_filter, "core.status", mLOG_ALL & ~mLOG_DEBUG);
20 m_filter.defaultLevels = levels;
21
22 if (this != &s_global) {
23 connect(&s_global, &LogController::logPosted, this, &LogController::postLog);
24 connect(this, static_cast<void (LogController::*)(int)>(&LogController::levelsSet), &s_global, static_cast<void (LogController::*)(int)>(&LogController::setLevels));
25 connect(this, static_cast<void (LogController::*)(int)>(&LogController::levelsEnabled), &s_global, static_cast<void (LogController::*)(int)>(&LogController::enableLevels));
26 connect(this, static_cast<void (LogController::*)(int)>(&LogController::levelsDisabled), &s_global, static_cast<void (LogController::*)(int)>(&LogController::disableLevels));
27 }
28}
29
30LogController::~LogController() {
31 mLogFilterDeinit(&m_filter);
32}
33
34int LogController::levels(int category) const {
35 return mLogFilterLevels(&m_filter, category);
36}
37
38LogController::Stream LogController::operator()(int category, int level) {
39 return Stream(this, category, level);
40}
41
42void LogController::load(const ConfigController* config) {
43 mLogFilterLoad(&m_filter, config->config());
44 setLogFile(config->getOption("logFile"));
45 logToStdout(config->getOption("logToStdout").toInt());
46 logToFile(config->getOption("logToFile").toInt());
47}
48
49void LogController::save(ConfigController* config) const {
50 mLogFilterSave(&m_filter, config->config());
51}
52
53void LogController::postLog(int level, int category, const QString& string) {
54 if (!mLogFilterTest(&m_filter, category, static_cast<mLogLevel>(level))) {
55 return;
56 }
57 if (m_logToStdout || m_logToFile) {
58 QString line = tr("[%1] %2: %3").arg(LogController::toString(level)).arg(mLogCategoryName(category)).arg(string);
59
60 if (m_logToStdout) {
61 QTextStream out(stdout);
62 out << line << endl;
63 }
64 if (m_logToFile && m_logStream) {
65 *m_logStream << line << endl;
66 }
67 }
68 emit logPosted(level, category, string);
69}
70
71void LogController::setLevels(int levels) {
72 m_filter.defaultLevels = levels;
73 emit levelsSet(levels);
74}
75
76void LogController::enableLevels(int levels) {
77 m_filter.defaultLevels |= levels;
78 emit levelsEnabled(levels);
79}
80
81void LogController::disableLevels(int levels) {
82 m_filter.defaultLevels &= ~levels;
83 emit levelsDisabled(levels);
84}
85
86void LogController::setLevels(int levels, int category) {
87 auto id = mLogCategoryId(category);
88 mLogFilterSet(&m_filter, id, levels);
89 emit levelsSet(levels, category);
90}
91
92void LogController::enableLevels(int levels, int category) {
93 auto id = mLogCategoryId(category);
94 int newLevels = mLogFilterLevels(&m_filter, category) | levels;
95 mLogFilterSet(&m_filter, id, newLevels);
96 emit levelsEnabled(levels, category);
97}
98
99void LogController::disableLevels(int levels, int category) {
100 auto id = mLogCategoryId(category);
101 int newLevels = mLogFilterLevels(&m_filter, category) & ~levels;
102 mLogFilterSet(&m_filter, id, newLevels);
103 emit levelsDisabled(levels, category);
104}
105
106void LogController::clearLevels(int category) {
107 auto id = mLogCategoryId(category);
108 mLogFilterReset (&m_filter, id);
109}
110
111void LogController::logToFile(bool log) {
112 m_logToFile = log;
113}
114
115void LogController::logToStdout(bool log) {
116 m_logToStdout = log;
117}
118
119void LogController::setLogFile(const QString& file) {
120 m_logStream.reset();
121 m_logFile = std::make_unique<QFile>(file);
122 m_logFile->open(QIODevice::Append | QIODevice::Text);
123 m_logStream = std::make_unique<QTextStream>(m_logFile.get());
124}
125
126LogController* LogController::global() {
127 return &s_global;
128}
129
130QString LogController::toString(int level) {
131 switch (level) {
132 case mLOG_DEBUG:
133 return tr("DEBUG");
134 case mLOG_STUB:
135 return tr("STUB");
136 case mLOG_INFO:
137 return tr("INFO");
138 case mLOG_WARN:
139 return tr("WARN");
140 case mLOG_ERROR:
141 return tr("ERROR");
142 case mLOG_FATAL:
143 return tr("FATAL");
144 case mLOG_GAME_ERROR:
145 return tr("GAME ERROR");
146 }
147 return QString();
148}
149
150LogController::Stream::Stream(LogController* controller, int level, int category)
151 : m_level(level)
152 , m_category(category)
153 , m_log(controller)
154{
155}
156
157LogController::Stream::~Stream() {
158 m_log->postLog(m_level, m_category, m_queue.join(" "));
159}
160
161LogController::Stream& LogController::Stream::operator<<(const QString& string) {
162 m_queue.append(string);
163 return *this;
164}