1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-24 00:03:11 +01:00

Fix ObjectEntryDescriptor (#13506)

This commit is contained in:
Duncan
2020-12-06 09:28:06 +00:00
committed by GitHub
parent 7df4f1835f
commit a9ed5d6536
6 changed files with 86 additions and 74 deletions

View File

@@ -14,6 +14,7 @@
#include "../localisation/Localisation.h"
#include "../network/NetworkTypes.h"
#include "../network/network.h"
#include "../object/Object.h"
#include "../ride/Ride.h"
#include "../ride/TrackDesign.h"
#include "../world/Location.hpp"
@@ -730,3 +731,46 @@ template<> struct DataSerializerTraits_t<rct_vehicle_colour>
stream->Write(msg, strlen(msg));
}
};
template<> struct DataSerializerTraits_t<ObjectEntryDescriptor>
{
static void encode(OpenRCT2::IStream* stream, const ObjectEntryDescriptor& val)
{
stream->Write(&val.Generation);
if (val.Generation == ObjectGeneration::DAT)
{
DataSerializerTraits<rct_object_entry> s;
s.encode(stream, val.Entry);
}
else
{
DataSerializerTraits<std::string> s;
s.encode(stream, val.Identifier);
}
}
static void decode(OpenRCT2::IStream* stream, ObjectEntryDescriptor& val)
{
ObjectGeneration generation;
stream->Read(&generation);
if (generation == ObjectGeneration::DAT)
{
rct_object_entry obj;
DataSerializerTraits<rct_object_entry> s;
s.decode(stream, obj);
val = ObjectEntryDescriptor(obj);
}
else
{
std::string id;
DataSerializerTraits<std::string> s;
s.decode(stream, id);
val = ObjectEntryDescriptor(id);
}
}
static void log(OpenRCT2::IStream* stream, const ObjectEntryDescriptor& val)
{
char msg[128] = {};
snprintf(msg, sizeof(msg), "ObjectEntryDescriptor (Generation = %d)", static_cast<int32_t>(val.Generation));
stream->Write(msg, strlen(msg));
}
};

View File

@@ -276,7 +276,7 @@ private:
for (uint32_t i = 0; i < header.NumItems; i++)
{
auto item = Deserialise(&fs);
items.push_back(item);
items.emplace_back(std::move(item));
}
loadedItems = true;
}
@@ -291,7 +291,7 @@ private:
Console::Error::WriteLine("%s", e.what());
}
}
return std::make_tuple(loadedItems, items);
return std::make_tuple(loadedItems, std::move(items));
}
void WriteIndexFile(int32_t language, const DirectoryStats& stats, const std::vector<TItem>& items) const

View File

@@ -61,23 +61,4 @@ namespace OpenRCT2
{
WriteString(str.c_str());
}
ObjectEntryDescriptor IStream::ReadObjectEntryDescriptor()
{
auto generation = ReadValue<ObjectGeneration>();
if (generation == ObjectGeneration::DAT)
return ObjectEntryDescriptor(ReadValue<rct_object_entry>());
return ObjectEntryDescriptor(ReadStdString());
}
void IStream::WriteObjectEntryDescriptor(const ObjectEntryDescriptor& oed)
{
WriteValue<ObjectGeneration>(oed.Generation);
if (oed.Generation == ObjectGeneration::DAT)
WriteValue<rct_object_entry>(oed.Entry);
else
WriteString(oed.Identifier);
}
} // namespace OpenRCT2

View File

@@ -207,8 +207,6 @@ namespace OpenRCT2
std::string ReadStdString();
void WriteString(const utf8* str);
void WriteString(const std::string& string);
ObjectEntryDescriptor ReadObjectEntryDescriptor();
void WriteObjectEntryDescriptor(const ObjectEntryDescriptor& oed);
};
} // namespace OpenRCT2

View File

@@ -15,8 +15,6 @@
#include "ImageTable.h"
#include "StringTable.h"
#include <algorithm>
#include <cstring>
#include <optional>
#include <string_view>
#include <vector>
@@ -128,52 +126,6 @@ struct rct_object_entry_group
assert_struct_size(rct_object_entry_group, 8);
#endif
enum class ObjectGeneration : uint8_t
{
DAT,
JSON,
};
struct ObjectEntryDescriptor
{
ObjectGeneration Generation;
union
{
rct_object_entry Entry; // For DAT objects
char Identifier[64]; // For JSON objects
};
ObjectEntryDescriptor() = default;
ObjectEntryDescriptor(const ObjectEntryDescriptor& entry)
{
*this = entry;
}
explicit ObjectEntryDescriptor(const rct_object_entry& newEntry)
{
Generation = ObjectGeneration::DAT;
Entry = newEntry;
}
explicit ObjectEntryDescriptor(std::string_view newIdentifier)
{
Generation = ObjectGeneration::JSON;
safe_strcpy(const_cast<char*>(Identifier), std::string(newIdentifier).c_str(), 64);
}
ObjectEntryDescriptor& operator=(const ObjectEntryDescriptor& newEntry)
{
Generation = newEntry.Generation;
if (newEntry.Generation == ObjectGeneration::DAT)
Entry = newEntry.Entry;
else
safe_strcpy(const_cast<char*>(Identifier), std::string(newEntry.Identifier).c_str(), 64);
return *this;
}
};
struct rct_ride_filters
{
uint8_t category[2];
@@ -191,6 +143,38 @@ struct rct_object_filters
assert_struct_size(rct_object_filters, 3);
#pragma pack(pop)
enum class ObjectGeneration : uint8_t
{
DAT,
JSON,
};
struct ObjectEntryDescriptor
{
ObjectGeneration Generation;
std::string Identifier; // For JSON objects
rct_object_entry Entry; // For DAT objects
ObjectEntryDescriptor()
: Generation(ObjectGeneration::JSON)
, Identifier()
, Entry()
{
}
explicit ObjectEntryDescriptor(const rct_object_entry& newEntry)
{
Generation = ObjectGeneration::DAT;
Entry = newEntry;
}
explicit ObjectEntryDescriptor(std::string_view newIdentifier)
{
Generation = ObjectGeneration::JSON;
Identifier = std::string(newIdentifier);
}
};
struct IObjectRepository;
namespace OpenRCT2
{

View File

@@ -14,6 +14,7 @@
#include "../common.h"
#include "../config/Config.h"
#include "../core/Console.hpp"
#include "../core/DataSerialiser.h"
#include "../core/FileIndex.hpp"
#include "../core/FileStream.h"
#include "../core/Guard.hpp"
@@ -75,7 +76,7 @@ class ObjectFileIndex final : public FileIndex<ObjectRepositoryItem>
{
private:
static constexpr uint32_t MAGIC_NUMBER = 0x5844494F; // OIDX
static constexpr uint16_t VERSION = 24;
static constexpr uint16_t VERSION = 25;
static constexpr auto PATTERN = "*.dat;*.pob;*.json;*.parkobj";
IObjectRepository& _objectRepository;
@@ -160,12 +161,15 @@ protected:
}
break;
case ObjectType::SceneryGroup:
{
stream->WriteValue<uint16_t>(static_cast<uint16_t>(item.SceneryGroupInfo.Entries.size()));
DataSerialiser serialiser(true, *stream);
for (const auto& entry : item.SceneryGroupInfo.Entries)
{
stream->WriteObjectEntryDescriptor(entry);
serialiser << entry;
}
break;
}
default:
// Switch processes only ObjectType::Ride and ObjectType::SceneryGroup
break;
@@ -212,9 +216,10 @@ protected:
{
auto numEntries = stream->ReadValue<uint16_t>();
item.SceneryGroupInfo.Entries = std::vector<ObjectEntryDescriptor>(numEntries);
DataSerialiser serialiser(false, *stream);
for (size_t i = 0; i < numEntries; i++)
{
item.SceneryGroupInfo.Entries[i] = stream->ReadObjectEntryDescriptor();
serialiser << item.SceneryGroupInfo.Entries[i];
}
break;
}