diff --git a/src/openrct2/windows/Intent.cpp b/src/openrct2/windows/Intent.cpp index 74432d8eec..61fe133c27 100644 --- a/src/openrct2/windows/Intent.cpp +++ b/src/openrct2/windows/Intent.cpp @@ -11,6 +11,7 @@ #include "../core/Guard.hpp" +#include #include using namespace OpenRCT2; @@ -32,35 +33,50 @@ Intent::Intent(IntentAction intentAction) Intent* Intent::PutExtra(uint32_t key, uint32_t value) { - _Data.emplace(key, static_cast(value)); + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + assert(it == _Data.end() || it->first != key); + + _Data.emplace(it, key, static_cast(value)); return this; } Intent* Intent::PutExtra(uint32_t key, void* value) { - _Data.emplace(key, value); + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + assert(it == _Data.end() || it->first != key); + + _Data.emplace(it, key, value); return this; } Intent* Intent::PutExtra(uint32_t key, int32_t value) { - _Data.emplace(key, static_cast(value)); + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + assert(it == _Data.end() || it->first != key); + + _Data.emplace(it, key, static_cast(value)); return this; } Intent* Intent::PutExtra(uint32_t key, std::string value) { - _Data.emplace(key, value); + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + assert(it == _Data.end() || it->first != key); + + _Data.emplace(it, key, std::move(value)); return this; } Intent* Intent::PutExtra(uint32_t key, close_callback value) { - _Data.emplace(key, value); + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + assert(it == _Data.end() || it->first != key); + + _Data.emplace(it, key, value); return this; } @@ -82,12 +98,13 @@ IntentAction Intent::GetAction() const void* Intent::GetPointerExtra(uint32_t key) const { - if (_Data.count(key) == 0) + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + if (it == _Data.end() || it->first != key) { return nullptr; } - auto data = _Data.at(key); + const auto& [_, data] = *it; assert(std::holds_alternative(data)); return std::get(data); @@ -95,12 +112,13 @@ void* Intent::GetPointerExtra(uint32_t key) const uint32_t Intent::GetUIntExtra(uint32_t key) const { - if (_Data.count(key) == 0) + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + if (it == _Data.end() || it->first != key) { return 0; } - auto data = _Data.at(key); + const auto& [_, data] = *it; assert(std::holds_alternative(data)); return static_cast(std::get(data)); @@ -108,12 +126,13 @@ uint32_t Intent::GetUIntExtra(uint32_t key) const int32_t Intent::GetSIntExtra(uint32_t key) const { - if (_Data.count(key) == 0) + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + if (it == _Data.end() || it->first != key) { return 0; } - auto data = _Data.at(key); + const auto& [_, data] = *it; assert(std::holds_alternative(data)); return static_cast(std::get(data)); @@ -121,12 +140,13 @@ int32_t Intent::GetSIntExtra(uint32_t key) const std::string Intent::GetStringExtra(uint32_t key) const { - if (_Data.count(key) == 0) + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + if (it == _Data.end() || it->first != key) { return std::string{}; } - auto data = _Data.at(key); + const auto& [_, data] = *it; assert(std::holds_alternative(data)); return std::get(data); @@ -134,12 +154,13 @@ std::string Intent::GetStringExtra(uint32_t key) const close_callback Intent::GetCloseCallbackExtra(uint32_t key) const { - if (_Data.count(key) == 0) + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + if (it == _Data.end() || it->first != key) { return nullptr; } - auto data = _Data.at(key); + const auto& [_, data] = *it; assert(std::holds_alternative(data)); return std::get(data); diff --git a/src/openrct2/windows/Intent.h b/src/openrct2/windows/Intent.h index f859bf1b2a..7b71b1954d 100644 --- a/src/openrct2/windows/Intent.h +++ b/src/openrct2/windows/Intent.h @@ -13,6 +13,7 @@ #include "../interface/Window.h" #include +#include #include #include @@ -60,12 +61,17 @@ enum IntentAction class Intent { + // The maximum amount of data the Intent can hold, 8 should be sufficient, raise this if needed. + static constexpr size_t kMaxDataSlots = 8; + using IntentData = std::variant; WindowClass _Class{ WindowClass::Null }; WindowDetail _WindowDetail{ WD_NULL }; IntentAction _Action{ INTENT_ACTION_NULL }; - std::map _Data; + + using DataEntry = std::pair; + sfl::static_vector _Data; public: explicit Intent(WindowClass windowClass);