MemoryViewWidget: Add OnFrameEnd callback to auto-update memory while a game is running.

This commit is contained in:
TryTwo 2024-06-24 14:18:41 -07:00
parent 3edb5accca
commit 32e135e6a9
4 changed files with 56 additions and 1 deletions

View File

@ -311,7 +311,12 @@ constexpr int GetCharacterCount(MemoryViewWidget::Type type)
void MemoryViewWidget::UpdateDispatcher(UpdateType type) void MemoryViewWidget::UpdateDispatcher(UpdateType type)
{ {
if (!isVisible()) std::unique_lock lock(m_updating, std::defer_lock);
// A full update may change parameters like row count, so make sure it goes through.
if (type == UpdateType::Full)
lock.lock();
else if (!isVisible() || !lock.try_lock())
return; return;
// Check if table needs to be created. // Check if table needs to be created.
@ -331,6 +336,10 @@ void MemoryViewWidget::UpdateDispatcher(UpdateType type)
GetValues(); GetValues();
UpdateColumns(); UpdateColumns();
break; break;
case UpdateType::Auto:
// Values were captured on CPU thread while doing a callback.
if (m_values.size() != 0)
UpdateColumns();
default: default:
break; break;
} }
@ -522,6 +531,18 @@ void MemoryViewWidget::UpdateColumns()
} }
} }
// Always runs on CPU thread from a callback.
void MemoryViewWidget::UpdateOnFrameEnd()
{
std::unique_lock lock(m_updating, std::try_to_lock);
if (lock)
{
GetValues();
// Should not directly trigger widget updates on a cpu thread. Signal main thread to do it.
emit AutoUpdate();
}
}
void MemoryViewWidget::GetValues() void MemoryViewWidget::GetValues()
{ {
m_values.clear(); m_values.clear();

View File

@ -84,6 +84,7 @@ public:
void CreateTable(); void CreateTable();
void UpdateDispatcher(UpdateType type = UpdateType::Addresses); void UpdateDispatcher(UpdateType type = UpdateType::Addresses);
void Update(); void Update();
void UpdateOnFrameEnd();
void GetValues(); void GetValues();
void UpdateFont(const QFont& font); void UpdateFont(const QFont& font);
void ToggleBreakpoint(u32 addr, bool row); void ToggleBreakpoint(u32 addr, bool row);
@ -99,6 +100,7 @@ public:
void SetBPLoggingEnabled(bool enabled); void SetBPLoggingEnabled(bool enabled);
signals: signals:
void AutoUpdate();
void ShowCode(u32 address); void ShowCode(u32 address);
void RequestWatch(QString name, u32 address); void RequestWatch(QString name, u32 address);
@ -131,6 +133,7 @@ private:
int m_alignment = 16; int m_alignment = 16;
int m_data_columns; int m_data_columns;
bool m_dual_view = false; bool m_dual_view = false;
std::mutex m_updating;
QColor m_highlight_color = QColor(120, 255, 255, 100); QColor m_highlight_color = QColor(120, 255, 255, 100);
friend class MemoryViewTable; friend class MemoryViewTable;

View File

@ -340,13 +340,38 @@ void MemoryWidget::ConnectWidgets()
void MemoryWidget::closeEvent(QCloseEvent*) void MemoryWidget::closeEvent(QCloseEvent*)
{ {
Settings::Instance().SetMemoryVisible(false); Settings::Instance().SetMemoryVisible(false);
RemoveAfterFrameEventCallback();
} }
void MemoryWidget::showEvent(QShowEvent* event) void MemoryWidget::showEvent(QShowEvent* event)
{ {
RegisterAfterFrameEventCallback();
Update(); 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()
{
if (!isVisible())
return;
m_memory_view->UpdateOnFrameEnd();
}
void MemoryWidget::Update() void MemoryWidget::Update()
{ {
if (!isVisible()) if (!isVisible())

View File

@ -9,6 +9,7 @@
#include <QDockWidget> #include <QDockWidget>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "VideoCommon/VideoEvents.h"
class MemoryViewWidget; class MemoryViewWidget;
class QCheckBox; class QCheckBox;
@ -76,7 +77,11 @@ private:
void FindValue(bool next); void FindValue(bool next);
void closeEvent(QCloseEvent*) override; void closeEvent(QCloseEvent*) override;
void hideEvent(QHideEvent* event) override;
void showEvent(QShowEvent* event) override; void showEvent(QShowEvent* event) override;
void RegisterAfterFrameEventCallback();
void RemoveAfterFrameEventCallback();
void AutoUpdateTable();
Core::System& m_system; Core::System& m_system;
@ -109,4 +114,5 @@ private:
QRadioButton* m_bp_read_only; QRadioButton* m_bp_read_only;
QRadioButton* m_bp_write_only; QRadioButton* m_bp_write_only;
QCheckBox* m_bp_log_check; QCheckBox* m_bp_log_check;
Common::EventHook m_vi_end_field_event;
}; };