mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 19:13:07 +01:00
Deduplicate the code, add more safety checks
This commit is contained in:
@@ -16,6 +16,35 @@
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
template<typename T>
|
||||
static void putExtraImpl(IntentDataStorage& storage, uint32_t key, T&& value)
|
||||
{
|
||||
auto it = std::ranges::lower_bound(storage, key, {}, &IntentDataEntry::first);
|
||||
|
||||
// Key should not already exist.
|
||||
assert(it == storage.end() || it->first != key);
|
||||
|
||||
storage.emplace(it, key, std::forward<T>(value));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static auto getExtraImpl(const IntentDataStorage& storage, uint32_t key)
|
||||
{
|
||||
auto it = std::ranges::lower_bound(storage, key, {}, &IntentDataEntry::first);
|
||||
if (it == storage.end() || it->first != key)
|
||||
{
|
||||
// If key does not exist then the usage of Intent is incorrect.
|
||||
assert(false);
|
||||
|
||||
return T{};
|
||||
}
|
||||
|
||||
const auto& [_, data] = *it;
|
||||
assert(std::holds_alternative<T>(data));
|
||||
|
||||
return std::get<T>(data);
|
||||
}
|
||||
|
||||
Intent::Intent(WindowClass windowClass)
|
||||
: _Class(windowClass)
|
||||
{
|
||||
@@ -33,51 +62,31 @@ Intent::Intent(IntentAction intentAction)
|
||||
|
||||
Intent* Intent::PutExtra(uint32_t key, uint32_t value)
|
||||
{
|
||||
auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first);
|
||||
assert(it == _Data.end() || it->first != key);
|
||||
|
||||
_Data.emplace(it, key, static_cast<int64_t>(value));
|
||||
|
||||
putExtraImpl(_Data, key, static_cast<int64_t>(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
Intent* Intent::PutExtra(uint32_t key, void* value)
|
||||
{
|
||||
auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first);
|
||||
assert(it == _Data.end() || it->first != key);
|
||||
|
||||
_Data.emplace(it, key, value);
|
||||
|
||||
putExtraImpl(_Data, key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
Intent* Intent::PutExtra(uint32_t key, int32_t value)
|
||||
{
|
||||
auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first);
|
||||
assert(it == _Data.end() || it->first != key);
|
||||
|
||||
_Data.emplace(it, key, static_cast<int64_t>(value));
|
||||
|
||||
putExtraImpl(_Data, key, static_cast<int64_t>(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
Intent* Intent::PutExtra(uint32_t key, std::string 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));
|
||||
|
||||
putExtraImpl(_Data, key, std::move(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
Intent* Intent::PutExtra(uint32_t key, close_callback value)
|
||||
{
|
||||
auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first);
|
||||
assert(it == _Data.end() || it->first != key);
|
||||
|
||||
_Data.emplace(it, key, value);
|
||||
|
||||
putExtraImpl(_Data, key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -98,70 +107,25 @@ IntentAction Intent::GetAction() const
|
||||
|
||||
void* Intent::GetPointerExtra(uint32_t key) const
|
||||
{
|
||||
auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first);
|
||||
if (it == _Data.end() || it->first != key)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto& [_, data] = *it;
|
||||
|
||||
assert(std::holds_alternative<void*>(data));
|
||||
return std::get<void*>(data);
|
||||
return getExtraImpl<void*>(_Data, key);
|
||||
}
|
||||
|
||||
uint32_t Intent::GetUIntExtra(uint32_t key) const
|
||||
{
|
||||
auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first);
|
||||
if (it == _Data.end() || it->first != key)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto& [_, data] = *it;
|
||||
|
||||
assert(std::holds_alternative<int64_t>(data));
|
||||
return static_cast<uint32_t>(std::get<int64_t>(data));
|
||||
return static_cast<uint32_t>(getExtraImpl<int64_t>(_Data, key));
|
||||
}
|
||||
|
||||
int32_t Intent::GetSIntExtra(uint32_t key) const
|
||||
{
|
||||
auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first);
|
||||
if (it == _Data.end() || it->first != key)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto& [_, data] = *it;
|
||||
|
||||
assert(std::holds_alternative<int64_t>(data));
|
||||
return static_cast<int32_t>(std::get<int64_t>(data));
|
||||
return static_cast<uint32_t>(getExtraImpl<int64_t>(_Data, key));
|
||||
}
|
||||
|
||||
std::string Intent::GetStringExtra(uint32_t key) const
|
||||
{
|
||||
auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first);
|
||||
if (it == _Data.end() || it->first != key)
|
||||
{
|
||||
return std::string{};
|
||||
}
|
||||
|
||||
const auto& [_, data] = *it;
|
||||
|
||||
assert(std::holds_alternative<std::string>(data));
|
||||
return std::get<std::string>(data);
|
||||
return getExtraImpl<std::string>(_Data, key);
|
||||
}
|
||||
|
||||
close_callback Intent::GetCloseCallbackExtra(uint32_t key) const
|
||||
{
|
||||
auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first);
|
||||
if (it == _Data.end() || it->first != key)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto& [_, data] = *it;
|
||||
|
||||
assert(std::holds_alternative<close_callback>(data));
|
||||
return std::get<close_callback>(data);
|
||||
return getExtraImpl<close_callback>(_Data, key);
|
||||
}
|
||||
|
||||
@@ -59,32 +59,35 @@ enum IntentAction
|
||||
INTENT_ACTION_NULL = 255,
|
||||
};
|
||||
|
||||
// The maximum amount of data the Intent can hold, 8 should be sufficient, raise this if needed.
|
||||
static constexpr size_t kIntentMaxDataSlots = 8;
|
||||
|
||||
using IntentData = std::variant<int64_t, std::string, close_callback, void*>;
|
||||
using IntentDataEntry = std::pair<uint32_t, IntentData>;
|
||||
using IntentDataStorage = sfl::static_vector<IntentDataEntry, kIntentMaxDataSlots>;
|
||||
|
||||
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<int64_t, std::string, close_callback, void*>;
|
||||
|
||||
WindowClass _Class{ WindowClass::Null };
|
||||
WindowDetail _WindowDetail{ WD_NULL };
|
||||
IntentAction _Action{ INTENT_ACTION_NULL };
|
||||
|
||||
using DataEntry = std::pair<uint32_t, IntentData>;
|
||||
sfl::static_vector<DataEntry, kMaxDataSlots> _Data;
|
||||
IntentDataStorage _Data;
|
||||
|
||||
public:
|
||||
explicit Intent(WindowClass windowClass);
|
||||
explicit Intent(WindowDetail windowDetail);
|
||||
explicit Intent(IntentAction windowclass);
|
||||
|
||||
WindowClass GetWindowClass() const;
|
||||
WindowDetail GetWindowDetail() const;
|
||||
IntentAction GetAction() const;
|
||||
|
||||
void* GetPointerExtra(uint32_t key) const;
|
||||
std::string GetStringExtra(uint32_t key) const;
|
||||
uint32_t GetUIntExtra(uint32_t key) const;
|
||||
int32_t GetSIntExtra(uint32_t key) const;
|
||||
close_callback GetCloseCallbackExtra(uint32_t key) const;
|
||||
|
||||
Intent* PutExtra(uint32_t key, uint32_t value);
|
||||
Intent* PutExtra(uint32_t key, void* value);
|
||||
Intent* PutExtra(uint32_t key, int32_t value);
|
||||
|
||||
Reference in New Issue
Block a user