summaryrefslogtreecommitdiff
path: root/Source/Core/DolphinQt/Debugger/BranchWatchTableModel.h
blob: c1cfca2415422f5429627c4b0fb636602a1bac6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright 2024 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <cstdio>

#include <QAbstractTableModel>
#include <QFont>
#include <QList>
#include <QVariant>

#include "Common/SymbolDB.h"

namespace Core
{
class BranchWatch;
enum class BranchWatchSelectionInspection : u8;
struct BranchWatchSelectionValueType;
class CPUThreadGuard;
class System;
}  // namespace Core
class PPCSymbolDB;

namespace BranchWatchTableModelColumn
{
enum EnumType : int
{
  Instruction = 0,
  Condition,
  Origin,
  Destination,
  RecentHits,
  TotalHits,
  OriginSymbol,
  DestinSymbol,
  NumberOfColumns,
};
}

namespace BranchWatchTableModelUserRole
{
enum EnumType : int
{
  ClickRole = Qt::UserRole,
  SortRole,
};
}

struct BranchWatchTableModelSymbolListValueType
{
  explicit BranchWatchTableModelSymbolListValueType(const Common::Symbol* const origin_symbol,
                                                    const Common::Symbol* const destin_symbol)
      : origin_name(origin_symbol ? QString::fromStdString(origin_symbol->name) : QVariant{}),
        origin_addr(origin_symbol ? origin_symbol->address : QVariant{}),
        destin_name(destin_symbol ? QString::fromStdString(destin_symbol->name) : QVariant{}),
        destin_addr(destin_symbol ? destin_symbol->address : QVariant{})
  {
  }
  QVariant origin_name, origin_addr;
  QVariant destin_name, destin_addr;
};

class BranchWatchTableModel final : public QAbstractTableModel
{
  Q_OBJECT

public:
  using Column = BranchWatchTableModelColumn::EnumType;
  using UserRole = BranchWatchTableModelUserRole::EnumType;
  using SymbolListValueType = BranchWatchTableModelSymbolListValueType;
  using SymbolList = QList<SymbolListValueType>;

  explicit BranchWatchTableModel(Core::System& system, Core::BranchWatch& branch_watch,
                                 PPCSymbolDB& ppc_symbol_db, QObject* parent = nullptr)
      : QAbstractTableModel(parent), m_system(system), m_branch_watch(branch_watch),
        m_ppc_symbol_db(ppc_symbol_db)
  {
  }
  ~BranchWatchTableModel() override = default;

  BranchWatchTableModel(const BranchWatchTableModel&) = delete;
  BranchWatchTableModel(BranchWatchTableModel&&) = delete;
  BranchWatchTableModel& operator=(const BranchWatchTableModel&) = delete;
  BranchWatchTableModel& operator=(BranchWatchTableModel&&) = delete;

  QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
  QVariant headerData(int section, Qt::Orientation orientation,
                      int role = Qt::DisplayRole) const override;
  int rowCount(const QModelIndex& parent = QModelIndex{}) const override;
  int columnCount(const QModelIndex& parent = QModelIndex{}) const override;
  bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex{}) override;
  void setFont(const QFont& font) { m_font = font; }

  void OnClearBranchWatch(const Core::CPUThreadGuard& guard);
  void OnCodePathWasTaken(const Core::CPUThreadGuard& guard);
  void OnCodePathNotTaken(const Core::CPUThreadGuard& guard);
  void OnBranchWasOverwritten(const Core::CPUThreadGuard& guard);
  void OnBranchNotOverwritten(const Core::CPUThreadGuard& guard);
  void OnWipeRecentHits();
  void OnWipeInspection();
  void OnDebugFontChanged(const QFont& font);
  void OnPPCSymbolsChanged();

  void Save(const Core::CPUThreadGuard& guard, std::FILE* file) const;
  void Load(const Core::CPUThreadGuard& guard, std::FILE* file);
  void UpdateSymbols();
  void UpdateHits();
  void SetInspected(const QModelIndex& index);

  const Core::BranchWatchSelectionValueType&
  GetBranchWatchSelection(const QModelIndex& index) const;
  const SymbolList& GetSymbolList() const { return m_symbol_list; }

private:
  void SetInspected(const QModelIndex& index, Core::BranchWatchSelectionInspection inspection);
  void SetOriginInspected(u32 origin_addr);
  void SetDestinInspected(u32 destin_addr, bool nested);
  void SetSymbolInspected(u32 symbol_addr, bool nested);
  void PrefetchSymbols();

  [[nodiscard]] QVariant DisplayRoleData(const QModelIndex& index) const;
  [[nodiscard]] QVariant FontRoleData(const QModelIndex& index) const;
  [[nodiscard]] QVariant TextAlignmentRoleData(const QModelIndex& index) const;
  [[nodiscard]] QVariant ForegroundRoleData(const QModelIndex& index) const;
  [[nodiscard]] QVariant ClickRoleData(const QModelIndex& index) const;
  [[nodiscard]] QVariant SortRoleData(const QModelIndex& index) const;

  Core::System& m_system;
  Core::BranchWatch& m_branch_watch;
  PPCSymbolDB& m_ppc_symbol_db;

  SymbolList m_symbol_list;
  mutable QFont m_font;
};