src/platform/qt/DebuggerConsoleController.cpp (view raw)
1/* Copyright (c) 2013-2016 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 "DebuggerConsoleController.h"
7
8#include "GameController.h"
9
10#include <QMutexLocker>
11
12extern "C" {
13#include "debugger/cli-debugger.h"
14}
15
16using namespace QGBA;
17
18DebuggerConsoleController::DebuggerConsoleController(GameController* controller, QObject* parent)
19 : DebuggerController(controller, &m_cliDebugger.d, parent)
20{
21 m_backend.d.printf = printf;
22 m_backend.d.init = init;
23 m_backend.d.deinit = deinit;
24 m_backend.d.readline = readLine;
25 m_backend.d.lineAppend = lineAppend;
26 m_backend.d.historyLast = historyLast;
27 m_backend.d.historyAppend = historyAppend;
28 m_backend.self = this;
29
30 CLIDebuggerCreate(&m_cliDebugger);
31 CLIDebuggerAttachBackend(&m_cliDebugger, &m_backend.d);
32}
33
34void DebuggerConsoleController::enterLine(const QString& line) {
35 QMutexLocker lock(&m_mutex);
36 m_lines.append(line);
37 if (m_cliDebugger.d.state == DEBUGGER_RUNNING) {
38 mDebuggerEnter(&m_cliDebugger.d, DEBUGGER_ENTER_MANUAL, nullptr);
39 }
40 m_cond.wakeOne();
41}
42
43void DebuggerConsoleController::attachInternal() {
44 mCore* core = m_gameController->thread()->core;
45 CLIDebuggerAttachSystem(&m_cliDebugger, core->cliDebuggerSystem(core));
46}
47
48void DebuggerConsoleController::printf(struct CLIDebuggerBackend* be, const char* fmt, ...) {
49 Backend* consoleBe = reinterpret_cast<Backend*>(be);
50 DebuggerConsoleController* self = consoleBe->self;
51 va_list args;
52 va_start(args, fmt);
53 self->log(QString().vsprintf(fmt, args));
54 va_end(args);
55}
56
57void DebuggerConsoleController::init(struct CLIDebuggerBackend* be) {
58 Backend* consoleBe = reinterpret_cast<Backend*>(be);
59 DebuggerConsoleController* self = consoleBe->self;
60}
61
62void DebuggerConsoleController::deinit(struct CLIDebuggerBackend* be) {
63 Backend* consoleBe = reinterpret_cast<Backend*>(be);
64 DebuggerConsoleController* self = consoleBe->self;
65}
66
67const char* DebuggerConsoleController::readLine(struct CLIDebuggerBackend* be, size_t* len) {
68 Backend* consoleBe = reinterpret_cast<Backend*>(be);
69 DebuggerConsoleController* self = consoleBe->self;
70 GameController::Interrupter interrupter(self->m_gameController, true);
71 QMutexLocker lock(&self->m_mutex);
72 while (self->m_lines.isEmpty()) {
73 self->m_cond.wait(&self->m_mutex);
74 }
75 self->m_last = self->m_lines.takeFirst().toUtf8();
76 *len = self->m_last.size();
77 return self->m_last.constData();
78
79}
80
81void DebuggerConsoleController::lineAppend(struct CLIDebuggerBackend* be, const char* line) {
82 Backend* consoleBe = reinterpret_cast<Backend*>(be);
83 DebuggerConsoleController* self = consoleBe->self;
84 self->lineAppend(QString::fromUtf8(line));
85}
86
87const char* DebuggerConsoleController::historyLast(struct CLIDebuggerBackend* be, size_t* len) {
88 Backend* consoleBe = reinterpret_cast<Backend*>(be);
89 DebuggerConsoleController* self = consoleBe->self;
90 GameController::Interrupter interrupter(self->m_gameController, true);
91 QMutexLocker lock(&self->m_mutex);
92 self->m_last = self->m_history.last().toUtf8();
93 return self->m_last.constData();
94}
95
96void DebuggerConsoleController::historyAppend(struct CLIDebuggerBackend* be, const char* line) {
97 Backend* consoleBe = reinterpret_cast<Backend*>(be);
98 DebuggerConsoleController* self = consoleBe->self;
99 GameController::Interrupter interrupter(self->m_gameController, true);
100 QMutexLocker lock(&self->m_mutex);
101 self->m_history.append(QString::fromUtf8(line));
102}