mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge pull request #11261 from TryTwo/PR_MemoryView_Auto_Update
MemoryView auto-update while running and color recently changed cells.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
#include <mutex>
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QWidget>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
@@ -22,6 +24,21 @@ class CPUThreadGuard;
|
||||
class System;
|
||||
} // namespace Core
|
||||
|
||||
// Captures direct editing of the table.
|
||||
class TableEditDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TableEditDelegate(QObject* parent) : QStyledItemDelegate(parent) {}
|
||||
|
||||
void setModelData(QWidget* editor, QAbstractItemModel* model,
|
||||
const QModelIndex& index) const override;
|
||||
|
||||
signals:
|
||||
void editFinished(const int row, const int column, const QString& text) const;
|
||||
};
|
||||
|
||||
class MemoryViewTable;
|
||||
|
||||
class MemoryViewWidget final : public QWidget
|
||||
@@ -54,10 +71,21 @@ public:
|
||||
WriteOnly
|
||||
};
|
||||
|
||||
enum class UpdateType
|
||||
{
|
||||
Full,
|
||||
Addresses,
|
||||
Values,
|
||||
Auto,
|
||||
};
|
||||
|
||||
explicit MemoryViewWidget(Core::System& system, QWidget* parent = nullptr);
|
||||
|
||||
void CreateTable();
|
||||
void UpdateDispatcher(UpdateType type = UpdateType::Addresses);
|
||||
void Update();
|
||||
void UpdateOnFrameEnd();
|
||||
void GetValues();
|
||||
void UpdateFont(const QFont& font);
|
||||
void ToggleBreakpoint(u32 addr, bool row);
|
||||
|
||||
@@ -65,6 +93,8 @@ public:
|
||||
void SetAddressSpace(AddressSpace::Type address_space);
|
||||
AddressSpace::Type GetAddressSpace() const;
|
||||
void SetDisplay(Type type, int bytes_per_row, int alignment, bool dual_view);
|
||||
void ToggleHighlights(bool enabled);
|
||||
void SetHighlightColor();
|
||||
void SetBPType(BPType type);
|
||||
void SetAddress(u32 address);
|
||||
void SetFocus() const;
|
||||
@@ -72,6 +102,7 @@ public:
|
||||
void SetBPLoggingEnabled(bool enabled);
|
||||
|
||||
signals:
|
||||
void AutoUpdate();
|
||||
void ShowCode(u32 address);
|
||||
void RequestWatch(QString name, u32 address);
|
||||
|
||||
@@ -81,10 +112,9 @@ private:
|
||||
void OnCopyHex(u32 addr);
|
||||
void UpdateBreakpointTags();
|
||||
void UpdateColumns();
|
||||
void UpdateColumns(const Core::CPUThreadGuard* guard);
|
||||
void ScrollbarActionTriggered(int action);
|
||||
void ScrollbarSliderReleased();
|
||||
QString ValueToString(const Core::CPUThreadGuard& guard, u32 address, Type type);
|
||||
std::optional<QString> ValueToString(const Core::CPUThreadGuard& guard, u32 address, Type type);
|
||||
|
||||
Core::System& m_system;
|
||||
|
||||
@@ -95,6 +125,9 @@ private:
|
||||
BPType m_bp_type = BPType::ReadWrite;
|
||||
bool m_do_log = true;
|
||||
u32 m_address = 0x80000000;
|
||||
std::pair<u32, u32> m_address_range;
|
||||
std::map<u32, std::optional<QString>> m_values;
|
||||
std::map<u32, std::optional<QString>> m_values_dual_view;
|
||||
u32 m_address_highlight = 0;
|
||||
int m_font_width = 0;
|
||||
int m_font_vspace = 0;
|
||||
@@ -102,6 +135,8 @@ private:
|
||||
int m_alignment = 16;
|
||||
int m_data_columns;
|
||||
bool m_dual_view = false;
|
||||
std::mutex m_updating;
|
||||
QColor m_highlight_color = QColor(120, 255, 255, 100);
|
||||
|
||||
friend class MemoryViewTable;
|
||||
};
|
||||
|
||||
@@ -66,9 +66,13 @@ MemoryWidget::MemoryWidget(Core::System& system, QWidget* parent)
|
||||
connect(&Settings::Instance(), &Settings::DebugModeToggled, this,
|
||||
[this](bool enabled) { setHidden(!enabled || !Settings::Instance().IsMemoryVisible()); });
|
||||
|
||||
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, &MemoryWidget::Update);
|
||||
connect(Host::GetInstance(), &Host::UpdateDisasmDialog, this, &MemoryWidget::Update);
|
||||
|
||||
connect(this, &QDockWidget::visibilityChanged, this, [this](bool visible) {
|
||||
// Stop auto-update if MemoryView is tabbed out.
|
||||
if (visible && m_auto_update_enabled)
|
||||
RegisterAfterFrameEventCallback();
|
||||
else
|
||||
RemoveAfterFrameEventCallback();
|
||||
});
|
||||
LoadSettings();
|
||||
|
||||
ConnectWidgets();
|
||||
@@ -250,12 +254,34 @@ void MemoryWidget::CreateWidgets()
|
||||
// Sidebar top menu
|
||||
QMenuBar* menubar = new QMenuBar(sidebar);
|
||||
menubar->setNativeMenuBar(false);
|
||||
QMenu* menu_views = new QMenu(tr("&View"), menubar);
|
||||
menubar->addMenu(menu_views);
|
||||
|
||||
QMenu* menu_import = new QMenu(tr("&Import"), menubar);
|
||||
menu_import->addAction(tr("&Load file to current address"), this,
|
||||
&MemoryWidget::OnSetValueFromFile);
|
||||
menubar->addMenu(menu_import);
|
||||
|
||||
auto* auto_update_action =
|
||||
menu_views->addAction(tr("Auto update memory values"), this, [this](bool checked) {
|
||||
m_auto_update_enabled = checked;
|
||||
if (checked)
|
||||
RegisterAfterFrameEventCallback();
|
||||
else
|
||||
RemoveAfterFrameEventCallback();
|
||||
});
|
||||
auto_update_action->setCheckable(true);
|
||||
auto_update_action->setChecked(true);
|
||||
|
||||
auto* highlight_update_action =
|
||||
menu_views->addAction(tr("Highlight recently changed values"), this,
|
||||
[this](bool checked) { m_memory_view->ToggleHighlights(checked); });
|
||||
highlight_update_action->setCheckable(true);
|
||||
highlight_update_action->setChecked(true);
|
||||
|
||||
menu_views->addAction(tr("Highlight color"), this,
|
||||
[this] { m_memory_view->SetHighlightColor(); });
|
||||
|
||||
QMenu* menu_export = new QMenu(tr("&Export"), menubar);
|
||||
menu_export->addAction(tr("Dump &MRAM"), this, &MemoryWidget::OnDumpMRAM);
|
||||
menu_export->addAction(tr("Dump &ExRAM"), this, &MemoryWidget::OnDumpExRAM);
|
||||
@@ -340,19 +366,43 @@ void MemoryWidget::ConnectWidgets()
|
||||
void MemoryWidget::closeEvent(QCloseEvent*)
|
||||
{
|
||||
Settings::Instance().SetMemoryVisible(false);
|
||||
RemoveAfterFrameEventCallback();
|
||||
}
|
||||
|
||||
void MemoryWidget::showEvent(QShowEvent* event)
|
||||
{
|
||||
if (m_auto_update_enabled)
|
||||
RegisterAfterFrameEventCallback();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
void MemoryWidget::hideEvent(QHideEvent* event)
|
||||
{
|
||||
RemoveAfterFrameEventCallback();
|
||||
}
|
||||
|
||||
void MemoryWidget::RegisterAfterFrameEventCallback()
|
||||
{
|
||||
m_vi_end_field_event = VIEndFieldEvent::Register([this] { AutoUpdateTable(); }, "MemoryWidget");
|
||||
}
|
||||
|
||||
void MemoryWidget::RemoveAfterFrameEventCallback()
|
||||
{
|
||||
m_vi_end_field_event.reset();
|
||||
}
|
||||
|
||||
void MemoryWidget::AutoUpdateTable()
|
||||
{
|
||||
m_memory_view->UpdateOnFrameEnd();
|
||||
}
|
||||
|
||||
void MemoryWidget::Update()
|
||||
{
|
||||
if (!isVisible())
|
||||
return;
|
||||
|
||||
m_memory_view->Update();
|
||||
m_memory_view->UpdateDispatcher(MemoryViewWidget::UpdateType::Addresses);
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <QDockWidget>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "VideoCommon/VideoEvents.h"
|
||||
|
||||
class MemoryViewWidget;
|
||||
class QCheckBox;
|
||||
@@ -76,7 +77,11 @@ private:
|
||||
void FindValue(bool next);
|
||||
|
||||
void closeEvent(QCloseEvent*) override;
|
||||
void hideEvent(QHideEvent* event) override;
|
||||
void showEvent(QShowEvent* event) override;
|
||||
void RegisterAfterFrameEventCallback();
|
||||
void RemoveAfterFrameEventCallback();
|
||||
void AutoUpdateTable();
|
||||
|
||||
Core::System& m_system;
|
||||
|
||||
@@ -109,4 +114,7 @@ private:
|
||||
QRadioButton* m_bp_read_only;
|
||||
QRadioButton* m_bp_write_only;
|
||||
QCheckBox* m_bp_log_check;
|
||||
Common::EventHook m_vi_end_field_event;
|
||||
|
||||
bool m_auto_update_enabled = true;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user