50 changes: 49 additions & 1 deletion Source/Core/DolphinQt/CheatsManager.cpp
Expand Up @@ -19,8 +19,10 @@
#include "DolphinQt/CheatSearchWidget.h"
#include "DolphinQt/Config/ARCodeWidget.h"
#include "DolphinQt/Config/GeckoCodeWidget.h"
#include "DolphinQt/QtUtils/PartiallyClosableTabWidget.h"
#include "DolphinQt/Settings.h"
#include "QtUtils/PartiallyClosableTabWidget.h"

#include "VideoCommon/VideoEvents.h"

CheatsManager::CheatsManager(QWidget* parent) : QDialog(parent)
{
Expand Down Expand Up @@ -48,6 +50,52 @@ CheatsManager::~CheatsManager()
void CheatsManager::OnStateChanged(Core::State state)
{
RefreshCodeTabs(state, false);
if (state == Core::State::Paused)
UpdateAllCheatSearchWidgetCurrentValues();
}

void CheatsManager::OnFrameEnd()
{
if (!isVisible())
return;

auto* const selected_cheat_search_widget =
qobject_cast<CheatSearchWidget*>(m_tab_widget->currentWidget());
if (selected_cheat_search_widget != nullptr)
{
selected_cheat_search_widget->UpdateTableVisibleCurrentValues(
CheatSearchWidget::UpdateSource::Auto);
}
}

void CheatsManager::UpdateAllCheatSearchWidgetCurrentValues()
{
for (int i = 0; i < m_tab_widget->count(); ++i)
{
auto* const cheat_search_widget = qobject_cast<CheatSearchWidget*>(m_tab_widget->widget(i));
if (cheat_search_widget != nullptr)
cheat_search_widget->UpdateTableAllCurrentValues(CheatSearchWidget::UpdateSource::Auto);
}
}

void CheatsManager::RegisterAfterFrameEventCallback()
{
m_VI_end_field_event = VIEndFieldEvent::Register([this] { OnFrameEnd(); }, "CheatsManager");
}

void CheatsManager::RemoveAfterFrameEventCallback()
{
m_VI_end_field_event.reset();
}

void CheatsManager::hideEvent(QHideEvent* event)
{
RemoveAfterFrameEventCallback();
}

void CheatsManager::showEvent(QShowEvent* event)
{
RegisterAfterFrameEventCallback();
}

void CheatsManager::RefreshCodeTabs(Core::State state, bool force)
Expand Down
16 changes: 14 additions & 2 deletions Source/Core/DolphinQt/CheatsManager.h
Expand Up @@ -11,14 +11,16 @@
#include <QDialog>

#include "Common/CommonTypes.h"
#include "DolphinQt/GameList/GameListModel.h"

#include "Core/CheatSearch.h"
#include "DolphinQt/GameList/GameListModel.h"
#include "VideoCommon/VideoEvents.h"

class ARCodeWidget;
class GeckoCodeWidget;
class CheatSearchFactoryWidget;
class QDialogButtonBox;
class QHideEvent;
class QShowEvent;
class PartiallyClosableTabWidget;

namespace Core
Expand All @@ -38,14 +40,22 @@ class CheatsManager : public QDialog
void ShowMemory(u32 address);
void RequestWatch(QString name, u32 address);

protected:
void hideEvent(QHideEvent* event) override;
void showEvent(QShowEvent* event) override;

private:
void CreateWidgets();
void ConnectWidgets();
void OnStateChanged(Core::State state);
void OnFrameEnd();
void RegisterAfterFrameEventCallback();
void RemoveAfterFrameEventCallback();
void OnNewSessionCreated(const Cheats::CheatSearchSessionBase& session);
void OnTabCloseRequested(int index);

void RefreshCodeTabs(Core::State state, bool force);
void UpdateAllCheatSearchWidgetCurrentValues();

std::string m_game_id;
std::string m_game_tdb_id;
Expand All @@ -57,4 +67,6 @@ class CheatsManager : public QDialog
ARCodeWidget* m_ar_code = nullptr;
GeckoCodeWidget* m_gecko_code = nullptr;
CheatSearchFactoryWidget* m_cheat_search_new = nullptr;

Common::EventHook m_VI_end_field_event;
};
3 changes: 3 additions & 0 deletions Source/Core/VideoCommon/VideoEvents.h
Expand Up @@ -81,3 +81,6 @@ using BeforePresentEvent = Common::HookableEvent<"BeforePresent", PresentInfo&>;
// An event that is triggered after a frame is presented.
// The exact timing of this event depends on backend/driver support.
using AfterPresentEvent = Common::HookableEvent<"AfterPresent", PresentInfo&>;

// An end of frame event that runs on the CPU thread
using VIEndFieldEvent = Common::HookableEvent<"VIEndField">;