From a36e0a32f7f3962f93694a3ed7fab02632078372 Mon Sep 17 00:00:00 2001 From: ZehMatt Date: Thu, 22 Jul 2021 19:54:15 +0300 Subject: [PATCH 1/9] Add EnumMap container for bidirectional key, enum mapping --- OpenRCT2.xcodeproj/project.pbxproj | 4 + src/openrct2/core/EnumMap.hpp | 157 +++++++++++++++++++++++++++++ src/openrct2/libopenrct2.vcxproj | 1 + 3 files changed, 162 insertions(+) create mode 100644 src/openrct2/core/EnumMap.hpp diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index b6527ce470..82b726f9ed 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -767,6 +767,7 @@ F42186C5840D4196981ADD16 /* EntityTweener.h in Headers */ = {isa = PBXBuildFile; fileRef = 091352A950004312BAB18717 /* EntityTweener.h */; }; 0746674FA0794ABF86E406A1 /* Litter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9D3DD6CD73F5421880280D9D /* Litter.cpp */; }; B9B6F97CE24E4A559C7BBA0A /* RideConstruction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BCCA2EF0F5A40D5B83A83AC /* RideConstruction.cpp */; }; + 317B766A750D4365B22A1682 /* EnumMap.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BA2317BF6FB54E328DEB7055 /* EnumMap.hpp */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -1836,6 +1837,7 @@ 091352A950004312BAB18717 /* EntityTweener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EntityTweener.h; path = src/openrct2/world/EntityTweener.h; sourceTree = SOURCE_ROOT; }; 9D3DD6CD73F5421880280D9D /* Litter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Litter.cpp; path = src/openrct2/world/Litter.cpp; sourceTree = SOURCE_ROOT; }; 6BCCA2EF0F5A40D5B83A83AC /* RideConstruction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RideConstruction.cpp; path = src/openrct2/ride/RideConstruction.cpp; sourceTree = SOURCE_ROOT; }; + BA2317BF6FB54E328DEB7055 /* EnumMap.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = EnumMap.hpp; path = src/openrct2/core/EnumMap.hpp; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -2503,6 +2505,7 @@ 4C8BB67F25533D64005C8830 /* StringReader.h */, F76C83991EC4E7CC00FA49E2 /* Zip.cpp */, F76C839A1EC4E7CC00FA49E2 /* Zip.h */, + BA2317BF6FB54E328DEB7055 /* EnumMap.hpp */, ); path = core; sourceTree = ""; @@ -3468,6 +3471,7 @@ 2ADE2F342244191E002598AF /* VirtualFloor.h in Headers */, 66A10F8B257F1E1800DD651A /* LandSmoothAction.h in Headers */, F42186C5840D4196981ADD16 /* EntityTweener.h in Headers */, + 317B766A750D4365B22A1682 /* EnumMap.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/openrct2/core/EnumMap.hpp b/src/openrct2/core/EnumMap.hpp new file mode 100644 index 0000000000..95f539421a --- /dev/null +++ b/src/openrct2/core/EnumMap.hpp @@ -0,0 +1,157 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ +#pragma once + +#include +#include +#include +#include + +/** + * Bi-directional map for converting between strings and enums / numbers. + */ +template class EnumMap +{ +private: + std::vector> _map; + bool _continiousValueIndex{ false }; + + static constexpr size_t BucketSize = 43; + std::array, BucketSize> _buckets; + + static constexpr bool ValueIndexable() + { + if constexpr (std::is_enum_v) + return true; + else if constexpr (std::is_integral_v) + return true; + return false; + } + + static constexpr auto ValueDistance(T a, T b) + { + if constexpr (std::is_enum_v) + return static_cast>(b) - static_cast>(a); + else if constexpr (std::is_integral_v) + return (b - a); + } + + static constexpr uint32_t MakeHash(const std::string_view str) + { + uint32_t res = 0x811c9dc5; + for (auto chr : str) + { + res ^= chr; + res *= 0x01000193; + } + return res; + } + +public: + EnumMap(const std::initializer_list>&& items) + : _map{ items } + { + std::sort(_map.begin(), _map.end(), [](const auto& a, const auto& b) { return a.second < b.second; }); + + if constexpr (ValueIndexable()) + { + _continiousValueIndex = true; + T cur{}; + for (size_t i = 1; i < _map.size(); i++) + { + auto nextVal = _map[i].second; + auto dist = ValueDistance(cur, _map[i].second); + if (dist != 1) + { + _continiousValueIndex = false; + break; + } + cur = nextVal; + } + } + + int32_t index = 0; + for (auto& kv : _map) + { + auto hash = MakeHash(kv.first); + auto bucketIndex = hash % BucketSize; + auto& bucket = _buckets[bucketIndex]; + bucket.push_back(index); + index++; + } + } + + std::string_view operator[](T k) const + { + auto it = find(k); + return it->first; + } + + T operator[](std::string_view k) const + { + auto it = find(k); + return it->second; + } + + auto find(const std::string_view k) const + { + const auto hash = MakeHash(k); + const auto bucketIndex = hash % BucketSize; + const auto& bucket = _buckets[bucketIndex]; + + for (auto index : bucket) + { + auto& entry = _map[index]; + if (entry.first == k) + { + return _map.begin() + index; + } + } + + return end(); + } + + auto find(const T k) const + { + const auto binarySearchValue = [&]() { + auto it = std::lower_bound(_map.begin(), _map.end(), k, [](const auto& a, const auto& b) { return a.second < b; }); + if (it == _map.end() || it->second != k) + return end(); + + return it; + }; + + if constexpr (ValueIndexable()) + { + if (_continiousValueIndex) + { + auto index = static_cast(k); + return _map.begin() + index; + } + else + { + return binarySearchValue(); + } + } + else + { + return binarySearchValue(); + } + } + + auto begin() const + { + return _map.begin(); + } + + auto end() const + { + return _map.end(); + } +}; diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 2af6898f4a..8a82280aee 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -157,6 +157,7 @@ + From ce8040b8580eda7693fe7b6369dee86f67bee72a Mon Sep 17 00:00:00 2001 From: ZehMatt Date: Thu, 22 Jul 2021 20:13:55 +0300 Subject: [PATCH 2/9] Use EnumMap for string to colour conversion --- src/openrct2/interface/Colour.cpp | 72 ++++++++++++++++--------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/src/openrct2/interface/Colour.cpp b/src/openrct2/interface/Colour.cpp index 0f13bbc824..2f15032676 100644 --- a/src/openrct2/interface/Colour.cpp +++ b/src/openrct2/interface/Colour.cpp @@ -9,12 +9,12 @@ #include "Colour.h" +#include "../core/EnumMap.hpp" #include "../drawing/Drawing.h" #include "../sprites.h" #include #include -#include rct_colour_map ColourMapA[COLOUR_COUNT] = {}; @@ -60,45 +60,47 @@ void colours_init_maps() namespace Colour { + static const EnumMap LookupTable{ + { "black", COLOUR_BLACK }, + { "grey", COLOUR_GREY }, + { "white", COLOUR_WHITE }, + { "dark_purple", COLOUR_DARK_PURPLE }, + { "light_purple", COLOUR_LIGHT_PURPLE }, + { "bright_purple", COLOUR_BRIGHT_PURPLE }, + { "dark_blue", COLOUR_DARK_BLUE }, + { "light_blue", COLOUR_LIGHT_BLUE }, + { "icy_blue", COLOUR_ICY_BLUE }, + { "teal", COLOUR_TEAL }, + { "aquamarine", COLOUR_AQUAMARINE }, + { "saturated_green", COLOUR_SATURATED_GREEN }, + { "dark_green", COLOUR_DARK_GREEN }, + { "moss_green", COLOUR_MOSS_GREEN }, + { "bright_green", COLOUR_BRIGHT_GREEN }, + { "olive_green", COLOUR_OLIVE_GREEN }, + { "dark_olive_green", COLOUR_DARK_OLIVE_GREEN }, + { "bright_yellow", COLOUR_BRIGHT_YELLOW }, + { "yellow", COLOUR_YELLOW }, + { "dark_yellow", COLOUR_DARK_YELLOW }, + { "light_orange", COLOUR_LIGHT_ORANGE }, + { "dark_orange", COLOUR_DARK_ORANGE }, + { "light_brown", COLOUR_LIGHT_BROWN }, + { "saturated_brown", COLOUR_SATURATED_BROWN }, + { "dark_brown", COLOUR_DARK_BROWN }, + { "salmon_pink", COLOUR_SALMON_PINK }, + { "bordeaux_red", COLOUR_BORDEAUX_RED }, + { "saturated_red", COLOUR_SATURATED_RED }, + { "bright_red", COLOUR_BRIGHT_RED }, + { "dark_pink", COLOUR_DARK_PINK }, + { "bright_pink", COLOUR_BRIGHT_PINK }, + { "light_pink", COLOUR_LIGHT_PINK }, + }; + colour_t FromString(std::string_view s, colour_t defaultValue) { - static const std::unordered_map LookupTable{ - { "black", COLOUR_BLACK }, - { "grey", COLOUR_GREY }, - { "white", COLOUR_WHITE }, - { "dark_purple", COLOUR_DARK_PURPLE }, - { "light_purple", COLOUR_LIGHT_PURPLE }, - { "bright_purple", COLOUR_BRIGHT_PURPLE }, - { "dark_blue", COLOUR_DARK_BLUE }, - { "light_blue", COLOUR_LIGHT_BLUE }, - { "icy_blue", COLOUR_ICY_BLUE }, - { "teal", COLOUR_TEAL }, - { "aquamarine", COLOUR_AQUAMARINE }, - { "saturated_green", COLOUR_SATURATED_GREEN }, - { "dark_green", COLOUR_DARK_GREEN }, - { "moss_green", COLOUR_MOSS_GREEN }, - { "bright_green", COLOUR_BRIGHT_GREEN }, - { "olive_green", COLOUR_OLIVE_GREEN }, - { "dark_olive_green", COLOUR_DARK_OLIVE_GREEN }, - { "bright_yellow", COLOUR_BRIGHT_YELLOW }, - { "yellow", COLOUR_YELLOW }, - { "dark_yellow", COLOUR_DARK_YELLOW }, - { "light_orange", COLOUR_LIGHT_ORANGE }, - { "dark_orange", COLOUR_DARK_ORANGE }, - { "light_brown", COLOUR_LIGHT_BROWN }, - { "saturated_brown", COLOUR_SATURATED_BROWN }, - { "dark_brown", COLOUR_DARK_BROWN }, - { "salmon_pink", COLOUR_SALMON_PINK }, - { "bordeaux_red", COLOUR_BORDEAUX_RED }, - { "saturated_red", COLOUR_SATURATED_RED }, - { "bright_red", COLOUR_BRIGHT_RED }, - { "dark_pink", COLOUR_DARK_PINK }, - { "bright_pink", COLOUR_BRIGHT_PINK }, - { "light_pink", COLOUR_LIGHT_PINK }, - }; auto result = LookupTable.find(s); return (result != LookupTable.end()) ? result->second : defaultValue; } + } // namespace Colour #ifndef NO_TTF From f44687b6b2e71a00190541c40b4410a50dd7249f Mon Sep 17 00:00:00 2001 From: ZehMatt Date: Thu, 22 Jul 2021 20:21:38 +0300 Subject: [PATCH 3/9] Use EnumMap for lookup tables in scripting --- src/openrct2/scripting/Duktape.hpp | 38 ++----------------------- src/openrct2/scripting/ScriptEngine.cpp | 14 +++++---- 2 files changed, 10 insertions(+), 42 deletions(-) diff --git a/src/openrct2/scripting/Duktape.hpp b/src/openrct2/scripting/Duktape.hpp index fdd7f0f327..95de254bb3 100644 --- a/src/openrct2/scripting/Duktape.hpp +++ b/src/openrct2/scripting/Duktape.hpp @@ -12,6 +12,7 @@ #ifdef ENABLE_SCRIPTING # include "../core/Console.hpp" +# include "../core/EnumMap.hpp" # include "../ride/Vehicle.h" # include "../world/Map.h" @@ -221,42 +222,7 @@ namespace OpenRCT2::Scripting /** * Bi-directional map for converting between strings and enums / numbers. */ - template class DukEnumMap - { - private: - std::unordered_map _s2n; - std::unordered_map _n2s; - - public: - DukEnumMap(const std::initializer_list>& items) - { - _s2n = std::unordered_map(items.begin(), items.end()); - for (const auto& kvp : items) - { - _n2s.emplace(std::get<1>(kvp), std::get<0>(kvp)); - } - } - - std::string_view operator[](T k) const - { - auto it = _n2s.find(k); - if (it == _n2s.end()) - { - return ""; - } - return it->second; - } - - T operator[](std::string_view k) const - { - auto it = _s2n.find(k); - if (it == _s2n.end()) - { - return static_cast(0); - } - return it->second; - } - }; + template using DukEnumMap = EnumMap; inline duk_ret_t duk_json_decode_wrapper(duk_context* ctx, void*) { diff --git a/src/openrct2/scripting/ScriptEngine.cpp b/src/openrct2/scripting/ScriptEngine.cpp index db2f1a1801..d7fb754e89 100644 --- a/src/openrct2/scripting/ScriptEngine.cpp +++ b/src/openrct2/scripting/ScriptEngine.cpp @@ -17,6 +17,7 @@ # include "../actions/RideCreateAction.h" # include "../actions/StaffHireNewAction.h" # include "../config/Config.h" +# include "../core/EnumMap.hpp" # include "../core/File.h" # include "../core/FileScanner.h" # include "../core/Path.hpp" @@ -987,7 +988,8 @@ public: } }; -const static std::unordered_map ActionNameToType = { +// clang-format off +const static EnumMap ActionNameToType = { { "balloonpress", GameCommand::BalloonPress }, { "bannerplace", GameCommand::PlaceBanner }, { "bannerremove", GameCommand::RemoveBanner }, @@ -1067,21 +1069,21 @@ const static std::unordered_map ActionNameToType = { { "waterraise", GameCommand::RaiseWater }, { "watersetheight", GameCommand::SetWaterHeight } }; +// clang-format on static std::string GetActionName(GameCommand commandId) { - auto it = std::find_if( - ActionNameToType.begin(), ActionNameToType.end(), [commandId](const auto& kvp) { return kvp.second == commandId; }); + auto it = ActionNameToType.find(commandId); if (it != ActionNameToType.end()) { - return it->first; + return std::string{ it->first }; } return {}; } -static std::unique_ptr CreateGameActionFromActionId(const std::string& actionid) +static std::unique_ptr CreateGameActionFromActionId(const std::string& name) { - auto result = ActionNameToType.find(actionid); + auto result = ActionNameToType.find(name); if (result != ActionNameToType.end()) { return GameActions::Create(result->second); From 3fbfa26dd3602edd0c550d254d961cc42009f191 Mon Sep 17 00:00:00 2001 From: ZehMatt Date: Thu, 22 Jul 2021 20:22:47 +0300 Subject: [PATCH 4/9] Use EnumMap for Cursors string lookup --- src/openrct2/interface/Cursors.cpp | 62 +++++++++++++++--------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/src/openrct2/interface/Cursors.cpp b/src/openrct2/interface/Cursors.cpp index 01054812f3..5bf0051d46 100644 --- a/src/openrct2/interface/Cursors.cpp +++ b/src/openrct2/interface/Cursors.cpp @@ -9,43 +9,45 @@ #include "Cursors.h" +#include "../core/EnumMap.hpp" + #include -#include namespace Cursor { + static const EnumMap LookupTable{ + { "CURSOR_BLANK", CursorID::Blank }, + { "CURSOR_UP_ARROW", CursorID::UpArrow }, + { "CURSOR_UP_DOWN_ARROW", CursorID::UpDownArrow }, + { "CURSOR_HAND_POINT", CursorID::HandPoint }, + { "CURSOR_ZZZ", CursorID::ZZZ }, + { "CURSOR_DIAGONAL_ARROWS", CursorID::DiagonalArrows }, + { "CURSOR_PICKER", CursorID::Picker }, + { "CURSOR_TREE_DOWN", CursorID::TreeDown }, + { "CURSOR_FOUNTAIN_DOWN", CursorID::FountainDown }, + { "CURSOR_STATUE_DOWN", CursorID::StatueDown }, + { "CURSOR_BENCH_DOWN", CursorID::BenchDown }, + { "CURSOR_CROSS_HAIR", CursorID::CrossHair }, + { "CURSOR_BIN_DOWN", CursorID::BinDown }, + { "CURSOR_LAMPPOST_DOWN", CursorID::LamppostDown }, + { "CURSOR_FENCE_DOWN", CursorID::FenceDown }, + { "CURSOR_FLOWER_DOWN", CursorID::FlowerDown }, + { "CURSOR_PATH_DOWN", CursorID::PathDown }, + { "CURSOR_DIG_DOWN", CursorID::DigDown }, + { "CURSOR_WATER_DOWN", CursorID::WaterDown }, + { "CURSOR_HOUSE_DOWN", CursorID::HouseDown }, + { "CURSOR_VOLCANO_DOWN", CursorID::VolcanoDown }, + { "CURSOR_WALK_DOWN", CursorID::WalkDown }, + { "CURSOR_PAINT_DOWN", CursorID::PaintDown }, + { "CURSOR_ENTRANCE_DOWN", CursorID::EntranceDown }, + { "CURSOR_HAND_OPEN", CursorID::HandOpen }, + { "CURSOR_HAND_CLOSED", CursorID::HandClosed }, + { "CURSOR_ARROW", CursorID::Arrow }, + }; + CursorID FromString(const std::string& s, CursorID defaultValue) { assert(defaultValue != CursorID::Undefined); - static const std::unordered_map LookupTable{ - { "CURSOR_BLANK", CursorID::Blank }, - { "CURSOR_UP_ARROW", CursorID::UpArrow }, - { "CURSOR_UP_DOWN_ARROW", CursorID::UpDownArrow }, - { "CURSOR_HAND_POINT", CursorID::HandPoint }, - { "CURSOR_ZZZ", CursorID::ZZZ }, - { "CURSOR_DIAGONAL_ARROWS", CursorID::DiagonalArrows }, - { "CURSOR_PICKER", CursorID::Picker }, - { "CURSOR_TREE_DOWN", CursorID::TreeDown }, - { "CURSOR_FOUNTAIN_DOWN", CursorID::FountainDown }, - { "CURSOR_STATUE_DOWN", CursorID::StatueDown }, - { "CURSOR_BENCH_DOWN", CursorID::BenchDown }, - { "CURSOR_CROSS_HAIR", CursorID::CrossHair }, - { "CURSOR_BIN_DOWN", CursorID::BinDown }, - { "CURSOR_LAMPPOST_DOWN", CursorID::LamppostDown }, - { "CURSOR_FENCE_DOWN", CursorID::FenceDown }, - { "CURSOR_FLOWER_DOWN", CursorID::FlowerDown }, - { "CURSOR_PATH_DOWN", CursorID::PathDown }, - { "CURSOR_DIG_DOWN", CursorID::DigDown }, - { "CURSOR_WATER_DOWN", CursorID::WaterDown }, - { "CURSOR_HOUSE_DOWN", CursorID::HouseDown }, - { "CURSOR_VOLCANO_DOWN", CursorID::VolcanoDown }, - { "CURSOR_WALK_DOWN", CursorID::WalkDown }, - { "CURSOR_PAINT_DOWN", CursorID::PaintDown }, - { "CURSOR_ENTRANCE_DOWN", CursorID::EntranceDown }, - { "CURSOR_HAND_OPEN", CursorID::HandOpen }, - { "CURSOR_HAND_CLOSED", CursorID::HandClosed }, - { "CURSOR_ARROW", CursorID::Arrow }, - }; auto result = LookupTable.find(s); return (result != LookupTable.end()) ? result->second : defaultValue; From e991c128dcdcf2c257092b54b0988be16625dbc5 Mon Sep 17 00:00:00 2001 From: ZehMatt Date: Thu, 22 Jul 2021 20:25:38 +0300 Subject: [PATCH 5/9] Use EnumMap for format token lookups --- src/openrct2/localisation/FormatCodes.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/openrct2/localisation/FormatCodes.cpp b/src/openrct2/localisation/FormatCodes.cpp index 204afcaa11..2b5c408520 100644 --- a/src/openrct2/localisation/FormatCodes.cpp +++ b/src/openrct2/localisation/FormatCodes.cpp @@ -9,13 +9,14 @@ #include "FormatCodes.h" +#include "../core/EnumMap.hpp" + #include #include -#include #include // clang-format off -static const std::unordered_map FormatTokenMap = { +static const EnumMap FormatTokenMap = { { "MOVE_X", FormatToken::Move, }, { "NEWLINE", FormatToken::Newline, }, { "NEWLINE_SMALLER", FormatToken::NewlineSmall, }, @@ -97,13 +98,10 @@ std::string_view FormatTokenToString(FormatToken token, bool withBraces) } else { - for (const auto& t : FormatTokenMap) - { - if (t.second == token) - { - return t.first; - } - } + auto it = FormatTokenMap.find(token); + if (it != FormatTokenMap.end()) + return it->first; + return {}; } } From e520e4f991efc897d894aefc3b5926ad53414ed5 Mon Sep 17 00:00:00 2001 From: ZehMatt Date: Thu, 22 Jul 2021 20:29:17 +0300 Subject: [PATCH 6/9] Use EnumMap for RideObject lookup tables --- src/openrct2/object/RideObject.cpp | 286 +++++++++++++++-------------- 1 file changed, 145 insertions(+), 141 deletions(-) diff --git a/src/openrct2/object/RideObject.cpp b/src/openrct2/object/RideObject.cpp index b475785b5b..fa2f76a39a 100644 --- a/src/openrct2/object/RideObject.cpp +++ b/src/openrct2/object/RideObject.cpp @@ -13,6 +13,7 @@ #include "../OpenRCT2.h" #include "../audio/audio.h" +#include "../core/EnumMap.hpp" #include "../core/IStream.hpp" #include "../core/Json.hpp" #include "../core/Memory.hpp" @@ -969,155 +970,158 @@ bool RideObject::IsRideTypeShopOrFacility(uint8_t rideType) } } +static const EnumMap RideTypeLookupTable{ + { "spiral_rc", RIDE_TYPE_SPIRAL_ROLLER_COASTER }, + { "stand_up_rc", RIDE_TYPE_STAND_UP_ROLLER_COASTER }, + { "suspended_swinging_rc", RIDE_TYPE_SUSPENDED_SWINGING_COASTER }, + { "inverted_rc", RIDE_TYPE_INVERTED_ROLLER_COASTER }, + { "junior_rc", RIDE_TYPE_JUNIOR_ROLLER_COASTER }, + { "miniature_railway", RIDE_TYPE_MINIATURE_RAILWAY }, + { "monorail", RIDE_TYPE_MONORAIL }, + { "mini_suspended_rc", RIDE_TYPE_MINI_SUSPENDED_COASTER }, + { "boat_hire", RIDE_TYPE_BOAT_HIRE }, + { "wooden_wild_mouse", RIDE_TYPE_WOODEN_WILD_MOUSE }, + { "steeplechase", RIDE_TYPE_STEEPLECHASE }, + { "car_ride", RIDE_TYPE_CAR_RIDE }, + { "launched_freefall", RIDE_TYPE_LAUNCHED_FREEFALL }, + { "bobsleigh_rc", RIDE_TYPE_BOBSLEIGH_COASTER }, + { "observation_tower", RIDE_TYPE_OBSERVATION_TOWER }, + { "looping_rc", RIDE_TYPE_LOOPING_ROLLER_COASTER }, + { "dinghy_slide", RIDE_TYPE_DINGHY_SLIDE }, + { "mine_train_rc", RIDE_TYPE_MINE_TRAIN_COASTER }, + { "chairlift", RIDE_TYPE_CHAIRLIFT }, + { "corkscrew_rc", RIDE_TYPE_CORKSCREW_ROLLER_COASTER }, + { "maze", RIDE_TYPE_MAZE }, + { "spiral_slide", RIDE_TYPE_SPIRAL_SLIDE }, + { "go_karts", RIDE_TYPE_GO_KARTS }, + { "log_flume", RIDE_TYPE_LOG_FLUME }, + { "river_rapids", RIDE_TYPE_RIVER_RAPIDS }, + { "dodgems", RIDE_TYPE_DODGEMS }, + { "swinging_ship", RIDE_TYPE_SWINGING_SHIP }, + { "swinging_inverter_ship", RIDE_TYPE_SWINGING_INVERTER_SHIP }, + { "food_stall", RIDE_TYPE_FOOD_STALL }, + { "drink_stall", RIDE_TYPE_DRINK_STALL }, + { "shop", RIDE_TYPE_SHOP }, + { "merry_go_round", RIDE_TYPE_MERRY_GO_ROUND }, + { "information_kiosk", RIDE_TYPE_INFORMATION_KIOSK }, + { "toilets", RIDE_TYPE_TOILETS }, + { "ferris_wheel", RIDE_TYPE_FERRIS_WHEEL }, + { "motion_simulator", RIDE_TYPE_MOTION_SIMULATOR }, + { "3d_cinema", RIDE_TYPE_3D_CINEMA }, + { "top_spin", RIDE_TYPE_TOP_SPIN }, + { "space_rings", RIDE_TYPE_SPACE_RINGS }, + { "reverse_freefall_rc", RIDE_TYPE_REVERSE_FREEFALL_COASTER }, + { "lift", RIDE_TYPE_LIFT }, + { "vertical_drop_rc", RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER }, + { "cash_machine", RIDE_TYPE_CASH_MACHINE }, + { "twist", RIDE_TYPE_TWIST }, + { "haunted_house", RIDE_TYPE_HAUNTED_HOUSE }, + { "first_aid", RIDE_TYPE_FIRST_AID }, + { "circus", RIDE_TYPE_CIRCUS }, + { "ghost_train", RIDE_TYPE_GHOST_TRAIN }, + { "twister_rc", RIDE_TYPE_TWISTER_ROLLER_COASTER }, + { "wooden_rc", RIDE_TYPE_WOODEN_ROLLER_COASTER }, + { "side_friction_rc", RIDE_TYPE_SIDE_FRICTION_ROLLER_COASTER }, + { "steel_wild_mouse", RIDE_TYPE_STEEL_WILD_MOUSE }, + { "multi_dimension_rc", RIDE_TYPE_MULTI_DIMENSION_ROLLER_COASTER }, + { "flying_rc", RIDE_TYPE_FLYING_ROLLER_COASTER }, + { "virginia_reel", RIDE_TYPE_VIRGINIA_REEL }, + { "splash_boats", RIDE_TYPE_SPLASH_BOATS }, + { "mini_helicopters", RIDE_TYPE_MINI_HELICOPTERS }, + { "lay_down_rc", RIDE_TYPE_LAY_DOWN_ROLLER_COASTER }, + { "suspended_monorail", RIDE_TYPE_SUSPENDED_MONORAIL }, + { "reverser_rc", RIDE_TYPE_REVERSER_ROLLER_COASTER }, + { "heartline_twister_rc", RIDE_TYPE_HEARTLINE_TWISTER_COASTER }, + { "mini_golf", RIDE_TYPE_MINI_GOLF }, + { "giga_rc", RIDE_TYPE_GIGA_COASTER }, + { "roto_drop", RIDE_TYPE_ROTO_DROP }, + { "flying_saucers", RIDE_TYPE_FLYING_SAUCERS }, + { "crooked_house", RIDE_TYPE_CROOKED_HOUSE }, + { "monorail_cycles", RIDE_TYPE_MONORAIL_CYCLES }, + { "compact_inverted_rc", RIDE_TYPE_COMPACT_INVERTED_COASTER }, + { "water_coaster", RIDE_TYPE_WATER_COASTER }, + { "air_powered_vertical_rc", RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER }, + { "inverted_hairpin_rc", RIDE_TYPE_INVERTED_HAIRPIN_COASTER }, + { "magic_carpet", RIDE_TYPE_MAGIC_CARPET }, + { "submarine_ride", RIDE_TYPE_SUBMARINE_RIDE }, + { "river_rafts", RIDE_TYPE_RIVER_RAFTS }, + { "enterprise", RIDE_TYPE_ENTERPRISE }, + { "inverted_impulse_rc", RIDE_TYPE_INVERTED_IMPULSE_COASTER }, + { "mini_rc", RIDE_TYPE_MINI_ROLLER_COASTER }, + { "mine_ride", RIDE_TYPE_MINE_RIDE }, + { "lim_launched_rc", RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER }, + { "hypercoaster", RIDE_TYPE_HYPERCOASTER }, + { "hyper_twister", RIDE_TYPE_HYPER_TWISTER }, + { "monster_trucks", RIDE_TYPE_MONSTER_TRUCKS }, + { "spinning_wild_mouse", RIDE_TYPE_SPINNING_WILD_MOUSE }, + { "classic_mini_rc", RIDE_TYPE_CLASSIC_MINI_ROLLER_COASTER }, + { "hybrid_rc", RIDE_TYPE_HYBRID_COASTER }, + { "single_rail_rc", RIDE_TYPE_SINGLE_RAIL_ROLLER_COASTER }, +}; + uint8_t RideObject::ParseRideType(const std::string& s) { - static const std::unordered_map LookupTable{ - { "spiral_rc", RIDE_TYPE_SPIRAL_ROLLER_COASTER }, - { "stand_up_rc", RIDE_TYPE_STAND_UP_ROLLER_COASTER }, - { "suspended_swinging_rc", RIDE_TYPE_SUSPENDED_SWINGING_COASTER }, - { "inverted_rc", RIDE_TYPE_INVERTED_ROLLER_COASTER }, - { "junior_rc", RIDE_TYPE_JUNIOR_ROLLER_COASTER }, - { "miniature_railway", RIDE_TYPE_MINIATURE_RAILWAY }, - { "monorail", RIDE_TYPE_MONORAIL }, - { "mini_suspended_rc", RIDE_TYPE_MINI_SUSPENDED_COASTER }, - { "boat_hire", RIDE_TYPE_BOAT_HIRE }, - { "wooden_wild_mouse", RIDE_TYPE_WOODEN_WILD_MOUSE }, - { "steeplechase", RIDE_TYPE_STEEPLECHASE }, - { "car_ride", RIDE_TYPE_CAR_RIDE }, - { "launched_freefall", RIDE_TYPE_LAUNCHED_FREEFALL }, - { "bobsleigh_rc", RIDE_TYPE_BOBSLEIGH_COASTER }, - { "observation_tower", RIDE_TYPE_OBSERVATION_TOWER }, - { "looping_rc", RIDE_TYPE_LOOPING_ROLLER_COASTER }, - { "dinghy_slide", RIDE_TYPE_DINGHY_SLIDE }, - { "mine_train_rc", RIDE_TYPE_MINE_TRAIN_COASTER }, - { "chairlift", RIDE_TYPE_CHAIRLIFT }, - { "corkscrew_rc", RIDE_TYPE_CORKSCREW_ROLLER_COASTER }, - { "maze", RIDE_TYPE_MAZE }, - { "spiral_slide", RIDE_TYPE_SPIRAL_SLIDE }, - { "go_karts", RIDE_TYPE_GO_KARTS }, - { "log_flume", RIDE_TYPE_LOG_FLUME }, - { "river_rapids", RIDE_TYPE_RIVER_RAPIDS }, - { "dodgems", RIDE_TYPE_DODGEMS }, - { "swinging_ship", RIDE_TYPE_SWINGING_SHIP }, - { "swinging_inverter_ship", RIDE_TYPE_SWINGING_INVERTER_SHIP }, - { "food_stall", RIDE_TYPE_FOOD_STALL }, - { "drink_stall", RIDE_TYPE_DRINK_STALL }, - { "shop", RIDE_TYPE_SHOP }, - { "merry_go_round", RIDE_TYPE_MERRY_GO_ROUND }, - { "information_kiosk", RIDE_TYPE_INFORMATION_KIOSK }, - { "toilets", RIDE_TYPE_TOILETS }, - { "ferris_wheel", RIDE_TYPE_FERRIS_WHEEL }, - { "motion_simulator", RIDE_TYPE_MOTION_SIMULATOR }, - { "3d_cinema", RIDE_TYPE_3D_CINEMA }, - { "top_spin", RIDE_TYPE_TOP_SPIN }, - { "space_rings", RIDE_TYPE_SPACE_RINGS }, - { "reverse_freefall_rc", RIDE_TYPE_REVERSE_FREEFALL_COASTER }, - { "lift", RIDE_TYPE_LIFT }, - { "vertical_drop_rc", RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER }, - { "cash_machine", RIDE_TYPE_CASH_MACHINE }, - { "twist", RIDE_TYPE_TWIST }, - { "haunted_house", RIDE_TYPE_HAUNTED_HOUSE }, - { "first_aid", RIDE_TYPE_FIRST_AID }, - { "circus", RIDE_TYPE_CIRCUS }, - { "ghost_train", RIDE_TYPE_GHOST_TRAIN }, - { "twister_rc", RIDE_TYPE_TWISTER_ROLLER_COASTER }, - { "wooden_rc", RIDE_TYPE_WOODEN_ROLLER_COASTER }, - { "side_friction_rc", RIDE_TYPE_SIDE_FRICTION_ROLLER_COASTER }, - { "steel_wild_mouse", RIDE_TYPE_STEEL_WILD_MOUSE }, - { "multi_dimension_rc", RIDE_TYPE_MULTI_DIMENSION_ROLLER_COASTER }, - { "flying_rc", RIDE_TYPE_FLYING_ROLLER_COASTER }, - { "virginia_reel", RIDE_TYPE_VIRGINIA_REEL }, - { "splash_boats", RIDE_TYPE_SPLASH_BOATS }, - { "mini_helicopters", RIDE_TYPE_MINI_HELICOPTERS }, - { "lay_down_rc", RIDE_TYPE_LAY_DOWN_ROLLER_COASTER }, - { "suspended_monorail", RIDE_TYPE_SUSPENDED_MONORAIL }, - { "reverser_rc", RIDE_TYPE_REVERSER_ROLLER_COASTER }, - { "heartline_twister_rc", RIDE_TYPE_HEARTLINE_TWISTER_COASTER }, - { "mini_golf", RIDE_TYPE_MINI_GOLF }, - { "giga_rc", RIDE_TYPE_GIGA_COASTER }, - { "roto_drop", RIDE_TYPE_ROTO_DROP }, - { "flying_saucers", RIDE_TYPE_FLYING_SAUCERS }, - { "crooked_house", RIDE_TYPE_CROOKED_HOUSE }, - { "monorail_cycles", RIDE_TYPE_MONORAIL_CYCLES }, - { "compact_inverted_rc", RIDE_TYPE_COMPACT_INVERTED_COASTER }, - { "water_coaster", RIDE_TYPE_WATER_COASTER }, - { "air_powered_vertical_rc", RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER }, - { "inverted_hairpin_rc", RIDE_TYPE_INVERTED_HAIRPIN_COASTER }, - { "magic_carpet", RIDE_TYPE_MAGIC_CARPET }, - { "submarine_ride", RIDE_TYPE_SUBMARINE_RIDE }, - { "river_rafts", RIDE_TYPE_RIVER_RAFTS }, - { "enterprise", RIDE_TYPE_ENTERPRISE }, - { "inverted_impulse_rc", RIDE_TYPE_INVERTED_IMPULSE_COASTER }, - { "mini_rc", RIDE_TYPE_MINI_ROLLER_COASTER }, - { "mine_ride", RIDE_TYPE_MINE_RIDE }, - { "lim_launched_rc", RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER }, - { "hypercoaster", RIDE_TYPE_HYPERCOASTER }, - { "hyper_twister", RIDE_TYPE_HYPER_TWISTER }, - { "monster_trucks", RIDE_TYPE_MONSTER_TRUCKS }, - { "spinning_wild_mouse", RIDE_TYPE_SPINNING_WILD_MOUSE }, - { "classic_mini_rc", RIDE_TYPE_CLASSIC_MINI_ROLLER_COASTER }, - { "hybrid_rc", RIDE_TYPE_HYBRID_COASTER }, - { "single_rail_rc", RIDE_TYPE_SINGLE_RAIL_ROLLER_COASTER } - }; - auto result = LookupTable.find(s); - return (result != LookupTable.end()) ? result->second : static_cast(RIDE_TYPE_NULL); + auto result = RideTypeLookupTable.find(s); + return (result != RideTypeLookupTable.end()) ? result->second : static_cast(RIDE_TYPE_NULL); } +static const EnumMap RideCategoryLookupTable{ + { "transport", RIDE_CATEGORY_TRANSPORT }, + { "gentle", RIDE_CATEGORY_GENTLE }, + { "rollercoaster", RIDE_CATEGORY_ROLLERCOASTER }, + { "thrill", RIDE_CATEGORY_THRILL }, + { "water", RIDE_CATEGORY_WATER }, + { "stall", RIDE_CATEGORY_SHOP }, +}; + uint8_t RideObject::ParseRideCategory(const std::string& s) { - static const std::unordered_map LookupTable{ - { "transport", RIDE_CATEGORY_TRANSPORT }, - { "gentle", RIDE_CATEGORY_GENTLE }, - { "rollercoaster", RIDE_CATEGORY_ROLLERCOASTER }, - { "thrill", RIDE_CATEGORY_THRILL }, - { "water", RIDE_CATEGORY_WATER }, - { "stall", RIDE_CATEGORY_SHOP }, - }; - auto result = LookupTable.find(s); - return (result != LookupTable.end()) ? result->second : static_cast(RIDE_CATEGORY_TRANSPORT); + auto result = RideCategoryLookupTable.find(s); + return (result != RideCategoryLookupTable.end()) ? result->second : static_cast(RIDE_CATEGORY_TRANSPORT); } +static const EnumMap ShopItemLookupTable{ + { "burger", ShopItem::Burger }, + { "chips", ShopItem::Chips }, + { "ice_cream", ShopItem::IceCream }, + { "candyfloss", ShopItem::Candyfloss }, + { "pizza", ShopItem::Pizza }, + { "popcorn", ShopItem::Popcorn }, + { "hot_dog", ShopItem::HotDog }, + { "tentacle", ShopItem::Tentacle }, + { "toffee_apple", ShopItem::ToffeeApple }, + { "doughnut", ShopItem::Doughnut }, + { "chicken", ShopItem::Chicken }, + { "pretzel", ShopItem::Pretzel }, + { "funnel_cake", ShopItem::FunnelCake }, + { "beef_noodles", ShopItem::BeefNoodles }, + { "fried_rice_noodles", ShopItem::FriedRiceNoodles }, + { "wonton_soup", ShopItem::WontonSoup }, + { "meatball_soup", ShopItem::MeatballSoup }, + { "sub_sandwich", ShopItem::SubSandwich }, + { "cookie", ShopItem::Cookie }, + { "roast_sausage", ShopItem::RoastSausage }, + { "drink", ShopItem::Drink }, + { "coffee", ShopItem::Coffee }, + { "lemonade", ShopItem::Lemonade }, + { "chocolate", ShopItem::Chocolate }, + { "iced_tea", ShopItem::IcedTea }, + { "fruit_juice", ShopItem::FruitJuice }, + { "soybean_milk", ShopItem::SoybeanMilk }, + { "sujeonggwa", ShopItem::Sujeonggwa }, + { "balloon", ShopItem::Balloon }, + { "toy", ShopItem::Toy }, + { "map", ShopItem::Map }, + { "photo", ShopItem::Photo }, + { "umbrella", ShopItem::Umbrella }, + { "voucher", ShopItem::Voucher }, + { "hat", ShopItem::Hat }, + { "tshirt", ShopItem::TShirt }, + { "sunglasses", ShopItem::Sunglasses }, +}; + ShopItem RideObject::ParseShopItem(const std::string& s) { - static const std::unordered_map LookupTable{ - { "burger", ShopItem::Burger }, - { "chips", ShopItem::Chips }, - { "ice_cream", ShopItem::IceCream }, - { "candyfloss", ShopItem::Candyfloss }, - { "pizza", ShopItem::Pizza }, - { "popcorn", ShopItem::Popcorn }, - { "hot_dog", ShopItem::HotDog }, - { "tentacle", ShopItem::Tentacle }, - { "toffee_apple", ShopItem::ToffeeApple }, - { "doughnut", ShopItem::Doughnut }, - { "chicken", ShopItem::Chicken }, - { "pretzel", ShopItem::Pretzel }, - { "funnel_cake", ShopItem::FunnelCake }, - { "beef_noodles", ShopItem::BeefNoodles }, - { "fried_rice_noodles", ShopItem::FriedRiceNoodles }, - { "wonton_soup", ShopItem::WontonSoup }, - { "meatball_soup", ShopItem::MeatballSoup }, - { "sub_sandwich", ShopItem::SubSandwich }, - { "cookie", ShopItem::Cookie }, - { "roast_sausage", ShopItem::RoastSausage }, - { "drink", ShopItem::Drink }, - { "coffee", ShopItem::Coffee }, - { "lemonade", ShopItem::Lemonade }, - { "chocolate", ShopItem::Chocolate }, - { "iced_tea", ShopItem::IcedTea }, - { "fruit_juice", ShopItem::FruitJuice }, - { "soybean_milk", ShopItem::SoybeanMilk }, - { "sujeonggwa", ShopItem::Sujeonggwa }, - { "balloon", ShopItem::Balloon }, - { "toy", ShopItem::Toy }, - { "map", ShopItem::Map }, - { "photo", ShopItem::Photo }, - { "umbrella", ShopItem::Umbrella }, - { "voucher", ShopItem::Voucher }, - { "hat", ShopItem::Hat }, - { "tshirt", ShopItem::TShirt }, - { "sunglasses", ShopItem::Sunglasses }, - }; - auto result = LookupTable.find(s); - return (result != LookupTable.end()) ? result->second : ShopItem::None; + auto result = ShopItemLookupTable.find(s); + return (result != ShopItemLookupTable.end()) ? result->second : ShopItem::None; } From d9f9e7542ae5747d53d34f106b514c85db822a35 Mon Sep 17 00:00:00 2001 From: ZehMatt Date: Thu, 22 Jul 2021 20:51:15 +0300 Subject: [PATCH 7/9] Use EnumMap for HookEngine lookups --- src/openrct2/scripting/HookEngine.cpp | 32 ++++++++++++++------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/openrct2/scripting/HookEngine.cpp b/src/openrct2/scripting/HookEngine.cpp index 266c7050d2..e857a41025 100644 --- a/src/openrct2/scripting/HookEngine.cpp +++ b/src/openrct2/scripting/HookEngine.cpp @@ -11,29 +11,31 @@ # include "HookEngine.h" +# include "../core/EnumMap.hpp" # include "ScriptEngine.h" # include using namespace OpenRCT2::Scripting; +static const EnumMap HooksLookupTable({ + { "action.query", HOOK_TYPE::ACTION_QUERY }, + { "action.execute", HOOK_TYPE::ACTION_EXECUTE }, + { "interval.tick", HOOK_TYPE::INTERVAL_TICK }, + { "interval.day", HOOK_TYPE::INTERVAL_DAY }, + { "network.chat", HOOK_TYPE::NETWORK_CHAT }, + { "network.authenticate", HOOK_TYPE::NETWORK_AUTHENTICATE }, + { "network.join", HOOK_TYPE::NETWORK_JOIN }, + { "network.leave", HOOK_TYPE::NETWORK_LEAVE }, + { "ride.ratings.calculate", HOOK_TYPE::RIDE_RATINGS_CALCULATE }, + { "action.location", HOOK_TYPE::ACTION_LOCATION }, + { "guest.generation", HOOK_TYPE::GUEST_GENERATION }, +}); + HOOK_TYPE OpenRCT2::Scripting::GetHookType(const std::string& name) { - static const std::unordered_map LookupTable({ - { "action.query", HOOK_TYPE::ACTION_QUERY }, - { "action.execute", HOOK_TYPE::ACTION_EXECUTE }, - { "interval.tick", HOOK_TYPE::INTERVAL_TICK }, - { "interval.day", HOOK_TYPE::INTERVAL_DAY }, - { "network.chat", HOOK_TYPE::NETWORK_CHAT }, - { "network.authenticate", HOOK_TYPE::NETWORK_AUTHENTICATE }, - { "network.join", HOOK_TYPE::NETWORK_JOIN }, - { "network.leave", HOOK_TYPE::NETWORK_LEAVE }, - { "ride.ratings.calculate", HOOK_TYPE::RIDE_RATINGS_CALCULATE }, - { "action.location", HOOK_TYPE::ACTION_LOCATION }, - { "guest.generation", HOOK_TYPE::GUEST_GENERATION }, - }); - auto result = LookupTable.find(name); - return (result != LookupTable.end()) ? result->second : HOOK_TYPE::UNDEFINED; + auto result = HooksLookupTable.find(name); + return (result != HooksLookupTable.end()) ? result->second : HOOK_TYPE::UNDEFINED; } HookEngine::HookEngine(ScriptEngine& scriptEngine) From cd43cab9991d87d4305a4d7f9b668ce8d7214da5 Mon Sep 17 00:00:00 2001 From: ZehMatt Date: Thu, 22 Jul 2021 20:51:28 +0300 Subject: [PATCH 8/9] Add tests for EnumMap --- test/tests/CMakeLists.txt | 9 +++ test/tests/EnumMapTest.cpp | 146 +++++++++++++++++++++++++++++++++++++ test/tests/tests.vcxproj | 1 + 3 files changed, 156 insertions(+) create mode 100644 test/tests/EnumMapTest.cpp diff --git a/test/tests/CMakeLists.txt b/test/tests/CMakeLists.txt index 191c63e1e9..703871f2d9 100644 --- a/test/tests/CMakeLists.txt +++ b/test/tests/CMakeLists.txt @@ -248,3 +248,12 @@ SET_CHECK_CXX_FLAGS(test_s6importexporttests) target_link_libraries(test_s6importexporttests ${GTEST_LIBRARIES} libopenrct2 ${LDL} z) target_link_platform_libraries(test_s6importexporttests) add_test(NAME s6importexporttests COMMAND test_s6importexporttests) + +# EnumMap Test +set(ENUMMAP_TEST_SOURCES "${CMAKE_CURRENT_LIST_DIR}/EnumMapTest.cpp.cpp" + "${CMAKE_CURRENT_LIST_DIR}/TestData.cpp") +add_executable(test_enummap ${S6IMPORTEXPORT_TEST_SOURCES}) +SET_CHECK_CXX_FLAGS(test_enummap) +target_link_libraries(test_enummap ${GTEST_LIBRARIES} libopenrct2 ${LDL} z) +target_link_platform_libraries(test_enummap) +add_test(NAME enummaptests COMMAND test_enummap) diff --git a/test/tests/EnumMapTest.cpp b/test/tests/EnumMapTest.cpp new file mode 100644 index 0000000000..98efbc8e73 --- /dev/null +++ b/test/tests/EnumMapTest.cpp @@ -0,0 +1,146 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ +#include +#include + +enum class TestEnumClassContinous +{ + A, + B, + C, + D, + E, + F, + G +}; + +enum class TestEnumClassNonContinous +{ + A = 1, + B, + C = 7, + D, + E, + F, + G +}; + +template void TestEnumKeyLookup() +{ + // clang-format off + EnumMap enumMap = { + { "A", TEnum::A }, + { "B", TEnum::B }, + { "C", TEnum::C }, + { "D", TEnum::D }, + { "E", TEnum::E }, + { "F", TEnum::F }, + { "G", TEnum::G }, + }; + // clang-format on + + ASSERT_EQ(enumMap.find("Z"), enumMap.end()); + + auto itA = enumMap.find("A"); + ASSERT_NE(itA, enumMap.end()); + ASSERT_EQ(itA->second, TEnum::A); + + auto itB = enumMap.find("B"); + ASSERT_NE(itB, enumMap.end()); + ASSERT_EQ(itB->second, TEnum::B); + + auto itC = enumMap.find("C"); + ASSERT_NE(itC, enumMap.end()); + ASSERT_EQ(itC->second, TEnum::C); + + auto itD = enumMap.find("D"); + ASSERT_NE(itD, enumMap.end()); + ASSERT_EQ(itD->second, TEnum::D); + + auto itE = enumMap.find("E"); + ASSERT_NE(itE, enumMap.end()); + ASSERT_EQ(itE->second, TEnum::E); + + auto itF = enumMap.find("F"); + ASSERT_NE(itF, enumMap.end()); + ASSERT_EQ(itF->second, TEnum::F); + + auto itG = enumMap.find("G"); + ASSERT_NE(itG, enumMap.end()); + ASSERT_EQ(itG->second, TEnum::G); + + SUCCEED(); +} + +template void TestEnumValueLookup() +{ + // clang-format off + EnumMap enumMap = { + { "A", TEnum::A }, + { "B", TEnum::B }, + { "C", TEnum::C }, + { "D", TEnum::D }, + { "E", TEnum::E }, + { "F", TEnum::F }, + { "G", TEnum::G }, + }; + // clang-format on + + ASSERT_EQ(enumMap.find("Z"), enumMap.end()); + + auto itA = enumMap.find(TEnum::A); + ASSERT_NE(itA, enumMap.end()); + ASSERT_EQ(itA->second, TEnum::A); + + auto itB = enumMap.find(TEnum::B); + ASSERT_NE(itB, enumMap.end()); + ASSERT_EQ(itB->second, TEnum::B); + + auto itC = enumMap.find(TEnum::C); + ASSERT_NE(itC, enumMap.end()); + ASSERT_EQ(itC->second, TEnum::C); + + auto itD = enumMap.find(TEnum::D); + ASSERT_NE(itD, enumMap.end()); + ASSERT_EQ(itD->second, TEnum::D); + + auto itE = enumMap.find(TEnum::E); + ASSERT_NE(itE, enumMap.end()); + ASSERT_EQ(itE->second, TEnum::E); + + auto itF = enumMap.find(TEnum::F); + ASSERT_NE(itF, enumMap.end()); + ASSERT_EQ(itF->second, TEnum::F); + + auto itG = enumMap.find(TEnum::G); + ASSERT_NE(itG, enumMap.end()); + ASSERT_EQ(itG->second, TEnum::G); + + SUCCEED(); +} + +TEST(EnumMapTest, LookupContinousByKey) +{ + TestEnumKeyLookup(); +} + +TEST(EnumMapTest, LookupContiniousByValue) +{ + TestEnumValueLookup(); +} + +TEST(EnumMapTest, LookupNonContinousByKey) +{ + TestEnumKeyLookup(); +} + +TEST(EnumMapTest, LookupNonContiniousByValue) +{ + TestEnumValueLookup(); +} diff --git a/test/tests/tests.vcxproj b/test/tests/tests.vcxproj index 53a49a7ca0..a49cf5a70c 100644 --- a/test/tests/tests.vcxproj +++ b/test/tests/tests.vcxproj @@ -60,6 +60,7 @@ + From 86af7f486d7ab70d67df7034db2d083332b66116 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Thu, 29 Jul 2021 13:02:20 +0200 Subject: [PATCH 9/9] =?UTF-8?q?Fix=20spelling=20of=20=E2=80=9Ccontinuous?= =?UTF-8?q?=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/tests/EnumMapTest.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/tests/EnumMapTest.cpp b/test/tests/EnumMapTest.cpp index 98efbc8e73..f6d54f6321 100644 --- a/test/tests/EnumMapTest.cpp +++ b/test/tests/EnumMapTest.cpp @@ -9,7 +9,7 @@ #include #include -enum class TestEnumClassContinous +enum class TestEnumClassContinuous { A, B, @@ -20,7 +20,7 @@ enum class TestEnumClassContinous G }; -enum class TestEnumClassNonContinous +enum class TestEnumClassNonContinuous { A = 1, B, @@ -125,22 +125,22 @@ template void TestEnumValueLookup() SUCCEED(); } -TEST(EnumMapTest, LookupContinousByKey) +TEST(EnumMapTest, LookupContinuousByKey) { - TestEnumKeyLookup(); + TestEnumKeyLookup(); } -TEST(EnumMapTest, LookupContiniousByValue) +TEST(EnumMapTest, LookupContinuousByValue) { - TestEnumValueLookup(); + TestEnumValueLookup(); } -TEST(EnumMapTest, LookupNonContinousByKey) +TEST(EnumMapTest, LookupNonContinuousByKey) { - TestEnumKeyLookup(); + TestEnumKeyLookup(); } -TEST(EnumMapTest, LookupNonContiniousByValue) +TEST(EnumMapTest, LookupNonContinuousByValue) { - TestEnumValueLookup(); + TestEnumValueLookup(); }