all repos — mgba @ 9a0561e9c2fe3ccade7a97477f49cfcff70ac34a

mGBA Game Boy Advance Emulator

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