mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-23 14:54:30 +01:00
Merge pull request #15058 from ZehMatt/enummap
Refactor lookup tables to use EnumMap
This commit is contained in:
@@ -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 = "<group>";
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
157
src/openrct2/core/EnumMap.hpp
Normal file
157
src/openrct2/core/EnumMap.hpp
Normal file
@@ -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 <algorithm>
|
||||
#include <array>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Bi-directional map for converting between strings and enums / numbers.
|
||||
*/
|
||||
template<typename T> class EnumMap
|
||||
{
|
||||
private:
|
||||
std::vector<std::pair<std::string_view, T>> _map;
|
||||
bool _continiousValueIndex{ false };
|
||||
|
||||
static constexpr size_t BucketSize = 43;
|
||||
std::array<std::vector<int32_t>, BucketSize> _buckets;
|
||||
|
||||
static constexpr bool ValueIndexable()
|
||||
{
|
||||
if constexpr (std::is_enum_v<T>)
|
||||
return true;
|
||||
else if constexpr (std::is_integral_v<T>)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static constexpr auto ValueDistance(T a, T b)
|
||||
{
|
||||
if constexpr (std::is_enum_v<T>)
|
||||
return static_cast<std::underlying_type_t<T>>(b) - static_cast<std::underlying_type_t<T>>(a);
|
||||
else if constexpr (std::is_integral_v<T>)
|
||||
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<std::pair<std::string_view, T>>&& 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<size_t>(k);
|
||||
return _map.begin() + index;
|
||||
}
|
||||
else
|
||||
{
|
||||
return binarySearchValue();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return binarySearchValue();
|
||||
}
|
||||
}
|
||||
|
||||
auto begin() const
|
||||
{
|
||||
return _map.begin();
|
||||
}
|
||||
|
||||
auto end() const
|
||||
{
|
||||
return _map.end();
|
||||
}
|
||||
};
|
||||
@@ -9,12 +9,12 @@
|
||||
|
||||
#include "Colour.h"
|
||||
|
||||
#include "../core/EnumMap.hpp"
|
||||
#include "../drawing/Drawing.h"
|
||||
#include "../sprites.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <unordered_map>
|
||||
|
||||
rct_colour_map ColourMapA[COLOUR_COUNT] = {};
|
||||
|
||||
@@ -60,45 +60,47 @@ void colours_init_maps()
|
||||
|
||||
namespace Colour
|
||||
{
|
||||
static const EnumMap<colour_t> 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<std::string_view, colour_t> 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
|
||||
|
||||
@@ -9,43 +9,45 @@
|
||||
|
||||
#include "Cursors.h"
|
||||
|
||||
#include "../core/EnumMap.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Cursor
|
||||
{
|
||||
static const EnumMap<CursorID> 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<std::string, CursorID> 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;
|
||||
|
||||
@@ -157,6 +157,7 @@
|
||||
<ClInclude Include="core\DataSerialiserTraits.h" />
|
||||
<ClInclude Include="core\Diagnostics.hpp" />
|
||||
<ClInclude Include="core\Endianness.h" />
|
||||
<ClInclude Include="core\EnumMap.hpp" />
|
||||
<ClInclude Include="core\File.h" />
|
||||
<ClInclude Include="core\FileIndex.hpp" />
|
||||
<ClInclude Include="core\FileScanner.h" />
|
||||
|
||||
@@ -9,13 +9,14 @@
|
||||
|
||||
#include "FormatCodes.h"
|
||||
|
||||
#include "../core/EnumMap.hpp"
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
// clang-format off
|
||||
static const std::unordered_map<std::string_view, FormatToken> FormatTokenMap = {
|
||||
static const EnumMap<FormatToken> 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 {};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<uint8_t> 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<std::string, uint8_t> 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<uint8_t>(RIDE_TYPE_NULL);
|
||||
auto result = RideTypeLookupTable.find(s);
|
||||
return (result != RideTypeLookupTable.end()) ? result->second : static_cast<uint8_t>(RIDE_TYPE_NULL);
|
||||
}
|
||||
|
||||
static const EnumMap<uint8_t> 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<std::string, uint8_t> 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<uint8_t>(RIDE_CATEGORY_TRANSPORT);
|
||||
auto result = RideCategoryLookupTable.find(s);
|
||||
return (result != RideCategoryLookupTable.end()) ? result->second : static_cast<uint8_t>(RIDE_CATEGORY_TRANSPORT);
|
||||
}
|
||||
|
||||
static const EnumMap<ShopItem> 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<std::string, ShopItem> 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;
|
||||
}
|
||||
|
||||
@@ -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<typename T> class DukEnumMap
|
||||
{
|
||||
private:
|
||||
std::unordered_map<std::string_view, T> _s2n;
|
||||
std::unordered_map<T, std::string_view> _n2s;
|
||||
|
||||
public:
|
||||
DukEnumMap(const std::initializer_list<std::pair<std::string_view, T>>& items)
|
||||
{
|
||||
_s2n = std::unordered_map<std::string_view, T>(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<T>(0);
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
};
|
||||
template<typename T> using DukEnumMap = EnumMap<T>;
|
||||
|
||||
inline duk_ret_t duk_json_decode_wrapper(duk_context* ctx, void*)
|
||||
{
|
||||
|
||||
@@ -11,29 +11,31 @@
|
||||
|
||||
# include "HookEngine.h"
|
||||
|
||||
# include "../core/EnumMap.hpp"
|
||||
# include "ScriptEngine.h"
|
||||
|
||||
# include <unordered_map>
|
||||
|
||||
using namespace OpenRCT2::Scripting;
|
||||
|
||||
static const EnumMap<HOOK_TYPE> 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<std::string, HOOK_TYPE> 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)
|
||||
|
||||
@@ -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<std::string, GameCommand> ActionNameToType = {
|
||||
// clang-format off
|
||||
const static EnumMap<GameCommand> ActionNameToType = {
|
||||
{ "balloonpress", GameCommand::BalloonPress },
|
||||
{ "bannerplace", GameCommand::PlaceBanner },
|
||||
{ "bannerremove", GameCommand::RemoveBanner },
|
||||
@@ -1067,21 +1069,21 @@ const static std::unordered_map<std::string, GameCommand> 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<GameAction> CreateGameActionFromActionId(const std::string& actionid)
|
||||
static std::unique_ptr<GameAction> CreateGameActionFromActionId(const std::string& name)
|
||||
{
|
||||
auto result = ActionNameToType.find(actionid);
|
||||
auto result = ActionNameToType.find(name);
|
||||
if (result != ActionNameToType.end())
|
||||
{
|
||||
return GameActions::Create(result->second);
|
||||
|
||||
@@ -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)
|
||||
|
||||
146
test/tests/EnumMapTest.cpp
Normal file
146
test/tests/EnumMapTest.cpp
Normal file
@@ -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 <gtest/gtest.h>
|
||||
#include <openrct2/core/EnumMap.hpp>
|
||||
|
||||
enum class TestEnumClassContinuous
|
||||
{
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
E,
|
||||
F,
|
||||
G
|
||||
};
|
||||
|
||||
enum class TestEnumClassNonContinuous
|
||||
{
|
||||
A = 1,
|
||||
B,
|
||||
C = 7,
|
||||
D,
|
||||
E,
|
||||
F,
|
||||
G
|
||||
};
|
||||
|
||||
template<typename TEnum> void TestEnumKeyLookup()
|
||||
{
|
||||
// clang-format off
|
||||
EnumMap<TEnum> 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<typename TEnum> void TestEnumValueLookup()
|
||||
{
|
||||
// clang-format off
|
||||
EnumMap<TEnum> 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, LookupContinuousByKey)
|
||||
{
|
||||
TestEnumKeyLookup<TestEnumClassContinuous>();
|
||||
}
|
||||
|
||||
TEST(EnumMapTest, LookupContinuousByValue)
|
||||
{
|
||||
TestEnumValueLookup<TestEnumClassContinuous>();
|
||||
}
|
||||
|
||||
TEST(EnumMapTest, LookupNonContinuousByKey)
|
||||
{
|
||||
TestEnumKeyLookup<TestEnumClassNonContinuous>();
|
||||
}
|
||||
|
||||
TEST(EnumMapTest, LookupNonContinuousByValue)
|
||||
{
|
||||
TestEnumValueLookup<TestEnumClassNonContinuous>();
|
||||
}
|
||||
@@ -60,6 +60,7 @@
|
||||
<ClCompile Include="CLITests.cpp" />
|
||||
<ClCompile Include="CryptTests.cpp" />
|
||||
<ClCompile Include="Endianness.cpp" />
|
||||
<ClCompile Include="EnumMapTest.cpp" />
|
||||
<ClCompile Include="FormattingTests.cpp" />
|
||||
<ClCompile Include="LanguagePackTest.cpp" />
|
||||
<ClCompile Include="ImageImporterTests.cpp" />
|
||||
|
||||
Reference in New Issue
Block a user