mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-09-10 04:42:04 -04:00
revise randomizerEnumStrings, include fmt compatibility (#7148)
prefer switch over map, avoids static initializer & reduces code size by over a megabyte
This commit is contained in:
@@ -11,8 +11,7 @@
|
||||
#include "soh/Enhancements/randomizer/static_data.h"
|
||||
#include "soh/Enhancements/randomizer/item.h"
|
||||
#include "soh/Enhancements/randomizer/dungeon.h"
|
||||
#include "soh/Enhancements/randomizer/randomizerEnums/RandomizerGet.h"
|
||||
#include "soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h"
|
||||
#include "soh/Enhancements/randomizer/randomizerEnumStrings.h"
|
||||
#include "soh/util.h"
|
||||
#include "soh/SohGui/ImGuiUtils.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
@@ -1368,13 +1367,24 @@ void DrawFlagArrayWithTooltips(const std::string& name, T& flags, Colors color,
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
static const char* GetFlagDescription(const FlagTable& flagTable, uint16_t index) {
|
||||
if (flagTable.flagTableType == RANDOMIZER_INF) {
|
||||
std::string_view name = EnumToString(static_cast<RandomizerInf>(index));
|
||||
return name.empty() ? "" : name.data();
|
||||
}
|
||||
auto it = flagTable.flagDescriptions.find(index);
|
||||
return it != flagTable.flagDescriptions.end() ? it->second : "";
|
||||
}
|
||||
|
||||
// Draw a flag bitfield as a grid of checkboxes
|
||||
void DrawFlagTableArray16(const FlagTable& flagTable, uint16_t row, uint16_t& flags) {
|
||||
ImGui::PushID((std::to_string(row) + flagTable.name).c_str());
|
||||
for (int32_t flagIndex = 15; flagIndex >= 0; flagIndex--) {
|
||||
ImGui::SameLine();
|
||||
ImGui::PushID(flagIndex);
|
||||
bool hasDescription = !!flagTable.flagDescriptions.contains(row * 16 + flagIndex);
|
||||
uint16_t index = static_cast<uint16_t>(row * 16 + flagIndex);
|
||||
const char* desc = GetFlagDescription(flagTable, index);
|
||||
bool hasDescription = desc[0] != '\0';
|
||||
uint32_t bitMask = 1 << flagIndex;
|
||||
ImVec4 themeColor = ColorValues.at(THEME_COLOR);
|
||||
ImVec4 colorDark = { themeColor.x * 0.4f, themeColor.y * 0.4f, themeColor.z * 0.4f, themeColor.z };
|
||||
@@ -1396,9 +1406,7 @@ void DrawFlagTableArray16(const FlagTable& flagTable, uint16_t row, uint16_t& fl
|
||||
PopStyleCheckbox();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
uint16_t index = row * 16 + flagIndex;
|
||||
if (hasDescription) {
|
||||
const char* desc = flagTable.flagDescriptions.at(index);
|
||||
ImGui::Text("0x%02X: %s", index, UIWidgets::WrappedText(desc, 60).c_str());
|
||||
} else {
|
||||
ImGui::Text("0x%02X: %s (Bit %d)", index, flagTable.name, flagIndex);
|
||||
@@ -1470,8 +1478,7 @@ static void DrawFlagTableSearchResults(const FlagTable& flagTable, ImGuiTextFilt
|
||||
|
||||
for (int32_t flagIndex = 15; flagIndex >= 0; flagIndex--) {
|
||||
uint16_t index = static_cast<uint16_t>(row * 16 + flagIndex);
|
||||
auto descIt = flagTable.flagDescriptions.find(index);
|
||||
const char* desc = descIt != flagTable.flagDescriptions.end() ? descIt->second : "";
|
||||
const char* desc = GetFlagDescription(flagTable, index);
|
||||
std::string searchable = spdlog::fmt_lib::format("0x{:02X} {}", index, desc);
|
||||
if (!filter.PassFilter(searchable.c_str())) {
|
||||
continue;
|
||||
@@ -1480,7 +1487,7 @@ static void DrawFlagTableSearchResults(const FlagTable& flagTable, ImGuiTextFilt
|
||||
hasMatches = true;
|
||||
|
||||
ImGui::PushID(index);
|
||||
bool hasDescription = descIt != flagTable.flagDescriptions.end();
|
||||
bool hasDescription = desc[0] != '\0';
|
||||
uint32_t bitMask = 1 << flagIndex;
|
||||
ImVec4 themeColor = ColorValues.at(THEME_COLOR);
|
||||
ImVec4 colorDark = { themeColor.x * 0.4f, themeColor.y * 0.4f, themeColor.z * 0.4f, themeColor.z };
|
||||
|
||||
@@ -359,14 +359,8 @@ const std::vector<FlagTable> flagTables = {
|
||||
{ 0x24, "Market Crowd Text Randomizer" },
|
||||
{ 0x30, "Entered the Market" },
|
||||
} },
|
||||
{ "Randomizer Inf Flags",
|
||||
RANDOMIZER_INF,
|
||||
(RAND_INF_MAX + 15) / 16,
|
||||
{
|
||||
#define RANDO_ENUM_ITEM(rand_inf) { rand_inf, #rand_inf },
|
||||
#include "soh/Enhancements/randomizer/randomizerEnums/RandomizerInf.h"
|
||||
#undef RANDO_ENUM_ITEM
|
||||
} },
|
||||
// Randomizer Inf flags are described by their enum name, see GetFlagDescription.
|
||||
{ "Randomizer Inf Flags", RANDOMIZER_INF, (RAND_INF_MAX + 15) / 16, {} },
|
||||
};
|
||||
|
||||
const std::vector<std::string> state1 = {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "../debugger/performanceTimer.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "randomizer.h"
|
||||
#include "randomizerEnumStrings.h"
|
||||
#include "dungeon.h"
|
||||
#include "SeedContext.h"
|
||||
#include "randomizer.h"
|
||||
@@ -322,8 +323,7 @@ bool Logic::HasItem(RandomizerGet itemName) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SPDLOG_ERROR("HasItem reached `return false;`. Missing case for RandomizerGet of {}",
|
||||
static_cast<uint32_t>(itemName));
|
||||
SPDLOG_ERROR("HasItem reached `return false;`. Missing case for RandomizerGet of {}", itemName);
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
@@ -486,7 +486,7 @@ bool Logic::ItemUseAllowed(RandomizerGet itemName) {
|
||||
case SCENE_FISHING_POND:
|
||||
return itemName == RG_FISHING_POLE;
|
||||
default:
|
||||
SPDLOG_INFO("ItemUseAllowed reached `default` with item {} in Scene {}.", static_cast<uint32_t>(itemName),
|
||||
SPDLOG_INFO("ItemUseAllowed reached `default` with item {} in Scene {}.", itemName,
|
||||
static_cast<uint32_t>(RegionTable(CurrentRegionKey)->scene));
|
||||
return true;
|
||||
}
|
||||
@@ -676,8 +676,7 @@ bool Logic::CanUse(RandomizerGet itemName) {
|
||||
return true;
|
||||
|
||||
default:
|
||||
SPDLOG_INFO("CanUse reached `default` for {}. using HasItem is a minor Optimisation.",
|
||||
static_cast<uint32_t>(itemName));
|
||||
SPDLOG_INFO("CanUse reached `default` for {}. using HasItem is a minor Optimisation.", itemName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <libultraship/bridge/consolevariablebridge.h>
|
||||
|
||||
#include "option.h"
|
||||
#include "randomizerEnumStrings.h"
|
||||
#include "static_data.h"
|
||||
#include "soh/SohGui/SohMenu.h"
|
||||
#include "soh/Enhancements/Lang/Lang.h"
|
||||
@@ -70,18 +71,6 @@ RandomizerSettingKey Option::GetKey() const {
|
||||
|
||||
#pragma region Lang
|
||||
|
||||
#define RANDO_ENUM_ITEM(enum) { enum, #enum },
|
||||
|
||||
std::unordered_map<RandomizerSettingKey, std::string> settingNames = {
|
||||
#include "randomizerEnums/RandomizerSettingKey.h"
|
||||
};
|
||||
|
||||
std::unordered_map<RandomizerTrick, std::string> trickNames = {
|
||||
#include "randomizerEnums/RandomizerTrick.h"
|
||||
};
|
||||
|
||||
#undef RANDO_ENUM_ITEM
|
||||
|
||||
const static std::string namePostfix = ".name";
|
||||
const static std::string descriptionPostfix = ".description";
|
||||
|
||||
@@ -92,13 +81,13 @@ const static std::string empty = "";
|
||||
const static std::string error = "[ERROR]";
|
||||
|
||||
static const std::string& MakeSettingName(RandomizerSettingKey key) {
|
||||
std::string settingNamePart = settingNames[key].substr(4);
|
||||
std::string settingNamePart(EnumToString(key).substr(4));
|
||||
std::transform(settingNamePart.begin(), settingNamePart.end(), settingNamePart.begin(), ::tolower);
|
||||
return Lang::Translate((settingPrefix + settingNamePart + namePostfix).c_str());
|
||||
}
|
||||
|
||||
static const std::string& MakeSettingDescription(RandomizerSettingKey key) {
|
||||
std::string settingNamePart = settingNames[key].substr(4);
|
||||
std::string settingNamePart(EnumToString(key).substr(4));
|
||||
std::transform(settingNamePart.begin(), settingNamePart.end(), settingNamePart.begin(), ::tolower);
|
||||
auto result = Lang::TryTranslate((settingPrefix + settingNamePart + descriptionPostfix).c_str());
|
||||
if (std::holds_alternative<std::reference_wrapper<const std::string>>(result)) {
|
||||
@@ -112,13 +101,13 @@ static const std::string& MakeSettingDescription(RandomizerSettingKey key) {
|
||||
}
|
||||
|
||||
static const std::string& MakeTrickName(RandomizerTrick key) {
|
||||
std::string trickNamePart = trickNames[key].substr(3);
|
||||
std::string trickNamePart(EnumToString(key).substr(3));
|
||||
std::transform(trickNamePart.begin(), trickNamePart.end(), trickNamePart.begin(), ::tolower);
|
||||
return Lang::Translate((trickPrefix + trickNamePart + namePostfix).c_str());
|
||||
}
|
||||
|
||||
static const std::string& MakeTrickDescription(RandomizerTrick key) {
|
||||
std::string trickNamePart = trickNames[key].substr(3);
|
||||
std::string trickNamePart(EnumToString(key).substr(3));
|
||||
std::transform(trickNamePart.begin(), trickNamePart.end(), trickNamePart.begin(), ::tolower);
|
||||
return Lang::Translate((trickPrefix + trickNamePart + descriptionPostfix).c_str());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// Deliberately has no include guard: define RANDO_ENUM_BEGIN/ITEM/END and include this to
|
||||
// expand every enum again.
|
||||
#include "randomizerEnums/LogicVal.h"
|
||||
#include "randomizerEnums/RandomizerCheck.h"
|
||||
#include "randomizerEnums/RandomizerGet.h"
|
||||
#include "randomizerEnums/RandomizerHintTextKey.h"
|
||||
#include "randomizerEnums/RandomizerInf.h"
|
||||
#include "randomizerEnums/RandomizerMiscEnums.h"
|
||||
#include "randomizerEnums/RandomizerOptions.h"
|
||||
#include "randomizerEnums/RandomizerRegion.h"
|
||||
#include "randomizerEnums/RandomizerSettingKey.h"
|
||||
#include "randomizerEnums/RandomizerTrick.h"
|
||||
@@ -1,35 +1,26 @@
|
||||
#include "randomizerEnumStrings.h"
|
||||
|
||||
// Redefine enum macros to generate string->enum maps for every enum.
|
||||
#define RANDO_ENUM_BEGIN(EnumName) \
|
||||
template <> const std::unordered_map<std::string_view, EnumName>& GetStringToEnumMap<EnumName>() { \
|
||||
static const std::unordered_map<std::string_view, EnumName> map = [] { \
|
||||
std::unordered_map<std::string_view, EnumName> m;
|
||||
static std::string NameOrValue(std::string_view name, std::string_view enumName, long long value) {
|
||||
if (!name.empty()) {
|
||||
return std::string(name);
|
||||
}
|
||||
return std::string(enumName) + '(' + std::to_string(value) + ')';
|
||||
}
|
||||
|
||||
#define RANDO_ENUM_ITEM(name, ...) m.emplace(#name, name);
|
||||
#define RANDO_ENUM_BEGIN(EnumName) \
|
||||
std::string_view EnumToString(EnumName value) { \
|
||||
switch (value) {
|
||||
|
||||
#define RANDO_ENUM_END(EnumName) \
|
||||
return m; \
|
||||
} \
|
||||
(); \
|
||||
return map; \
|
||||
#define RANDO_ENUM_ITEM(name, ...) \
|
||||
case name: \
|
||||
return #name;
|
||||
|
||||
#define RANDO_ENUM_END(EnumName) \
|
||||
} \
|
||||
return {}; \
|
||||
} \
|
||||
std::string format_as(EnumName value) { \
|
||||
return NameOrValue(EnumToString(value), #EnumName, (long long)value); \
|
||||
}
|
||||
|
||||
#undef RANDO_ENUM_BEGIN
|
||||
#undef RANDO_ENUM_ITEM
|
||||
#undef RANDO_ENUM_END
|
||||
|
||||
// Redefine enum macros to generate enum->string maps for every enum.
|
||||
#define RANDO_ENUM_BEGIN(EnumName) \
|
||||
template <> const std::unordered_map<EnumName, std::string_view>& GetEnumToStringMap<EnumName>() { \
|
||||
static const std::unordered_map<EnumName, std::string_view> map = [] { \
|
||||
std::unordered_map<EnumName, std::string_view> m;
|
||||
|
||||
#define RANDO_ENUM_ITEM(name, ...) m.emplace(name, #name);
|
||||
|
||||
#define RANDO_ENUM_END(EnumName) \
|
||||
return m; \
|
||||
} \
|
||||
(); \
|
||||
return map; \
|
||||
}
|
||||
#include "randomizerEnumList.h"
|
||||
|
||||
@@ -1,29 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <optional>
|
||||
|
||||
template <typename T> const std::unordered_map<std::string_view, T>& GetStringToEnumMap();
|
||||
#include "randomizerEnums.h"
|
||||
|
||||
template <typename T> std::optional<T> StringToEnum(const std::string_view& str) {
|
||||
const auto& map = GetStringToEnumMap<T>();
|
||||
auto it = map.find(str);
|
||||
if (it != map.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> const std::unordered_map<T, std::string_view>& GetEnumToStringMap();
|
||||
|
||||
template <typename T> std::optional<std::string_view> EnumToString(const T& value) {
|
||||
const auto& map = GetEnumToStringMap<T>();
|
||||
auto it = map.find(value);
|
||||
if (it != map.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
// EnumToString gives an item's name, or an empty view for a value that isn't one of them. A
|
||||
// name is a view over a string literal, so data() is NUL terminated and safe for %s.
|
||||
//
|
||||
// format_as is the hook fmt looks for: SPDLOG_ERROR("{}", RC_LINKS_POCKET) logs
|
||||
// "RC_LINKS_POCKET" rather than a number, and a value with no name logs as
|
||||
// "RandomizerCheck(...)". fmt finds it by argument dependent lookup, so including this
|
||||
// header is all a caller has to do.
|
||||
#define RANDO_ENUM_BEGIN(EnumName) \
|
||||
std::string_view EnumToString(EnumName value); \
|
||||
std::string format_as(EnumName value);
|
||||
#define RANDO_ENUM_ITEM(...)
|
||||
#define RANDO_ENUM_END(...)
|
||||
#include "randomizerEnumList.h"
|
||||
#undef RANDO_ENUM_BEGIN
|
||||
#undef RANDO_ENUM_ITEM
|
||||
#undef RANDO_ENUM_END
|
||||
|
||||
@@ -10,16 +10,7 @@
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
#include "randomizerEnums/LogicVal.h"
|
||||
#include "randomizerEnums/RandomizerCheck.h"
|
||||
#include "randomizerEnums/RandomizerGet.h"
|
||||
#include "randomizerEnums/RandomizerHintTextKey.h"
|
||||
#include "randomizerEnums/RandomizerInf.h"
|
||||
#include "randomizerEnums/RandomizerMiscEnums.h"
|
||||
#include "randomizerEnums/RandomizerOptions.h"
|
||||
#include "randomizerEnums/RandomizerRegion.h"
|
||||
#include "randomizerEnums/RandomizerSettingKey.h"
|
||||
#include "randomizerEnums/RandomizerTrick.h"
|
||||
#include "randomizerEnumList.h"
|
||||
|
||||
// Clean up only the defaults we defined.
|
||||
#ifdef RANDO_ENUM__CLEANUP
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "soh/Enhancements/randomizer/dungeon.h"
|
||||
#include "soh/Enhancements/randomizer/logic.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer.h"
|
||||
#include "soh/Enhancements/randomizer/randomizerEnumStrings.h"
|
||||
|
||||
extern "C" {
|
||||
#include "variables.h"
|
||||
@@ -326,7 +327,7 @@ void SetStartingItems() {
|
||||
Item_Give(NULL, ITEM_LETTER_RUTO);
|
||||
break;
|
||||
default:
|
||||
SPDLOG_ERROR("[SetStartingItems] Unhandled value for bottleKey {}: {}", (int)bottleKey, bottle);
|
||||
SPDLOG_ERROR("[SetStartingItems] Unhandled value for bottleKey {}: {}", bottleKey, bottle);
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_check_tracker.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer.h"
|
||||
#include "soh/Enhancements/randomizer/randomizerEnumStrings.h"
|
||||
|
||||
static bool isResultOfHandling = false;
|
||||
|
||||
@@ -41,7 +42,7 @@ void Anchor::HandlePacket_SetCheckStatus(nlohmann::json payload) {
|
||||
|
||||
RandomizerCheck rc = payload.at("rc").get<RandomizerCheck>();
|
||||
if (rc < 0 || rc >= RC_MAX) {
|
||||
SPDLOG_ERROR("[Anchor] SET_CHECK_STATUS: rc {} out of range", (int)rc);
|
||||
SPDLOG_ERROR("[Anchor] SET_CHECK_STATUS: {} out of range", rc);
|
||||
return;
|
||||
}
|
||||
RandomizerCheckStatus status = payload.at("status").get<RandomizerCheckStatus>();
|
||||
|
||||
Reference in New Issue
Block a user