yaze 0.2.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
transaction.h
Go to the documentation of this file.
1// Transaction helper for atomic ROM operations with rollback
2//
3// Usage:
4// yaze::Transaction tx(rom);
5// auto status = tx.WriteByte(addr, val)
6// .WriteWord(addr2, val2)
7// .Commit();
8//
9// If any write fails before Commit, subsequent operations are skipped and
10// Commit() will Rollback() previously applied writes in reverse order.
11
12#include <variant>
13#include <vector>
14
15#include "absl/status/status.h"
16#include "app/gfx/snes_color.h"
17#include "app/rom.h"
18
19namespace yaze {
20
22 public:
23 explicit Transaction(Rom &rom) : rom_(rom) {}
24
25 Transaction &WriteByte(int address, uint8_t value) {
26 if (!status_.ok()) return *this;
27 auto original = rom_.ReadByte(address);
28 if (!original.ok()) {
29 status_ = original.status();
30 return *this;
31 }
32 status_ = rom_.WriteByte(address, value);
33 if (status_.ok()) {
34 operations_.push_back({address, static_cast<uint8_t>(*original), OperationType::kWriteByte});
35 }
36 return *this;
37 }
38
39 Transaction &WriteWord(int address, uint16_t value) {
40 if (!status_.ok()) return *this;
41 auto original = rom_.ReadWord(address);
42 if (!original.ok()) {
43 status_ = original.status();
44 return *this;
45 }
46 status_ = rom_.WriteWord(address, value);
47 if (status_.ok()) {
48 operations_.push_back({address, static_cast<uint16_t>(*original), OperationType::kWriteWord});
49 }
50 return *this;
51 }
52
53 Transaction &WriteLong(int address, uint32_t value) {
54 if (!status_.ok()) return *this;
55 auto original = rom_.ReadLong(address);
56 if (!original.ok()) {
57 status_ = original.status();
58 return *this;
59 }
60 status_ = rom_.WriteLong(address, value);
61 if (status_.ok()) {
62 operations_.push_back({address, static_cast<uint32_t>(*original), OperationType::kWriteLong});
63 }
64 return *this;
65 }
66
67 Transaction &WriteVector(int address, const std::vector<uint8_t> &data) {
68 if (!status_.ok()) return *this;
69 auto original = rom_.ReadByteVector(address, static_cast<uint32_t>(data.size()));
70 if (!original.ok()) {
71 status_ = original.status();
72 return *this;
73 }
74 status_ = rom_.WriteVector(address, data);
75 if (status_.ok()) {
76 operations_.push_back({address, *original, OperationType::kWriteVector});
77 }
78 return *this;
79 }
80
81 Transaction &WriteColor(int address, const gfx::SnesColor &color) {
82 if (!status_.ok()) return *this;
83 // Store original raw 16-bit value for rollback via WriteWord.
84 auto original_word = rom_.ReadWord(address);
85 if (!original_word.ok()) {
86 status_ = original_word.status();
87 return *this;
88 }
89 status_ = rom_.WriteColor(address, color);
90 if (status_.ok()) {
91 operations_.push_back({address, static_cast<uint16_t>(*original_word), OperationType::kWriteColor});
92 }
93 return *this;
94 }
95
96 absl::Status Commit() {
97 if (!status_.ok()) {
98 Rollback();
99 }
100 return status_;
101 }
102
103 void Rollback() {
104 for (auto it = operations_.rbegin(); it != operations_.rend(); ++it) {
105 const auto &op = *it;
106 switch (op.type) {
108 (void)rom_.WriteByte(op.address, std::get<uint8_t>(op.original_value));
109 break;
111 (void)rom_.WriteWord(op.address, std::get<uint16_t>(op.original_value));
112 break;
114 (void)rom_.WriteLong(op.address, std::get<uint32_t>(op.original_value));
115 break;
117 (void)rom_.WriteVector(op.address, std::get<std::vector<uint8_t>>(op.original_value));
118 break;
120 (void)rom_.WriteWord(op.address, std::get<uint16_t>(op.original_value));
121 break;
122 }
123 }
124 operations_.clear();
125 }
126
127 private:
129
130 struct Operation {
132 std::variant<uint8_t, uint16_t, uint32_t, std::vector<uint8_t>> original_value;
134 };
135
137 absl::Status status_;
138 std::vector<Operation> operations_;
139};
140
141} // namespace yaze
The Rom class is used to load, save, and modify Rom data.
Definition rom.h:57
Transaction(Rom &rom)
Definition transaction.h:23
Transaction & WriteVector(int address, const std::vector< uint8_t > &data)
Definition transaction.h:67
std::vector< Operation > operations_
Transaction & WriteLong(int address, uint32_t value)
Definition transaction.h:53
Transaction & WriteWord(int address, uint16_t value)
Definition transaction.h:39
absl::Status Commit()
Definition transaction.h:96
Transaction & WriteByte(int address, uint8_t value)
Definition transaction.h:25
absl::Status status_
Transaction & WriteColor(int address, const gfx::SnesColor &color)
Definition transaction.h:81
SNES Color container.
Definition snes_color.h:38
Main namespace for the application.
Definition controller.cc:12
std::variant< uint8_t, uint16_t, uint32_t, std::vector< uint8_t > > original_value