From 656cdda39978f0788a83f9839ae6896b31a74091 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 26 Oct 2020 21:34:46 +0100 Subject: [PATCH 1/6] Add JSON identifier to object repository --- src/openrct2/object/ObjectRepository.cpp | 5 ++++- src/openrct2/object/ObjectRepository.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/openrct2/object/ObjectRepository.cpp b/src/openrct2/object/ObjectRepository.cpp index e0884aaecd..6cfbdce0d3 100644 --- a/src/openrct2/object/ObjectRepository.cpp +++ b/src/openrct2/object/ObjectRepository.cpp @@ -74,7 +74,7 @@ class ObjectFileIndex final : public FileIndex { private: static constexpr uint32_t MAGIC_NUMBER = 0x5844494F; // OIDX - static constexpr uint16_t VERSION = 21; + static constexpr uint16_t VERSION = 22; static constexpr auto PATTERN = "*.dat;*.pob;*.json;*.parkobj"; IObjectRepository& _objectRepository; @@ -111,6 +111,7 @@ public: if (object != nullptr) { ObjectRepositoryItem item = {}; + item.Identifier = object->GetIdentifier(); item.ObjectEntry = *object->GetObjectEntry(); item.Path = path; item.Name = object->GetName(); @@ -125,6 +126,7 @@ public: protected: void Serialise(IStream* stream, const ObjectRepositoryItem& item) const override { + stream->WriteValue(item.Identifier); stream->WriteValue(item.ObjectEntry); stream->WriteString(item.Path); stream->WriteString(item.Name); @@ -170,6 +172,7 @@ protected: { ObjectRepositoryItem item; + item.Identifier = stream->ReadStdString(); item.ObjectEntry = stream->ReadValue(); item.Path = stream->ReadStdString(); item.Name = stream->ReadStdString(); diff --git a/src/openrct2/object/ObjectRepository.h b/src/openrct2/object/ObjectRepository.h index 503e282d21..6670395e24 100644 --- a/src/openrct2/object/ObjectRepository.h +++ b/src/openrct2/object/ObjectRepository.h @@ -37,6 +37,7 @@ struct rct_drawpixelinfo; struct ObjectRepositoryItem { size_t Id; + std::string Identifier; // e.g. rct2.c3d rct_object_entry ObjectEntry; std::string Path; std::string Name; From bafafa6805ae62ad0845be43d129155a68a0d11a Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Thu, 5 Nov 2020 21:19:43 +0100 Subject: [PATCH 2/6] Create functions to load objects by JSON id --- src/openrct2/network/NetworkBase.cpp | 4 +- src/openrct2/object/BannerObject.cpp | 2 +- src/openrct2/object/FootpathItemObject.cpp | 2 +- src/openrct2/object/ObjectManager.cpp | 101 +++++++++++--------- src/openrct2/object/ObjectManager.h | 1 + src/openrct2/object/ObjectRepository.cpp | 48 +++++++++- src/openrct2/object/ObjectRepository.h | 3 +- src/openrct2/rct1/S4Importer.cpp | 2 +- src/openrct2/ride/TrackDesignRepository.cpp | 4 +- 9 files changed, 112 insertions(+), 55 deletions(-) diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 4be3980077..843d4aeee2 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -2340,7 +2340,7 @@ void NetworkBase::Client_Handle_OBJECTS_LIST(NetworkConnection& connection, Netw uint32_t flags = 0; packet >> checksum >> flags; - const auto* object = repo.FindObject(objectName); + const auto* object = repo.FindObjectLegacy(objectName); // This could potentially request the object if checksums don't match, but since client // won't replace its version with server-provided one, we don't do that. if (object == nullptr) @@ -2482,7 +2482,7 @@ void NetworkBase::Server_Handle_MAPREQUEST(NetworkConnection& connection, Networ // This is required, as packet does not have null terminator std::string s(name, name + 8); log_verbose("Client requested object %s", s.c_str()); - const ObjectRepositoryItem* item = repo.FindObject(s.c_str()); + const ObjectRepositoryItem* item = repo.FindObjectLegacy(s.c_str()); if (item == nullptr) { log_warning("Client tried getting non-existent object %s from us.", s.c_str()); diff --git a/src/openrct2/object/BannerObject.cpp b/src/openrct2/object/BannerObject.cpp index eb1493b48c..e81b172aa1 100644 --- a/src/openrct2/object/BannerObject.cpp +++ b/src/openrct2/object/BannerObject.cpp @@ -44,7 +44,7 @@ void BannerObject::ReadLegacy(IReadObjectContext* context, OpenRCT2::IStream* st auto identifier = GetLegacyIdentifier(); auto& objectRepository = context->GetObjectRepository(); - auto item = objectRepository.FindObject(identifier); + auto item = objectRepository.FindObjectLegacy(identifier); if (item != nullptr) { auto sourceGame = item->GetFirstSourceGame(); diff --git a/src/openrct2/object/FootpathItemObject.cpp b/src/openrct2/object/FootpathItemObject.cpp index ee076b2f48..970f9d0806 100644 --- a/src/openrct2/object/FootpathItemObject.cpp +++ b/src/openrct2/object/FootpathItemObject.cpp @@ -48,7 +48,7 @@ void FootpathItemObject::ReadLegacy(IReadObjectContext* context, OpenRCT2::IStre auto identifier = GetLegacyIdentifier(); auto& objectRepository = context->GetObjectRepository(); - auto item = objectRepository.FindObject(identifier); + auto item = objectRepository.FindObjectLegacy(identifier); if (item != nullptr) { auto sourceGame = item->GetFirstSourceGame(); diff --git a/src/openrct2/object/ObjectManager.cpp b/src/openrct2/object/ObjectManager.cpp index ba93821ce9..5a6edc0a6e 100644 --- a/src/openrct2/object/ObjectManager.cpp +++ b/src/openrct2/object/ObjectManager.cpp @@ -101,10 +101,9 @@ public: return result; } - Object* LoadObject(const rct_object_entry* entry) override + Object* RepositoryItemToObject(const ObjectRepositoryItem* ori) { Object* loadedObject = nullptr; - const ObjectRepositoryItem* ori = _objectRepository.FindObject(entry); if (ori != nullptr) { loadedObject = ori->LoadedObject; @@ -132,6 +131,18 @@ public: return loadedObject; } + Object* LoadObject(const std::string_view& identifier) override + { + const ObjectRepositoryItem* ori = _objectRepository.FindObject(identifier); + return RepositoryItemToObject(ori); + } + + Object* LoadObject(const rct_object_entry* entry) override + { + const ObjectRepositoryItem* ori = _objectRepository.FindObject(entry); + return RepositoryItemToObject(ori); + } + void LoadObjects(const rct_object_entry* entries, size_t count) override { // Find all the required objects @@ -222,52 +233,52 @@ public: // loaded RCT1 and RCT2 save files. // Surfaces - LoadObject("#RCT2SGR"); - LoadObject("#RCT2SSY"); - LoadObject("#RCT2SDI"); - LoadObject("#RCT2SRO"); - LoadObject("#RCT2SMA"); - LoadObject("#RCT2SCH"); - LoadObject("#RCT2SGC"); - LoadObject("#RCT2SIC"); - LoadObject("#RCT2SIR"); - LoadObject("#RCT2SIY"); - LoadObject("#RCT2SIP"); - LoadObject("#RCT2SIG"); - LoadObject("#RCT2SSR"); - LoadObject("#RCT2SSA"); + LoadObjectLegacy("#RCT2SGR"); + LoadObjectLegacy("#RCT2SSY"); + LoadObjectLegacy("#RCT2SDI"); + LoadObjectLegacy("#RCT2SRO"); + LoadObjectLegacy("#RCT2SMA"); + LoadObjectLegacy("#RCT2SCH"); + LoadObjectLegacy("#RCT2SGC"); + LoadObjectLegacy("#RCT2SIC"); + LoadObjectLegacy("#RCT2SIR"); + LoadObjectLegacy("#RCT2SIY"); + LoadObjectLegacy("#RCT2SIP"); + LoadObjectLegacy("#RCT2SIG"); + LoadObjectLegacy("#RCT2SSR"); + LoadObjectLegacy("#RCT2SSA"); // Edges - LoadObject("#RCT2ERO"); - LoadObject("#RCT2EWR"); - LoadObject("#RCT2EWB"); - LoadObject("#RCT2EIC"); - LoadObject("#RCT1EBR"); - LoadObject("#RCT1EIR"); - LoadObject("#RCT1EGY"); - LoadObject("#RCT1EYE"); - LoadObject("#RCT1ERE"); - LoadObject("#RCT1EPU"); - LoadObject("#RCT1EGR"); - LoadObject("#RCT1ESN"); - LoadObject("#RCT1ESG"); - LoadObject("#RCT1ESA"); - LoadObject("#RCT1ESB"); + LoadObjectLegacy("#RCT2ERO"); + LoadObjectLegacy("#RCT2EWR"); + LoadObjectLegacy("#RCT2EWB"); + LoadObjectLegacy("#RCT2EIC"); + LoadObjectLegacy("#RCT1EBR"); + LoadObjectLegacy("#RCT1EIR"); + LoadObjectLegacy("#RCT1EGY"); + LoadObjectLegacy("#RCT1EYE"); + LoadObjectLegacy("#RCT1ERE"); + LoadObjectLegacy("#RCT1EPU"); + LoadObjectLegacy("#RCT1EGR"); + LoadObjectLegacy("#RCT1ESN"); + LoadObjectLegacy("#RCT1ESG"); + LoadObjectLegacy("#RCT1ESA"); + LoadObjectLegacy("#RCT1ESB"); // Stations - LoadObject("#RCT2STN"); - LoadObject("#RCT2STW"); - LoadObject("#RCT2STV"); - LoadObject("#RCT2ST3"); - LoadObject("#RCT2ST4"); - LoadObject("#RCT2STJ"); - LoadObject("#RCT2STL"); - LoadObject("#RCT2STC"); - LoadObject("#RCT2STA"); - LoadObject("#RCT2STS"); - LoadObject("#RCT2STP"); - LoadObject("#RCT2STE"); - LoadObject("#ORCT2SN"); + LoadObjectLegacy("#RCT2STN"); + LoadObjectLegacy("#RCT2STW"); + LoadObjectLegacy("#RCT2STV"); + LoadObjectLegacy("#RCT2ST3"); + LoadObjectLegacy("#RCT2ST4"); + LoadObjectLegacy("#RCT2STJ"); + LoadObjectLegacy("#RCT2STL"); + LoadObjectLegacy("#RCT2STC"); + LoadObjectLegacy("#RCT2STA"); + LoadObjectLegacy("#RCT2STS"); + LoadObjectLegacy("#RCT2STP"); + LoadObjectLegacy("#RCT2STE"); + LoadObjectLegacy("#ORCT2SN"); } static rct_string_id GetObjectSourceGameString(const ObjectSourceGame sourceGame) @@ -304,7 +315,7 @@ public: } private: - Object* LoadObject(const std::string& name) + Object* LoadObjectLegacy(const std::string& name) { rct_object_entry entry{}; std::copy_n(name.c_str(), 8, entry.name); diff --git a/src/openrct2/object/ObjectManager.h b/src/openrct2/object/ObjectManager.h index dda14a4172..ea5f7145e5 100644 --- a/src/openrct2/object/ObjectManager.h +++ b/src/openrct2/object/ObjectManager.h @@ -30,6 +30,7 @@ struct IObjectManager virtual ObjectEntryIndex GetLoadedObjectEntryIndex(const Object* object) abstract; virtual std::vector GetInvalidObjects(const rct_object_entry* entries) abstract; + virtual Object* LoadObject(const std::string_view& identifier) abstract; virtual Object* LoadObject(const rct_object_entry* entry) abstract; virtual void LoadObjects(const rct_object_entry* entries, size_t count) abstract; virtual void LoadDefaultObjects() abstract; diff --git a/src/openrct2/object/ObjectRepository.cpp b/src/openrct2/object/ObjectRepository.cpp index 6cfbdce0d3..4c9503b3dd 100644 --- a/src/openrct2/object/ObjectRepository.cpp +++ b/src/openrct2/object/ObjectRepository.cpp @@ -47,6 +47,28 @@ using namespace OpenRCT2; +struct ObjectIdentifierHash +{ + size_t operator()(const std::string_view& identifier) const + { + std::string copy = identifier.data(); + uint32_t hash = 5381; + for (auto i : copy) + { + hash = ((hash << 5) + hash) + i; + } + return hash; + } +}; + +struct ObjectIdentifierEqual +{ + bool operator()(const std::string_view& lhs, const std::string_view& rhs) const + { + return lhs == rhs; + } +}; + struct ObjectEntryHash { size_t operator()(const rct_object_entry& entry) const @@ -68,6 +90,7 @@ struct ObjectEntryEqual } }; +using ObjectIdentifierMap = std::unordered_map; using ObjectEntryMap = std::unordered_map; class ObjectFileIndex final : public FileIndex @@ -230,6 +253,7 @@ class ObjectRepository final : public IObjectRepository std::shared_ptr const _env; ObjectFileIndex const _fileIndex; std::vector _items; + ObjectIdentifierMap _newItemMap; ObjectEntryMap _itemMap; public: @@ -269,7 +293,7 @@ public: return _items.data(); } - const ObjectRepositoryItem* FindObject(const std::string_view& legacyIdentifier) const override + const ObjectRepositoryItem* FindObjectLegacy(const std::string_view& legacyIdentifier) const override { rct_object_entry entry = {}; entry.SetName(legacyIdentifier); @@ -282,6 +306,16 @@ public: return nullptr; } + const ObjectRepositoryItem* FindObject(const std::string_view& identifier) const override final + { + auto kvp = _newItemMap.find(identifier.data()); + if (kvp != _newItemMap.end()) + { + return &_items[kvp->second]; + } + return nullptr; + } + const ObjectRepositoryItem* FindObject(const rct_object_entry* objectEntry) const override final { auto kvp = _itemMap.find(*objectEntry); @@ -411,6 +445,7 @@ private: void ClearItems() { _items.clear(); + _newItemMap.clear(); _itemMap.clear(); } @@ -428,10 +463,15 @@ private: // Rebuild item map _itemMap.clear(); + _newItemMap.clear(); for (size_t i = 0; i < _items.size(); i++) { rct_object_entry entry = _items[i].ObjectEntry; _itemMap[entry] = i; + if (_items[i].Identifier != "") + { + _newItemMap[_items[i].Identifier] = i; + } } } @@ -460,6 +500,10 @@ private: auto copy = item; copy.Id = index; _items.push_back(copy); + if (item.Identifier != "") + { + _newItemMap[item.Identifier] = index; + } _itemMap[item.ObjectEntry] = index; return true; } @@ -749,7 +793,7 @@ const ObjectRepositoryItem* object_repository_find_object_by_entry(const rct_obj const ObjectRepositoryItem* object_repository_find_object_by_name(const char* name) { auto& objectRepository = GetContext()->GetObjectRepository(); - return objectRepository.FindObject(name); + return objectRepository.FindObjectLegacy(name); } bool object_entry_compare(const rct_object_entry* a, const rct_object_entry* b) diff --git a/src/openrct2/object/ObjectRepository.h b/src/openrct2/object/ObjectRepository.h index 6670395e24..838c95f2df 100644 --- a/src/openrct2/object/ObjectRepository.h +++ b/src/openrct2/object/ObjectRepository.h @@ -72,7 +72,8 @@ struct IObjectRepository virtual void Construct(int32_t language) abstract; virtual size_t GetNumObjects() const abstract; virtual const ObjectRepositoryItem* GetObjects() const abstract; - virtual const ObjectRepositoryItem* FindObject(const std::string_view& legacyIdentifier) const abstract; + virtual const ObjectRepositoryItem* FindObjectLegacy(const std::string_view& legacyIdentifier) const abstract; + virtual const ObjectRepositoryItem* FindObject(const std::string_view& identifier) const abstract; virtual const ObjectRepositoryItem* FindObject(const rct_object_entry* objectEntry) const abstract; virtual std::unique_ptr LoadObject(const ObjectRepositoryItem* ori) abstract; diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index a052ec05d0..362df7c920 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -526,7 +526,7 @@ private: for (const char* objectName : objects) { auto& objectRepository = OpenRCT2::GetContext()->GetObjectRepository(); - auto foundObject = objectRepository.FindObject(objectName); + auto foundObject = objectRepository.FindObjectLegacy(objectName); if (foundObject != nullptr) { uint8_t objectType = foundObject->ObjectEntry.GetType(); diff --git a/src/openrct2/ride/TrackDesignRepository.cpp b/src/openrct2/ride/TrackDesignRepository.cpp index 3f676e4e3c..a032ad6f9d 100644 --- a/src/openrct2/ride/TrackDesignRepository.cpp +++ b/src/openrct2/ride/TrackDesignRepository.cpp @@ -164,7 +164,7 @@ public: bool entryIsNotSeparate = false; if (entry.empty()) { - const ObjectRepositoryItem* ori = repo.FindObject(item.ObjectEntry.c_str()); + const ObjectRepositoryItem* ori = repo.FindObjectLegacy(item.ObjectEntry.c_str()); if (ori == nullptr || !RideTypeDescriptors[rideType].HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY)) entryIsNotSeparate = true; @@ -198,7 +198,7 @@ public: bool entryIsNotSeparate = false; if (entry.empty()) { - const ObjectRepositoryItem* ori = repo.FindObject(item.ObjectEntry.c_str()); + const ObjectRepositoryItem* ori = repo.FindObjectLegacy(item.ObjectEntry.c_str()); if (ori == nullptr || !RideTypeDescriptors[rideType].HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY)) entryIsNotSeparate = true; From 6df36127b4c83ba07632dd1c253ada883dd192b7 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Thu, 5 Nov 2020 21:33:13 +0100 Subject: [PATCH 3/6] Replace calls to LoadObjectLegacy() with new IDs --- src/openrct2/object/ObjectManager.cpp | 91 +++++++++++++-------------- 1 file changed, 42 insertions(+), 49 deletions(-) diff --git a/src/openrct2/object/ObjectManager.cpp b/src/openrct2/object/ObjectManager.cpp index 5a6edc0a6e..6595db6fa1 100644 --- a/src/openrct2/object/ObjectManager.cpp +++ b/src/openrct2/object/ObjectManager.cpp @@ -233,52 +233,52 @@ public: // loaded RCT1 and RCT2 save files. // Surfaces - LoadObjectLegacy("#RCT2SGR"); - LoadObjectLegacy("#RCT2SSY"); - LoadObjectLegacy("#RCT2SDI"); - LoadObjectLegacy("#RCT2SRO"); - LoadObjectLegacy("#RCT2SMA"); - LoadObjectLegacy("#RCT2SCH"); - LoadObjectLegacy("#RCT2SGC"); - LoadObjectLegacy("#RCT2SIC"); - LoadObjectLegacy("#RCT2SIR"); - LoadObjectLegacy("#RCT2SIY"); - LoadObjectLegacy("#RCT2SIP"); - LoadObjectLegacy("#RCT2SIG"); - LoadObjectLegacy("#RCT2SSR"); - LoadObjectLegacy("#RCT2SSA"); + LoadObject("rct2.surface.grass"); + LoadObject("rct2.surface.sand"); + LoadObject("rct2.surface.dirt"); + LoadObject("rct2.surface.rock"); + LoadObject("rct2.surface.martian"); + LoadObject("rct2.surface.chequerboard"); + LoadObject("rct2.surface.grassclumps"); + LoadObject("rct2.surface.ice"); + LoadObject("rct2.surface.gridred"); + LoadObject("rct2.surface.gridyellow"); + LoadObject("rct2.surface.gridpurple"); + LoadObject("rct2.surface.gridgreen"); + LoadObject("rct2.surface.sandred"); + LoadObject("rct2.surface.sandbrown"); // Edges - LoadObjectLegacy("#RCT2ERO"); - LoadObjectLegacy("#RCT2EWR"); - LoadObjectLegacy("#RCT2EWB"); - LoadObjectLegacy("#RCT2EIC"); - LoadObjectLegacy("#RCT1EBR"); - LoadObjectLegacy("#RCT1EIR"); - LoadObjectLegacy("#RCT1EGY"); - LoadObjectLegacy("#RCT1EYE"); - LoadObjectLegacy("#RCT1ERE"); - LoadObjectLegacy("#RCT1EPU"); - LoadObjectLegacy("#RCT1EGR"); - LoadObjectLegacy("#RCT1ESN"); - LoadObjectLegacy("#RCT1ESG"); - LoadObjectLegacy("#RCT1ESA"); - LoadObjectLegacy("#RCT1ESB"); + LoadObject("rct2.edge.rock"); + LoadObject("rct2.edge.woodred"); + LoadObject("rct2.edge.woodblack"); + LoadObject("rct2.edge.ice"); + LoadObject("rct1.edge.brick"); + LoadObject("rct1.edge.iron"); + LoadObject("rct1.aa.edge.grey"); + LoadObject("rct1.aa.edge.yellow"); + LoadObject("rct1.aa.edge.red"); + LoadObject("rct1.ll.edge.purple"); + LoadObject("rct1.ll.edge.green"); + LoadObject("rct1.ll.edge.stonebrown"); + LoadObject("rct1.ll.edge.stonegrey"); + LoadObject("rct1.ll.edge.skyscrapera"); + LoadObject("rct1.ll.edge.skyscraperb"); // Stations - LoadObjectLegacy("#RCT2STN"); - LoadObjectLegacy("#RCT2STW"); - LoadObjectLegacy("#RCT2STV"); - LoadObjectLegacy("#RCT2ST3"); - LoadObjectLegacy("#RCT2ST4"); - LoadObjectLegacy("#RCT2STJ"); - LoadObjectLegacy("#RCT2STL"); - LoadObjectLegacy("#RCT2STC"); - LoadObjectLegacy("#RCT2STA"); - LoadObjectLegacy("#RCT2STS"); - LoadObjectLegacy("#RCT2STP"); - LoadObjectLegacy("#RCT2STE"); - LoadObjectLegacy("#ORCT2SN"); + LoadObject("rct2.station.plain"); + LoadObject("rct2.station.wooden"); + LoadObject("rct2.station.canvastent"); + LoadObject("rct2.station.castlegrey"); + LoadObject("rct2.station.castlebrown"); + LoadObject("rct2.station.jungle"); + LoadObject("rct2.station.log"); + LoadObject("rct2.station.classical"); + LoadObject("rct2.station.abstract"); + LoadObject("rct2.station.snow"); + LoadObject("rct2.station.pagoda"); + LoadObject("rct2.station.space"); + LoadObject("openrct2.station.noentrance"); } static rct_string_id GetObjectSourceGameString(const ObjectSourceGame sourceGame) @@ -315,13 +315,6 @@ public: } private: - Object* LoadObjectLegacy(const std::string& name) - { - rct_object_entry entry{}; - std::copy_n(name.c_str(), 8, entry.name); - return LoadObject(&entry); - } - int32_t FindSpareSlot(uint8_t objectType) { size_t firstIndex = GetIndexFromTypeEntry(objectType, 0); From 53aef4e549a35696eefac153a80852b0c816f602 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Thu, 5 Nov 2020 21:36:28 +0100 Subject: [PATCH 4/6] Replace old edge style names in Tables.cpp --- src/openrct2/rct1/Tables.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/openrct2/rct1/Tables.cpp b/src/openrct2/rct1/Tables.cpp index 536c41c3c1..0982ebd626 100644 --- a/src/openrct2/rct1/Tables.cpp +++ b/src/openrct2/rct1/Tables.cpp @@ -143,22 +143,22 @@ namespace RCT1 { static constexpr const uint8_t map[] = { - TERRAIN_EDGE_ROCK, // #RCT2ERO - TERRAIN_EDGE_BRICK, // #RCT1EBR - TERRAIN_EDGE_IRON, // #RCT1EIR - TERRAIN_EDGE_WOOD_RED, // #RCT2EWR - TERRAIN_EDGE_GREY, // #RCT1EGY - TERRAIN_EDGE_YELLOW, // #RCT1EYE - TERRAIN_EDGE_WOOD_BLACK, // #RCT2EWB - TERRAIN_EDGE_RED, // #RCT1ERE - TERRAIN_EDGE_ICE, // #RCT2EIC - TERRAIN_EDGE_PURPLE, // #RCT2EIC - TERRAIN_EDGE_GREEN, // #RCT1EGR - TERRAIN_EDGE_STONE_BROWN, // #RCT1ESN - TERRAIN_EDGE_STONE_GREY, // #RCT1ESG - TERRAIN_EDGE_SKYSCRAPER_A, // #RCT1ESA - TERRAIN_EDGE_SKYSCRAPER_B, // #RCT1ESB - TERRAIN_EDGE_ROCK // #RCT2ERO (Unused) + TERRAIN_EDGE_ROCK, // rct2.edge.rock + TERRAIN_EDGE_BRICK, // rct1.edge.brick + TERRAIN_EDGE_IRON, // rct1.edge.iron + TERRAIN_EDGE_WOOD_RED, // rct2.edge.woodred + TERRAIN_EDGE_GREY, // rct1.aa.edge.grey + TERRAIN_EDGE_YELLOW, // rct1.aa.edge.yellow + TERRAIN_EDGE_WOOD_BLACK, // rct2.edge.woodblack + TERRAIN_EDGE_RED, // rct1.aa.edge.red + TERRAIN_EDGE_ICE, // rct2.edge.ice + TERRAIN_EDGE_PURPLE, // rct1.ll.edge.purple + TERRAIN_EDGE_GREEN, // rct1.ll.edge.green + TERRAIN_EDGE_STONE_BROWN, // rct1.ll.edge.stonebrown + TERRAIN_EDGE_STONE_GREY, // rct1.ll.edge.stonegrey + TERRAIN_EDGE_SKYSCRAPER_A, // rct1.ll.edge.skyscrapera + TERRAIN_EDGE_SKYSCRAPER_B, // rct1.ll.edge.skyscraperb + TERRAIN_EDGE_ROCK // rct2.edge.rock (Unused) }; Guard::ArgumentInRange(terrainEdge, 0, std::size(map), "Unsupported RCT1 terrain edge."); return map[terrainEdge]; From ce15e20c942149c64e1dc996a06ff21e756190c1 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Fri, 6 Nov 2020 11:40:52 +0100 Subject: [PATCH 5/6] Use plain std::string_view instead of const & --- src/openrct2/object/ObjectManager.cpp | 2 +- src/openrct2/object/ObjectManager.h | 2 +- src/openrct2/object/ObjectRepository.cpp | 11 +++++------ src/openrct2/object/ObjectRepository.h | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/openrct2/object/ObjectManager.cpp b/src/openrct2/object/ObjectManager.cpp index 6595db6fa1..3763f5a590 100644 --- a/src/openrct2/object/ObjectManager.cpp +++ b/src/openrct2/object/ObjectManager.cpp @@ -131,7 +131,7 @@ public: return loadedObject; } - Object* LoadObject(const std::string_view& identifier) override + Object* LoadObject(std::string_view identifier) override { const ObjectRepositoryItem* ori = _objectRepository.FindObject(identifier); return RepositoryItemToObject(ori); diff --git a/src/openrct2/object/ObjectManager.h b/src/openrct2/object/ObjectManager.h index ea5f7145e5..85e8051eb6 100644 --- a/src/openrct2/object/ObjectManager.h +++ b/src/openrct2/object/ObjectManager.h @@ -30,7 +30,7 @@ struct IObjectManager virtual ObjectEntryIndex GetLoadedObjectEntryIndex(const Object* object) abstract; virtual std::vector GetInvalidObjects(const rct_object_entry* entries) abstract; - virtual Object* LoadObject(const std::string_view& identifier) abstract; + virtual Object* LoadObject(std::string_view identifier) abstract; virtual Object* LoadObject(const rct_object_entry* entry) abstract; virtual void LoadObjects(const rct_object_entry* entries, size_t count) abstract; virtual void LoadDefaultObjects() abstract; diff --git a/src/openrct2/object/ObjectRepository.cpp b/src/openrct2/object/ObjectRepository.cpp index 4c9503b3dd..78864f511e 100644 --- a/src/openrct2/object/ObjectRepository.cpp +++ b/src/openrct2/object/ObjectRepository.cpp @@ -49,11 +49,10 @@ using namespace OpenRCT2; struct ObjectIdentifierHash { - size_t operator()(const std::string_view& identifier) const + size_t operator()(std::string_view identifier) const { - std::string copy = identifier.data(); uint32_t hash = 5381; - for (auto i : copy) + for (auto i : identifier) { hash = ((hash << 5) + hash) + i; } @@ -63,7 +62,7 @@ struct ObjectIdentifierHash struct ObjectIdentifierEqual { - bool operator()(const std::string_view& lhs, const std::string_view& rhs) const + bool operator()(std::string_view lhs, std::string_view rhs) const { return lhs == rhs; } @@ -306,9 +305,9 @@ public: return nullptr; } - const ObjectRepositoryItem* FindObject(const std::string_view& identifier) const override final + const ObjectRepositoryItem* FindObject(std::string_view identifier) const override final { - auto kvp = _newItemMap.find(identifier.data()); + auto kvp = _newItemMap.find(std::string(identifier)); if (kvp != _newItemMap.end()) { return &_items[kvp->second]; diff --git a/src/openrct2/object/ObjectRepository.h b/src/openrct2/object/ObjectRepository.h index 838c95f2df..5b3a7cf877 100644 --- a/src/openrct2/object/ObjectRepository.h +++ b/src/openrct2/object/ObjectRepository.h @@ -73,7 +73,7 @@ struct IObjectRepository virtual size_t GetNumObjects() const abstract; virtual const ObjectRepositoryItem* GetObjects() const abstract; virtual const ObjectRepositoryItem* FindObjectLegacy(const std::string_view& legacyIdentifier) const abstract; - virtual const ObjectRepositoryItem* FindObject(const std::string_view& identifier) const abstract; + virtual const ObjectRepositoryItem* FindObject(std::string_view identifier) const abstract; virtual const ObjectRepositoryItem* FindObject(const rct_object_entry* objectEntry) const abstract; virtual std::unique_ptr LoadObject(const ObjectRepositoryItem* ori) abstract; From 880a2672521b7ef6915b67fc8d246d361d6d24a3 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Fri, 6 Nov 2020 11:59:02 +0100 Subject: [PATCH 6/6] Implement @ZehMatt's suggestions --- src/openrct2/object/ObjectRepository.cpp | 27 +++--------------------- 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/src/openrct2/object/ObjectRepository.cpp b/src/openrct2/object/ObjectRepository.cpp index 78864f511e..cda814a397 100644 --- a/src/openrct2/object/ObjectRepository.cpp +++ b/src/openrct2/object/ObjectRepository.cpp @@ -47,27 +47,6 @@ using namespace OpenRCT2; -struct ObjectIdentifierHash -{ - size_t operator()(std::string_view identifier) const - { - uint32_t hash = 5381; - for (auto i : identifier) - { - hash = ((hash << 5) + hash) + i; - } - return hash; - } -}; - -struct ObjectIdentifierEqual -{ - bool operator()(std::string_view lhs, std::string_view rhs) const - { - return lhs == rhs; - } -}; - struct ObjectEntryHash { size_t operator()(const rct_object_entry& entry) const @@ -89,7 +68,7 @@ struct ObjectEntryEqual } }; -using ObjectIdentifierMap = std::unordered_map; +using ObjectIdentifierMap = std::unordered_map; using ObjectEntryMap = std::unordered_map; class ObjectFileIndex final : public FileIndex @@ -467,7 +446,7 @@ private: { rct_object_entry entry = _items[i].ObjectEntry; _itemMap[entry] = i; - if (_items[i].Identifier != "") + if (!_items[i].Identifier.empty()) { _newItemMap[_items[i].Identifier] = i; } @@ -499,7 +478,7 @@ private: auto copy = item; copy.Id = index; _items.push_back(copy); - if (item.Identifier != "") + if (!item.Identifier.empty()) { _newItemMap[item.Identifier] = index; }