Refactor message handling: replace TextElement return type with std::optional for better nullability handling
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "message_data.h"
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "util/hex.h"
|
||||
@@ -24,17 +25,16 @@ uint8_t FindDictionaryEntry(uint8_t value) {
|
||||
return value - DICTOFF;
|
||||
}
|
||||
|
||||
TextElement FindMatchingCommand(uint8_t b) {
|
||||
TextElement empty_element;
|
||||
std::optional<TextElement> FindMatchingCommand(uint8_t b) {
|
||||
for (const auto &text_element : TextCommands) {
|
||||
if (text_element.ID == b) {
|
||||
return text_element;
|
||||
}
|
||||
}
|
||||
return empty_element;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
TextElement FindMatchingSpecial(uint8_t value) {
|
||||
std::optional<TextElement> FindMatchingSpecial(uint8_t value) {
|
||||
auto it = std::find_if(SpecialChars.begin(), SpecialChars.end(),
|
||||
[value](const TextElement &text_element) {
|
||||
return text_element.ID == value;
|
||||
@@ -42,8 +42,7 @@ TextElement FindMatchingSpecial(uint8_t value) {
|
||||
if (it != SpecialChars.end()) {
|
||||
return *it;
|
||||
}
|
||||
|
||||
return TextElement();
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
ParsedElement FindMatchingElement(const std::string &str) {
|
||||
@@ -80,15 +79,15 @@ std::string ParseTextDataByte(uint8_t value) {
|
||||
}
|
||||
|
||||
// Check for command.
|
||||
TextElement text_element = FindMatchingCommand(value);
|
||||
if (!text_element.Empty()) {
|
||||
return text_element.GenericToken;
|
||||
auto text_element = FindMatchingCommand(value);
|
||||
if (text_element != std::nullopt) {
|
||||
return text_element->GenericToken;
|
||||
}
|
||||
|
||||
// Check for special characters.
|
||||
text_element = FindMatchingSpecial(value);
|
||||
if (!text_element.Empty()) {
|
||||
return text_element.GenericToken;
|
||||
auto special_element = FindMatchingSpecial(value);
|
||||
if (special_element != std::nullopt) {
|
||||
return text_element->GenericToken;
|
||||
}
|
||||
|
||||
// Check for dictionary.
|
||||
@@ -214,10 +213,10 @@ absl::StatusOr<MessageData> ParseSingleMessage(
|
||||
temp_bytes_raw.push_back(current_byte);
|
||||
|
||||
// Check for command.
|
||||
TextElement text_element = FindMatchingCommand(current_byte);
|
||||
if (!text_element.Empty()) {
|
||||
current_message_raw.append(text_element.GetParamToken());
|
||||
current_message_parsed.append(text_element.GetParamToken());
|
||||
auto text_element = FindMatchingCommand(current_byte);
|
||||
if (text_element != std::nullopt) {
|
||||
current_message_raw.append(text_element->GetParamToken());
|
||||
current_message_parsed.append(text_element->GetParamToken());
|
||||
temp_bytes_parsed.push_back(current_byte);
|
||||
continue;
|
||||
}
|
||||
@@ -283,12 +282,12 @@ std::vector<std::string> ParseMessageData(
|
||||
}
|
||||
} else {
|
||||
auto text_element = FindMatchingCommand(byte);
|
||||
if (!text_element.Empty()) {
|
||||
if (text_element.ID == kScrollVertical ||
|
||||
text_element.ID == kLine2 || text_element.ID == kLine3) {
|
||||
if (text_element != std::nullopt) {
|
||||
if (text_element->ID == kScrollVertical ||
|
||||
text_element->ID == kLine2 || text_element->ID == kLine3) {
|
||||
parsed_message.append("\n");
|
||||
}
|
||||
parsed_message.append(text_element.GenericToken);
|
||||
parsed_message.append(text_element->GenericToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,7 +256,7 @@ static const std::vector<TextElement> TextCommands = {
|
||||
TextElement(0x70, "NONO", false, kCrash),
|
||||
};
|
||||
|
||||
TextElement FindMatchingCommand(uint8_t b);
|
||||
std::optional<TextElement> FindMatchingCommand(uint8_t b);
|
||||
|
||||
static const std::vector<TextElement> SpecialChars = {
|
||||
TextElement(0x43, "...", false, "Ellipsis …"),
|
||||
@@ -282,7 +282,7 @@ static const std::vector<TextElement> SpecialChars = {
|
||||
TextElement(0x4B, "LFR", false, "Link face right"),
|
||||
};
|
||||
|
||||
TextElement FindMatchingSpecial(uint8_t b);
|
||||
std::optional<TextElement> FindMatchingSpecial(uint8_t b);
|
||||
|
||||
struct ParsedElement {
|
||||
TextElement Parent;
|
||||
|
||||
@@ -261,23 +261,25 @@ void MessageEditor::ReadAllTextDataV2() {
|
||||
current_raw_message.clear();
|
||||
current_parsed_message.clear();
|
||||
continue;
|
||||
} else if (current_byte == 0xFF) {
|
||||
break;
|
||||
}
|
||||
|
||||
raw_message.push_back(current_byte);
|
||||
|
||||
TextElement text_element = FindMatchingCommand(current_byte);
|
||||
if (!text_element.Empty()) {
|
||||
auto text_element = FindMatchingCommand(current_byte);
|
||||
if (text_element != std::nullopt) {
|
||||
parsed_message.push_back(current_byte);
|
||||
if (text_element.HasArgument) {
|
||||
if (text_element->HasArgument) {
|
||||
current_byte = rom()->data()[pos++];
|
||||
raw_message.push_back(current_byte);
|
||||
parsed_message.push_back(current_byte);
|
||||
}
|
||||
|
||||
current_raw_message.append(text_element.GetParamToken(current_byte));
|
||||
current_parsed_message.append(text_element.GetParamToken(current_byte));
|
||||
current_raw_message.append(text_element->GetParamToken(current_byte));
|
||||
current_parsed_message.append(text_element->GetParamToken(current_byte));
|
||||
|
||||
if (text_element.Token == kBankToken) {
|
||||
if (text_element->Token == kBankToken) {
|
||||
pos = kTextData2;
|
||||
}
|
||||
|
||||
@@ -285,10 +287,10 @@ void MessageEditor::ReadAllTextDataV2() {
|
||||
}
|
||||
|
||||
// Check for special characters.
|
||||
text_element = FindMatchingSpecial(current_byte);
|
||||
if (!text_element.Empty()) {
|
||||
current_raw_message.append(text_element.GetParamToken());
|
||||
current_parsed_message.append(text_element.GetParamToken());
|
||||
auto special_element = FindMatchingSpecial(current_byte);
|
||||
if (special_element != std::nullopt) {
|
||||
current_raw_message.append(special_element->GetParamToken());
|
||||
current_parsed_message.append(special_element->GetParamToken());
|
||||
parsed_message.push_back(current_byte);
|
||||
continue;
|
||||
}
|
||||
@@ -299,7 +301,7 @@ void MessageEditor::ReadAllTextDataV2() {
|
||||
current_raw_message.append("[");
|
||||
current_raw_message.append(DICTIONARYTOKEN);
|
||||
current_raw_message.append(":");
|
||||
current_raw_message.append(util::HexWord(dictionary));
|
||||
current_raw_message.append(util::HexByte(dictionary));
|
||||
current_raw_message.append("]");
|
||||
|
||||
uint32_t address = Get24LocalFromPC(
|
||||
@@ -336,7 +338,6 @@ void MessageEditor::ReadAllTextData() {
|
||||
|
||||
std::string current_message_raw;
|
||||
std::string current_message_parsed;
|
||||
TextElement text_element;
|
||||
|
||||
while (true) {
|
||||
current_byte = rom()->data()[pos++];
|
||||
@@ -361,20 +362,19 @@ void MessageEditor::ReadAllTextData() {
|
||||
temp_bytes_raw.push_back(current_byte);
|
||||
|
||||
// Check for command.
|
||||
text_element = FindMatchingCommand(current_byte);
|
||||
|
||||
if (!text_element.Empty()) {
|
||||
auto text_element = FindMatchingCommand(current_byte);
|
||||
if (text_element.has_value()) {
|
||||
temp_bytes_parsed.push_back(current_byte);
|
||||
if (text_element.HasArgument) {
|
||||
if (text_element->HasArgument) {
|
||||
current_byte = rom()->data()[pos++];
|
||||
temp_bytes_raw.push_back(current_byte);
|
||||
temp_bytes_parsed.push_back(current_byte);
|
||||
}
|
||||
|
||||
current_message_raw.append(text_element.GetParamToken(current_byte));
|
||||
current_message_parsed.append(text_element.GetParamToken(current_byte));
|
||||
current_message_raw.append(text_element->GetParamToken(current_byte));
|
||||
current_message_parsed.append(text_element->GetParamToken(current_byte));
|
||||
|
||||
if (text_element.Token == kBankToken) {
|
||||
if (text_element->Token == kBankToken) {
|
||||
pos = kTextData2;
|
||||
}
|
||||
|
||||
@@ -382,10 +382,10 @@ void MessageEditor::ReadAllTextData() {
|
||||
}
|
||||
|
||||
// Check for special characters.
|
||||
text_element = FindMatchingSpecial(current_byte);
|
||||
if (!text_element.Empty()) {
|
||||
current_message_raw.append(text_element.GetParamToken());
|
||||
current_message_parsed.append(text_element.GetParamToken());
|
||||
auto special_element = FindMatchingSpecial(current_byte);
|
||||
if (special_element.has_value()) {
|
||||
current_message_raw.append(special_element->GetParamToken());
|
||||
current_message_parsed.append(special_element->GetParamToken());
|
||||
temp_bytes_parsed.push_back(current_byte);
|
||||
continue;
|
||||
}
|
||||
@@ -425,24 +425,6 @@ void MessageEditor::ReadAllTextData() {
|
||||
}
|
||||
}
|
||||
|
||||
std::string ReplaceAllDictionaryWords(std::string str,
|
||||
std::vector<DictionaryEntry> dictionary) {
|
||||
std::string temp = str;
|
||||
for (const auto &entry : dictionary) {
|
||||
if (absl::StrContains(temp, entry.Contents)) {
|
||||
temp = absl::StrReplaceAll(temp, {{entry.Contents, entry.Contents}});
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
DictionaryEntry MessageEditor::GetDictionaryFromID(uint8_t value) {
|
||||
if (value < 0 || value >= all_dictionaries_.size()) {
|
||||
return DictionaryEntry();
|
||||
}
|
||||
return all_dictionaries_[value];
|
||||
}
|
||||
|
||||
void MessageEditor::DrawTileToPreview(int x, int y, int srcx, int srcy, int pal,
|
||||
int sizex, int sizey) {
|
||||
const int num_x_tiles = 16;
|
||||
@@ -532,8 +514,14 @@ void MessageEditor::DrawCharacterToPreview(const std::vector<uint8_t> &text) {
|
||||
// characters.
|
||||
DrawStringToPreview("(NAME)");
|
||||
} else if (value >= DICTOFF && value < (DICTOFF + 97)) {
|
||||
auto dictionaryEntry = GetDictionaryFromID(value - DICTOFF);
|
||||
DrawCharacterToPreview(dictionaryEntry.Data);
|
||||
int pos = value - DICTOFF;
|
||||
if (pos < 0 || pos >= all_dictionaries_.size()) {
|
||||
// Invalid dictionary entry.
|
||||
std::cerr << "Invalid dictionary entry: " << pos << std::endl;
|
||||
continue;
|
||||
}
|
||||
auto dictionary_entry = all_dictionaries_[pos];
|
||||
DrawCharacterToPreview(dictionary_entry.Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,6 @@ constexpr uint8_t kWidthArraySize = 100;
|
||||
constexpr uint8_t kBlockTerminator = 0x80;
|
||||
constexpr uint8_t kMessageBankChangeId = 0x80;
|
||||
|
||||
static TextElement DictionaryElement =
|
||||
TextElement(0x80, DICTIONARYTOKEN, true, "Dictionary");
|
||||
|
||||
class MessageEditor : public Editor, public SharedRom {
|
||||
public:
|
||||
MessageEditor() { type_ = EditorType::kMessage; }
|
||||
@@ -62,7 +59,6 @@ class MessageEditor : public Editor, public SharedRom {
|
||||
void Delete();
|
||||
void SelectAll();
|
||||
|
||||
DictionaryEntry GetDictionaryFromID(uint8_t value);
|
||||
void DrawTileToPreview(int x, int y, int srcx, int srcy, int pal,
|
||||
int sizex = 1, int sizey = 1);
|
||||
void DrawCharacterToPreview(char c);
|
||||
|
||||
Reference in New Issue
Block a user