mirror of https://github.com/mgba-emu/mgba.git
Qt: Let memory access logs be loaded read-only
This commit is contained in:
parent
7012f9c666
commit
4cc49a6700
|
@ -65,7 +65,9 @@ void MemoryAccessLogController::updateRegion(const QString& internalName, bool c
|
||||||
if (!m_active) {
|
if (!m_active) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_regionMapping[internalName] = mDebuggerAccessLoggerWatchMemoryBlockName(&m_logger, internalName.toUtf8().constData(), activeFlags());
|
if (checked && !m_regionMapping.contains(internalName)) {
|
||||||
|
m_regionMapping[internalName] = mDebuggerAccessLoggerWatchMemoryBlockName(&m_logger, internalName.toUtf8().constData(), activeFlags());
|
||||||
|
}
|
||||||
emit regionMappingChanged(internalName, checked);
|
emit regionMappingChanged(internalName, checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +76,38 @@ void MemoryAccessLogController::setFile(const QString& path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryAccessLogController::start(bool loadExisting, bool logExtra) {
|
void MemoryAccessLogController::start(bool loadExisting, bool logExtra) {
|
||||||
|
if (!m_loaded) {
|
||||||
|
load(loadExisting);
|
||||||
|
}
|
||||||
|
if (!m_loaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CoreController::Interrupter interrupter(m_controller);
|
||||||
|
mDebuggerAccessLoggerStart(&m_logger);
|
||||||
|
m_logExtra = logExtra;
|
||||||
|
|
||||||
|
m_active = true;
|
||||||
|
for (const auto& region : m_watchedRegions) {
|
||||||
|
m_regionMapping[region] = mDebuggerAccessLoggerWatchMemoryBlockName(&m_logger, region.toUtf8().constData(), activeFlags());
|
||||||
|
}
|
||||||
|
emit loggingChanged(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryAccessLogController::stop() {
|
||||||
|
if (!m_active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CoreController::Interrupter interrupter(m_controller);
|
||||||
|
mDebuggerAccessLoggerStop(&m_logger);
|
||||||
|
emit loggingChanged(false);
|
||||||
|
interrupter.resume();
|
||||||
|
m_active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryAccessLogController::load(bool loadExisting) {
|
||||||
|
if (m_loaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
int flags = O_CREAT | O_RDWR;
|
int flags = O_CREAT | O_RDWR;
|
||||||
if (!loadExisting) {
|
if (!loadExisting) {
|
||||||
flags |= O_TRUNC;
|
flags |= O_TRUNC;
|
||||||
|
@ -83,7 +117,6 @@ void MemoryAccessLogController::start(bool loadExisting, bool logExtra) {
|
||||||
LOG(QT, ERROR) << tr("Failed to open memory log file");
|
LOG(QT, ERROR) << tr("Failed to open memory log file");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_logExtra = logExtra;
|
|
||||||
|
|
||||||
mDebuggerAccessLoggerInit(&m_logger);
|
mDebuggerAccessLoggerInit(&m_logger);
|
||||||
CoreController::Interrupter interrupter(m_controller);
|
CoreController::Interrupter interrupter(m_controller);
|
||||||
|
@ -93,26 +126,22 @@ void MemoryAccessLogController::start(bool loadExisting, bool logExtra) {
|
||||||
LOG(QT, ERROR) << tr("Failed to open memory log file");
|
LOG(QT, ERROR) << tr("Failed to open memory log file");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mDebuggerAccessLoggerStart(&m_logger);
|
emit loaded(true);
|
||||||
|
m_loaded = true;
|
||||||
m_active = true;
|
|
||||||
emit loggingChanged(true);
|
|
||||||
for (const auto& region : m_watchedRegions) {
|
|
||||||
m_regionMapping[region] = mDebuggerAccessLoggerWatchMemoryBlockName(&m_logger, region.toUtf8().constData(), activeFlags());
|
|
||||||
}
|
|
||||||
interrupter.resume();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryAccessLogController::stop() {
|
void MemoryAccessLogController::unload() {
|
||||||
if (!m_active) {
|
if (m_active) {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
if (m_active) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CoreController::Interrupter interrupter(m_controller);
|
CoreController::Interrupter interrupter(m_controller);
|
||||||
m_controller->detachDebuggerModule(&m_logger.d);
|
m_controller->detachDebuggerModule(&m_logger.d);
|
||||||
mDebuggerAccessLoggerDeinit(&m_logger);
|
mDebuggerAccessLoggerDeinit(&m_logger);
|
||||||
emit loggingChanged(false);
|
emit loaded(false);
|
||||||
interrupter.resume();
|
m_loaded = false;
|
||||||
m_active = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mDebuggerAccessLogRegionFlags MemoryAccessLogController::activeFlags() const {
|
mDebuggerAccessLogRegionFlags MemoryAccessLogController::activeFlags() const {
|
||||||
|
|
|
@ -49,6 +49,7 @@ public:
|
||||||
|
|
||||||
QString file() const { return m_path; }
|
QString file() const { return m_path; }
|
||||||
bool active() const { return m_active; }
|
bool active() const { return m_active; }
|
||||||
|
bool isLoaded() const { return m_loaded; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateRegion(const QString& internalName, bool enable);
|
void updateRegion(const QString& internalName, bool enable);
|
||||||
|
@ -57,9 +58,13 @@ public slots:
|
||||||
void start(bool loadExisting, bool logExtra);
|
void start(bool loadExisting, bool logExtra);
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
void load(bool loadExisting);
|
||||||
|
void unload();
|
||||||
|
|
||||||
void exportFile(const QString& filename);
|
void exportFile(const QString& filename);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void loaded(bool loaded);
|
||||||
void loggingChanged(bool active);
|
void loggingChanged(bool active);
|
||||||
void regionMappingChanged(const QString& internalName, bool active);
|
void regionMappingChanged(const QString& internalName, bool active);
|
||||||
|
|
||||||
|
@ -71,6 +76,7 @@ private:
|
||||||
QHash<QString, int> m_regionMapping;
|
QHash<QString, int> m_regionMapping;
|
||||||
QVector<Region> m_regions;
|
QVector<Region> m_regions;
|
||||||
struct mDebuggerAccessLogger m_logger{};
|
struct mDebuggerAccessLogger m_logger{};
|
||||||
|
bool m_loaded = false;
|
||||||
bool m_active = false;
|
bool m_active = false;
|
||||||
mDebuggerAccessLogRegion* m_cachedRegion = nullptr;
|
mDebuggerAccessLogRegion* m_cachedRegion = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,10 @@ MemoryAccessLogView::MemoryAccessLogView(std::weak_ptr<MemoryAccessLogController
|
||||||
connect(m_ui.exportButton, &QAbstractButton::clicked, this, &MemoryAccessLogView::exportFile);
|
connect(m_ui.exportButton, &QAbstractButton::clicked, this, &MemoryAccessLogView::exportFile);
|
||||||
connect(controllerPtr.get(), &MemoryAccessLogController::regionMappingChanged, this, &MemoryAccessLogView::updateRegion);
|
connect(controllerPtr.get(), &MemoryAccessLogController::regionMappingChanged, this, &MemoryAccessLogView::updateRegion);
|
||||||
connect(controllerPtr.get(), &MemoryAccessLogController::loggingChanged, this, &MemoryAccessLogView::handleStartStop);
|
connect(controllerPtr.get(), &MemoryAccessLogController::loggingChanged, this, &MemoryAccessLogView::handleStartStop);
|
||||||
|
connect(controllerPtr.get(), &MemoryAccessLogController::loaded, this, &MemoryAccessLogView::handleLoadUnload);
|
||||||
|
|
||||||
bool active = controllerPtr->active();
|
bool active = controllerPtr->active();
|
||||||
|
bool loaded = controllerPtr->isLoaded();
|
||||||
auto watchedRegions = controllerPtr->watchedRegions();
|
auto watchedRegions = controllerPtr->watchedRegions();
|
||||||
|
|
||||||
QVBoxLayout* regionBox = static_cast<QVBoxLayout*>(m_ui.regionBox->layout());
|
QVBoxLayout* regionBox = static_cast<QVBoxLayout*>(m_ui.regionBox->layout());
|
||||||
|
@ -46,11 +48,14 @@ MemoryAccessLogView::MemoryAccessLogView(std::weak_ptr<MemoryAccessLogController
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleLoadUnload(loaded);
|
||||||
handleStartStop(active);
|
handleStartStop(active);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryAccessLogView::updateRegion(const QString& internalName, bool) {
|
void MemoryAccessLogView::updateRegion(const QString& internalName, bool checked) {
|
||||||
m_regionBoxes[internalName]->setEnabled(false);
|
if (checked) {
|
||||||
|
m_regionBoxes[internalName]->setEnabled(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryAccessLogView::start() {
|
void MemoryAccessLogView::start() {
|
||||||
|
@ -68,10 +73,23 @@ void MemoryAccessLogView::stop() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
controllerPtr->stop();
|
controllerPtr->stop();
|
||||||
for (const auto& region : controllerPtr->watchedRegions()) {
|
}
|
||||||
m_regionBoxes[region]->setEnabled(true);
|
|
||||||
|
void MemoryAccessLogView::load() {
|
||||||
|
std::shared_ptr<MemoryAccessLogController> controllerPtr = m_controller.lock();
|
||||||
|
if (!controllerPtr) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
m_ui.exportButton->setEnabled(false);
|
controllerPtr->setFile(m_ui.filename->text());
|
||||||
|
controllerPtr->load(m_ui.loadExisting->isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryAccessLogView::unload() {
|
||||||
|
std::shared_ptr<MemoryAccessLogController> controllerPtr = m_controller.lock();
|
||||||
|
if (!controllerPtr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
controllerPtr->unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryAccessLogView::selectFile() {
|
void MemoryAccessLogView::selectFile() {
|
||||||
|
@ -110,12 +128,26 @@ void MemoryAccessLogView::handleStartStop(bool start) {
|
||||||
m_regionBoxes[region]->setChecked(true);
|
m_regionBoxes[region]->setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (watchedRegions.contains(QString("cart0"))) {
|
|
||||||
m_ui.exportButton->setEnabled(start);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ui.start->setDisabled(start);
|
m_ui.start->setDisabled(start);
|
||||||
m_ui.stop->setEnabled(start);
|
m_ui.stop->setEnabled(start);
|
||||||
m_ui.filename->setDisabled(start);
|
m_ui.unload->setDisabled(start || !controllerPtr->isLoaded());
|
||||||
m_ui.browse->setDisabled(start);
|
}
|
||||||
|
|
||||||
|
void MemoryAccessLogView::handleLoadUnload(bool load) {
|
||||||
|
std::shared_ptr<MemoryAccessLogController> controllerPtr = m_controller.lock();
|
||||||
|
if (!controllerPtr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_ui.filename->setText(controllerPtr->file());
|
||||||
|
|
||||||
|
if (load && controllerPtr->canExport()) {
|
||||||
|
m_ui.exportButton->setEnabled(true);
|
||||||
|
} else if (!load) {
|
||||||
|
m_ui.exportButton->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ui.load->setDisabled(load);
|
||||||
|
m_ui.unload->setEnabled(load);
|
||||||
|
m_ui.filename->setDisabled(load);
|
||||||
|
m_ui.browse->setDisabled(load);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,9 +34,13 @@ private slots:
|
||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
void load();
|
||||||
|
void unload();
|
||||||
|
|
||||||
void exportFile();
|
void exportFile();
|
||||||
|
|
||||||
void handleStartStop(bool start);
|
void handleStartStop(bool start);
|
||||||
|
void handleLoadUnload(bool load);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MemoryAccessLogView m_ui;
|
Ui::MemoryAccessLogView m_ui;
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>385</width>
|
<width>311</width>
|
||||||
<height>380</height>
|
<height>387</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -22,25 +22,25 @@
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Log file</string>
|
<string>Log file</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2" columnstretch="3,1,2">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0" colspan="2">
|
||||||
<widget class="QLineEdit" name="filename"/>
|
<widget class="QLineEdit" name="filename"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="2">
|
||||||
<widget class="QPushButton" name="browse">
|
<widget class="QPushButton" name="browse">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Browse</string>
|
<string>Browse</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0" colspan="2">
|
<item row="1" column="0" colspan="3">
|
||||||
<widget class="QCheckBox" name="logExtra">
|
<widget class="QCheckBox" name="logExtra">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Log additional information (uses 3× space)</string>
|
<string>Log additional information (uses 3× space)</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" colspan="2">
|
<item row="2" column="0" colspan="3">
|
||||||
<widget class="QCheckBox" name="loadExisting">
|
<widget class="QCheckBox" name="loadExisting">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Load existing file if present</string>
|
<string>Load existing file if present</string>
|
||||||
|
@ -50,6 +50,23 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QPushButton" name="load">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1" colspan="2">
|
||||||
|
<widget class="QPushButton" name="unload">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Unload</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -124,9 +141,43 @@
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>load</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>QGBA::MemoryAccessLogView</receiver>
|
||||||
|
<slot>load()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>81</x>
|
||||||
|
<y>152</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>192</x>
|
||||||
|
<y>189</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>unload</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>QGBA::MemoryAccessLogView</receiver>
|
||||||
|
<slot>unload()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>226</x>
|
||||||
|
<y>152</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>192</x>
|
||||||
|
<y>189</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
</connections>
|
</connections>
|
||||||
<slots>
|
<slots>
|
||||||
<slot>start()</slot>
|
<slot>start()</slot>
|
||||||
<slot>stop()</slot>
|
<slot>stop()</slot>
|
||||||
|
<slot>load()</slot>
|
||||||
|
<slot>unload()</slot>
|
||||||
</slots>
|
</slots>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
Loading…
Reference in New Issue