mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-24 00:03:11 +01:00
Merge pull request #13533 from duncanspumpkin/serial_2
FileIndex Serialise Cleanup
This commit is contained in:
@@ -110,6 +110,10 @@ template<> struct DataSerializerTraits_t<int8_t> : public DataSerializerTraitsIn
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct DataSerializerTraits_t<utf8> : public DataSerializerTraitsIntegral<utf8>
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct DataSerializerTraits_t<uint16_t> : public DataSerializerTraitsIntegral<uint16_t>
|
||||
{
|
||||
};
|
||||
@@ -141,6 +145,10 @@ template<> struct DataSerializerTraits_t<std::string>
|
||||
uint16_t len = static_cast<uint16_t>(str.size());
|
||||
uint16_t swapped = ByteSwapBE(len);
|
||||
stream->Write(&swapped);
|
||||
if (len == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
stream->WriteArray(str.c_str(), len);
|
||||
}
|
||||
static void decode(OpenRCT2::IStream* stream, std::string& res)
|
||||
@@ -148,7 +156,11 @@ template<> struct DataSerializerTraits_t<std::string>
|
||||
uint16_t len;
|
||||
stream->Read(&len);
|
||||
len = ByteSwapBE(len);
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
res = "";
|
||||
return;
|
||||
}
|
||||
const char* str = stream->ReadArray<char>(len);
|
||||
res.assign(str, len);
|
||||
|
||||
@@ -157,7 +169,10 @@ template<> struct DataSerializerTraits_t<std::string>
|
||||
static void log(OpenRCT2::IStream* stream, const std::string& str)
|
||||
{
|
||||
stream->Write("\"", 1);
|
||||
stream->Write(str.data(), str.size());
|
||||
if (str.size() != 0)
|
||||
{
|
||||
stream->Write(str.data(), str.size());
|
||||
}
|
||||
stream->Write("\"", 1);
|
||||
}
|
||||
};
|
||||
@@ -327,6 +342,10 @@ template<size_t _Size> struct DataSerializerTraits_t<uint8_t[_Size]> : public Da
|
||||
{
|
||||
};
|
||||
|
||||
template<size_t _Size> struct DataSerializerTraits_t<utf8[_Size]> : public DataSerializerTraitsPODArray<utf8, _Size>
|
||||
{
|
||||
};
|
||||
|
||||
template<size_t _Size> struct DataSerializerTraits_t<uint16_t[_Size]> : public DataSerializerTraitsPODArray<uint16_t, _Size>
|
||||
{
|
||||
};
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "../common.h"
|
||||
#include "Console.hpp"
|
||||
#include "DataSerialiser.h"
|
||||
#include "File.h"
|
||||
#include "FileScanner.h"
|
||||
#include "FileStream.h"
|
||||
@@ -130,14 +131,9 @@ protected:
|
||||
virtual std::tuple<bool, TItem> Create(int32_t language, const std::string& path) const abstract;
|
||||
|
||||
/**
|
||||
* Serialises an index item to the given stream.
|
||||
* Serialises/DeSerialises an index item to/from the given stream.
|
||||
*/
|
||||
virtual void Serialise(OpenRCT2::IStream* stream, const TItem& item) const abstract;
|
||||
|
||||
/**
|
||||
* Deserialises an index item from the given stream.
|
||||
*/
|
||||
virtual TItem Deserialise(OpenRCT2::IStream* stream) const abstract;
|
||||
virtual void Serialise(DataSerialiser& ds, TItem& item) const abstract;
|
||||
|
||||
private:
|
||||
ScanResult Scan() const
|
||||
@@ -272,10 +268,12 @@ private:
|
||||
&& header.Stats.PathChecksum == stats.PathChecksum)
|
||||
{
|
||||
items.reserve(header.NumItems);
|
||||
DataSerialiser ds(false, fs);
|
||||
// Directory is the same, just read the saved items
|
||||
for (uint32_t i = 0; i < header.NumItems; i++)
|
||||
{
|
||||
auto item = Deserialise(&fs);
|
||||
TItem item;
|
||||
Serialise(ds, item);
|
||||
items.emplace_back(std::move(item));
|
||||
}
|
||||
loadedItems = true;
|
||||
@@ -294,7 +292,7 @@ private:
|
||||
return std::make_tuple(loadedItems, std::move(items));
|
||||
}
|
||||
|
||||
void WriteIndexFile(int32_t language, const DirectoryStats& stats, const std::vector<TItem>& items) const
|
||||
void WriteIndexFile(int32_t language, const DirectoryStats& stats, std::vector<TItem>& items) const
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -312,10 +310,11 @@ private:
|
||||
header.NumItems = static_cast<uint32_t>(items.size());
|
||||
fs.WriteValue(header);
|
||||
|
||||
DataSerialiser ds(true, fs);
|
||||
// Write items
|
||||
for (const auto& item : items)
|
||||
for (auto& item : items)
|
||||
{
|
||||
Serialise(&fs, item);
|
||||
Serialise(ds, item);
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
|
||||
@@ -168,6 +168,10 @@ namespace OpenRCT2
|
||||
|
||||
void FileStream::Write(const void* buffer, uint64_t length)
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (fwrite(buffer, static_cast<size_t>(length), 1, _file) != 1)
|
||||
{
|
||||
throw IOException("Unable to write to file.");
|
||||
|
||||
@@ -76,7 +76,7 @@ class ObjectFileIndex final : public FileIndex<ObjectRepositoryItem>
|
||||
{
|
||||
private:
|
||||
static constexpr uint32_t MAGIC_NUMBER = 0x5844494F; // OIDX
|
||||
static constexpr uint16_t VERSION = 25;
|
||||
static constexpr uint16_t VERSION = 26;
|
||||
static constexpr auto PATTERN = "*.dat;*.pob;*.json;*.parkobj";
|
||||
|
||||
IObjectRepository& _objectRepository;
|
||||
@@ -126,48 +126,26 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
void Serialise(IStream* stream, const ObjectRepositoryItem& item) const override
|
||||
void Serialise(DataSerialiser& ds, ObjectRepositoryItem& item) const override
|
||||
{
|
||||
stream->WriteString(item.Identifier);
|
||||
stream->WriteValue(item.ObjectEntry);
|
||||
stream->WriteString(item.Path);
|
||||
stream->WriteString(item.Name);
|
||||
ds << item.Identifier;
|
||||
ds << item.ObjectEntry;
|
||||
ds << item.Path;
|
||||
ds << item.Name;
|
||||
|
||||
uint8_t sourceLength = static_cast<uint8_t>(item.Sources.size());
|
||||
stream->WriteValue(sourceLength);
|
||||
for (auto source : item.Sources)
|
||||
{
|
||||
stream->WriteValue(source);
|
||||
}
|
||||
|
||||
uint8_t authorsLength = static_cast<uint8_t>(item.Authors.size());
|
||||
stream->WriteValue(authorsLength);
|
||||
for (const auto& author : item.Authors)
|
||||
{
|
||||
stream->WriteString(author);
|
||||
}
|
||||
ds << item.Sources;
|
||||
ds << item.Authors;
|
||||
|
||||
switch (item.ObjectEntry.GetType())
|
||||
{
|
||||
case ObjectType::Ride:
|
||||
stream->WriteValue<uint8_t>(item.RideInfo.RideFlags);
|
||||
for (int32_t i = 0; i < MAX_CATEGORIES_PER_RIDE; i++)
|
||||
{
|
||||
stream->WriteValue<uint8_t>(item.RideInfo.RideCategory[i]);
|
||||
}
|
||||
for (int32_t i = 0; i < MAX_RIDE_TYPES_PER_RIDE_ENTRY; i++)
|
||||
{
|
||||
stream->WriteValue<uint8_t>(item.RideInfo.RideType[i]);
|
||||
}
|
||||
ds << item.RideInfo.RideFlags;
|
||||
ds << item.RideInfo.RideCategory;
|
||||
ds << item.RideInfo.RideType;
|
||||
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)
|
||||
{
|
||||
serialiser << entry;
|
||||
}
|
||||
ds << item.SceneryGroupInfo.Entries;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -176,60 +154,6 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
ObjectRepositoryItem Deserialise(IStream* stream) const override
|
||||
{
|
||||
ObjectRepositoryItem item;
|
||||
|
||||
item.Identifier = stream->ReadStdString();
|
||||
item.ObjectEntry = stream->ReadValue<rct_object_entry>();
|
||||
item.Path = stream->ReadStdString();
|
||||
item.Name = stream->ReadStdString();
|
||||
|
||||
auto sourceLength = stream->ReadValue<uint8_t>();
|
||||
for (size_t i = 0; i < sourceLength; i++)
|
||||
{
|
||||
auto value = stream->ReadValue<uint8_t>();
|
||||
item.Sources.push_back(static_cast<ObjectSourceGame>(value));
|
||||
}
|
||||
|
||||
auto authorsLength = stream->ReadValue<uint8_t>();
|
||||
for (size_t i = 0; i < authorsLength; i++)
|
||||
{
|
||||
auto author = stream->ReadStdString();
|
||||
item.Authors.emplace_back(author);
|
||||
}
|
||||
|
||||
switch (item.ObjectEntry.GetType())
|
||||
{
|
||||
case ObjectType::Ride:
|
||||
item.RideInfo.RideFlags = stream->ReadValue<uint8_t>();
|
||||
for (int32_t i = 0; i < MAX_CATEGORIES_PER_RIDE; i++)
|
||||
{
|
||||
item.RideInfo.RideCategory[i] = stream->ReadValue<uint8_t>();
|
||||
}
|
||||
for (int32_t i = 0; i < MAX_RIDE_TYPES_PER_RIDE_ENTRY; i++)
|
||||
{
|
||||
item.RideInfo.RideType[i] = stream->ReadValue<uint8_t>();
|
||||
}
|
||||
break;
|
||||
case ObjectType::SceneryGroup:
|
||||
{
|
||||
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++)
|
||||
{
|
||||
serialiser << item.SceneryGroupInfo.Entries[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Switch processes only ObjectType::Ride and ObjectType::SceneryGroup
|
||||
break;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
private:
|
||||
bool IsTrackReadOnly(const std::string& path) const
|
||||
{
|
||||
|
||||
@@ -57,7 +57,7 @@ class TrackDesignFileIndex final : public FileIndex<TrackRepositoryItem>
|
||||
{
|
||||
private:
|
||||
static constexpr uint32_t MAGIC_NUMBER = 0x58444954; // TIDX
|
||||
static constexpr uint16_t VERSION = 3;
|
||||
static constexpr uint16_t VERSION = 4;
|
||||
static constexpr auto PATTERN = "*.td4;*.td6";
|
||||
|
||||
public:
|
||||
@@ -97,24 +97,13 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
void Serialise(IStream* stream, const TrackRepositoryItem& item) const override
|
||||
void Serialise(DataSerialiser& ds, TrackRepositoryItem& item) const override
|
||||
{
|
||||
stream->WriteString(item.Name);
|
||||
stream->WriteString(item.Path);
|
||||
stream->WriteValue(item.RideType);
|
||||
stream->WriteString(item.ObjectEntry);
|
||||
stream->WriteValue(item.Flags);
|
||||
}
|
||||
|
||||
TrackRepositoryItem Deserialise(IStream* stream) const override
|
||||
{
|
||||
TrackRepositoryItem item;
|
||||
item.Name = stream->ReadStdString();
|
||||
item.Path = stream->ReadStdString();
|
||||
item.RideType = stream->ReadValue<uint8_t>();
|
||||
item.ObjectEntry = stream->ReadStdString();
|
||||
item.Flags = stream->ReadValue<uint32_t>();
|
||||
return item;
|
||||
ds << item.Name;
|
||||
ds << item.Path;
|
||||
ds << item.RideType;
|
||||
ds << item.ObjectEntry;
|
||||
ds << item.Flags;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -129,7 +129,7 @@ class ScenarioFileIndex final : public FileIndex<scenario_index_entry>
|
||||
{
|
||||
private:
|
||||
static constexpr uint32_t MAGIC_NUMBER = 0x58444953; // SIDX
|
||||
static constexpr uint16_t VERSION = 3;
|
||||
static constexpr uint16_t VERSION = 4;
|
||||
static constexpr auto PATTERN = "*.sc4;*.sc6;*.sea";
|
||||
|
||||
public:
|
||||
@@ -159,49 +159,22 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
void Serialise(IStream* stream, const scenario_index_entry& item) const override
|
||||
void Serialise(DataSerialiser& ds, scenario_index_entry& item) const override
|
||||
{
|
||||
stream->Write(item.path, sizeof(item.path));
|
||||
stream->WriteValue(item.timestamp);
|
||||
ds << item.path;
|
||||
ds << item.timestamp;
|
||||
ds << item.category;
|
||||
ds << item.source_game;
|
||||
ds << item.source_index;
|
||||
ds << item.sc_id;
|
||||
ds << item.objective_type;
|
||||
ds << item.objective_arg_1;
|
||||
ds << item.objective_arg_2;
|
||||
ds << item.objective_arg_3;
|
||||
|
||||
stream->WriteValue(item.category);
|
||||
stream->WriteValue(item.source_game);
|
||||
stream->WriteValue(item.source_index);
|
||||
stream->WriteValue(item.sc_id);
|
||||
|
||||
stream->WriteValue(item.objective_type);
|
||||
stream->WriteValue(item.objective_arg_1);
|
||||
stream->WriteValue(item.objective_arg_2);
|
||||
stream->WriteValue(item.objective_arg_3);
|
||||
|
||||
stream->Write(item.internal_name, sizeof(item.internal_name));
|
||||
stream->Write(item.name, sizeof(item.name));
|
||||
stream->Write(item.details, sizeof(item.details));
|
||||
}
|
||||
|
||||
scenario_index_entry Deserialise(IStream* stream) const override
|
||||
{
|
||||
scenario_index_entry item;
|
||||
|
||||
stream->Read(item.path, sizeof(item.path));
|
||||
item.timestamp = stream->ReadValue<uint64_t>();
|
||||
|
||||
item.category = stream->ReadValue<uint8_t>();
|
||||
item.source_game = ScenarioSource{ stream->ReadValue<uint8_t>() };
|
||||
item.source_index = stream->ReadValue<int16_t>();
|
||||
item.sc_id = stream->ReadValue<uint16_t>();
|
||||
|
||||
item.objective_type = stream->ReadValue<uint8_t>();
|
||||
item.objective_arg_1 = stream->ReadValue<uint8_t>();
|
||||
item.objective_arg_2 = stream->ReadValue<int32_t>();
|
||||
item.objective_arg_3 = stream->ReadValue<int16_t>();
|
||||
item.highscore = nullptr;
|
||||
|
||||
stream->Read(item.internal_name, sizeof(item.internal_name));
|
||||
stream->Read(item.name, sizeof(item.name));
|
||||
stream->Read(item.details, sizeof(item.details));
|
||||
|
||||
return item;
|
||||
ds << item.internal_name;
|
||||
ds << item.name;
|
||||
ds << item.details;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user