From 3d3a88a9c61f9e00defe08bac53acc193fd813db Mon Sep 17 00:00:00 2001 From: scawful Date: Sat, 5 Apr 2025 17:24:11 -0400 Subject: [PATCH] Refactor message handling: replace TextElement return type with std::optional for better nullability handling --- src/app/editor/message/message_data.cc | 39 ++++++------- src/app/editor/message/message_data.h | 4 +- src/app/editor/message/message_editor.cc | 74 ++++++++++-------------- src/app/editor/message/message_editor.h | 4 -- 4 files changed, 52 insertions(+), 69 deletions(-) diff --git a/src/app/editor/message/message_data.cc b/src/app/editor/message/message_data.cc index ade910fb..347c37b0 100644 --- a/src/app/editor/message/message_data.cc +++ b/src/app/editor/message/message_data.cc @@ -1,5 +1,6 @@ #include "message_data.h" +#include #include #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 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 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 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 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); } } } diff --git a/src/app/editor/message/message_data.h b/src/app/editor/message/message_data.h index 5eb2f9f7..161bbf48 100644 --- a/src/app/editor/message/message_data.h +++ b/src/app/editor/message/message_data.h @@ -256,7 +256,7 @@ static const std::vector TextCommands = { TextElement(0x70, "NONO", false, kCrash), }; -TextElement FindMatchingCommand(uint8_t b); +std::optional FindMatchingCommand(uint8_t b); static const std::vector SpecialChars = { TextElement(0x43, "...", false, "Ellipsis …"), @@ -282,7 +282,7 @@ static const std::vector SpecialChars = { TextElement(0x4B, "LFR", false, "Link face right"), }; -TextElement FindMatchingSpecial(uint8_t b); +std::optional FindMatchingSpecial(uint8_t b); struct ParsedElement { TextElement Parent; diff --git a/src/app/editor/message/message_editor.cc b/src/app/editor/message/message_editor.cc index 6472144f..fd1efae0 100644 --- a/src/app/editor/message/message_editor.cc +++ b/src/app/editor/message/message_editor.cc @@ -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 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 &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); } } } diff --git a/src/app/editor/message/message_editor.h b/src/app/editor/message/message_editor.h index 5a9b3c4a..624fb183 100644 --- a/src/app/editor/message/message_editor.h +++ b/src/app/editor/message/message_editor.h @@ -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);