mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-10 08:00:05 +00:00
Codechange: Preparation for ChunkHandler subclassing
This commit is contained in:
parent
7e7a4aad72
commit
f371a5ad70
@ -314,9 +314,9 @@ static void SlNullPointers()
|
|||||||
_sl_version = SAVEGAME_VERSION;
|
_sl_version = SAVEGAME_VERSION;
|
||||||
|
|
||||||
for (auto &ch : ChunkHandlers()) {
|
for (auto &ch : ChunkHandlers()) {
|
||||||
if (ch.ptrs_proc != nullptr) {
|
if (ch.fix_pointers) {
|
||||||
Debug(sl, 3, "Nulling pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
|
Debug(sl, 3, "Nulling pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
|
||||||
ch.ptrs_proc();
|
ch.FixPointers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2114,6 +2114,48 @@ void SlAutolength(AutolengthProc *proc, void *arg)
|
|||||||
if (offs != _sl.dumper->GetSize()) SlErrorCorrupt("Invalid chunk size");
|
if (offs != _sl.dumper->GetSize()) SlErrorCorrupt("Invalid chunk size");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChunkHandler::Save() const
|
||||||
|
{
|
||||||
|
assert(this->save_proc != nullptr);
|
||||||
|
this->save_proc();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChunkHandler::Load() const
|
||||||
|
{
|
||||||
|
assert(this->load_proc != nullptr);
|
||||||
|
this->load_proc();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChunkHandler::FixPointers() const
|
||||||
|
{
|
||||||
|
assert(this->ptrs_proc != nullptr);
|
||||||
|
this->ptrs_proc();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChunkHandler::LoadCheck(size_t len) const
|
||||||
|
{
|
||||||
|
if (this->load_check) {
|
||||||
|
assert(this->load_check_proc != nullptr);
|
||||||
|
this->load_check_proc();
|
||||||
|
} else {
|
||||||
|
switch (_sl.block_mode) {
|
||||||
|
case CH_TABLE:
|
||||||
|
case CH_SPARSE_TABLE:
|
||||||
|
SlTableHeader({});
|
||||||
|
FALLTHROUGH;
|
||||||
|
case CH_ARRAY:
|
||||||
|
case CH_SPARSE_ARRAY:
|
||||||
|
SlSkipArray();
|
||||||
|
break;
|
||||||
|
case CH_RIFF:
|
||||||
|
SlSkipBytes(len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a chunk of data (eg vehicles, stations, etc.)
|
* Load a chunk of data (eg vehicles, stations, etc.)
|
||||||
* @param ch The chunkhandler that will be used for the operation
|
* @param ch The chunkhandler that will be used for the operation
|
||||||
@ -2129,7 +2171,7 @@ static void SlLoadChunk(const ChunkHandler &ch)
|
|||||||
_sl.expect_table_header = (_sl.block_mode == CH_TABLE || _sl.block_mode == CH_SPARSE_TABLE);
|
_sl.expect_table_header = (_sl.block_mode == CH_TABLE || _sl.block_mode == CH_SPARSE_TABLE);
|
||||||
|
|
||||||
/* The header should always be at the start. Read the length; the
|
/* The header should always be at the start. Read the length; the
|
||||||
* load_proc() should as first action process the header. */
|
* Load() should as first action process the header. */
|
||||||
if (_sl.expect_table_header) {
|
if (_sl.expect_table_header) {
|
||||||
SlIterateArray();
|
SlIterateArray();
|
||||||
}
|
}
|
||||||
@ -2138,12 +2180,12 @@ static void SlLoadChunk(const ChunkHandler &ch)
|
|||||||
case CH_TABLE:
|
case CH_TABLE:
|
||||||
case CH_ARRAY:
|
case CH_ARRAY:
|
||||||
_sl.array_index = 0;
|
_sl.array_index = 0;
|
||||||
ch.load_proc();
|
ch.Load();
|
||||||
if (_next_offs != 0) SlErrorCorrupt("Invalid array length");
|
if (_next_offs != 0) SlErrorCorrupt("Invalid array length");
|
||||||
break;
|
break;
|
||||||
case CH_SPARSE_TABLE:
|
case CH_SPARSE_TABLE:
|
||||||
case CH_SPARSE_ARRAY:
|
case CH_SPARSE_ARRAY:
|
||||||
ch.load_proc();
|
ch.Load();
|
||||||
if (_next_offs != 0) SlErrorCorrupt("Invalid array length");
|
if (_next_offs != 0) SlErrorCorrupt("Invalid array length");
|
||||||
break;
|
break;
|
||||||
case CH_RIFF:
|
case CH_RIFF:
|
||||||
@ -2152,7 +2194,7 @@ static void SlLoadChunk(const ChunkHandler &ch)
|
|||||||
len += SlReadUint16();
|
len += SlReadUint16();
|
||||||
_sl.obj_len = len;
|
_sl.obj_len = len;
|
||||||
endoffs = _sl.reader->GetSize() + len;
|
endoffs = _sl.reader->GetSize() + len;
|
||||||
ch.load_proc();
|
ch.Load();
|
||||||
if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
|
if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -2179,9 +2221,8 @@ static void SlLoadCheckChunk(const ChunkHandler &ch)
|
|||||||
_sl.expect_table_header = (_sl.block_mode == CH_TABLE || _sl.block_mode == CH_SPARSE_TABLE);
|
_sl.expect_table_header = (_sl.block_mode == CH_TABLE || _sl.block_mode == CH_SPARSE_TABLE);
|
||||||
|
|
||||||
/* The header should always be at the start. Read the length; the
|
/* The header should always be at the start. Read the length; the
|
||||||
* load_check_proc() should as first action process the header. */
|
* LoadCheck() should as first action process the header. */
|
||||||
if (_sl.expect_table_header && ch.load_check_proc != nullptr) {
|
if (_sl.expect_table_header) {
|
||||||
/* If load_check_proc() is nullptr, SlSkipArray() will already skip the header. */
|
|
||||||
SlIterateArray();
|
SlIterateArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2189,19 +2230,11 @@ static void SlLoadCheckChunk(const ChunkHandler &ch)
|
|||||||
case CH_TABLE:
|
case CH_TABLE:
|
||||||
case CH_ARRAY:
|
case CH_ARRAY:
|
||||||
_sl.array_index = 0;
|
_sl.array_index = 0;
|
||||||
if (ch.load_check_proc != nullptr) {
|
ch.LoadCheck();
|
||||||
ch.load_check_proc();
|
|
||||||
} else {
|
|
||||||
SlSkipArray();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case CH_SPARSE_TABLE:
|
case CH_SPARSE_TABLE:
|
||||||
case CH_SPARSE_ARRAY:
|
case CH_SPARSE_ARRAY:
|
||||||
if (ch.load_check_proc != nullptr) {
|
ch.LoadCheck();
|
||||||
ch.load_check_proc();
|
|
||||||
} else {
|
|
||||||
SlSkipArray();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case CH_RIFF:
|
case CH_RIFF:
|
||||||
/* Read length */
|
/* Read length */
|
||||||
@ -2209,11 +2242,7 @@ static void SlLoadCheckChunk(const ChunkHandler &ch)
|
|||||||
len += SlReadUint16();
|
len += SlReadUint16();
|
||||||
_sl.obj_len = len;
|
_sl.obj_len = len;
|
||||||
endoffs = _sl.reader->GetSize() + len;
|
endoffs = _sl.reader->GetSize() + len;
|
||||||
if (ch.load_check_proc) {
|
ch.LoadCheck(len);
|
||||||
ch.load_check_proc();
|
|
||||||
} else {
|
|
||||||
SlSkipBytes(len);
|
|
||||||
}
|
|
||||||
if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
|
if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -2233,9 +2262,6 @@ static void SlSaveChunk(const ChunkHandler &ch)
|
|||||||
{
|
{
|
||||||
if (ch.type == CH_READONLY) return;
|
if (ch.type == CH_READONLY) return;
|
||||||
|
|
||||||
ChunkSaveLoadProc *proc = ch.save_proc;
|
|
||||||
assert(proc != nullptr);
|
|
||||||
|
|
||||||
SlWriteUint32(ch.id);
|
SlWriteUint32(ch.id);
|
||||||
Debug(sl, 2, "Saving chunk {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
|
Debug(sl, 2, "Saving chunk {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
|
||||||
|
|
||||||
@ -2246,19 +2272,19 @@ static void SlSaveChunk(const ChunkHandler &ch)
|
|||||||
|
|
||||||
switch (_sl.block_mode) {
|
switch (_sl.block_mode) {
|
||||||
case CH_RIFF:
|
case CH_RIFF:
|
||||||
proc();
|
ch.Save();
|
||||||
break;
|
break;
|
||||||
case CH_TABLE:
|
case CH_TABLE:
|
||||||
case CH_ARRAY:
|
case CH_ARRAY:
|
||||||
_sl.last_array_index = 0;
|
_sl.last_array_index = 0;
|
||||||
SlWriteByte(_sl.block_mode);
|
SlWriteByte(_sl.block_mode);
|
||||||
proc();
|
ch.Save();
|
||||||
SlWriteArrayLength(0); // Terminate arrays
|
SlWriteArrayLength(0); // Terminate arrays
|
||||||
break;
|
break;
|
||||||
case CH_SPARSE_TABLE:
|
case CH_SPARSE_TABLE:
|
||||||
case CH_SPARSE_ARRAY:
|
case CH_SPARSE_ARRAY:
|
||||||
SlWriteByte(_sl.block_mode);
|
SlWriteByte(_sl.block_mode);
|
||||||
proc();
|
ch.Save();
|
||||||
SlWriteArrayLength(0); // Terminate arrays
|
SlWriteArrayLength(0); // Terminate arrays
|
||||||
break;
|
break;
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
@ -2326,9 +2352,9 @@ static void SlFixPointers()
|
|||||||
_sl.action = SLA_PTRS;
|
_sl.action = SLA_PTRS;
|
||||||
|
|
||||||
for (auto &ch : ChunkHandlers()) {
|
for (auto &ch : ChunkHandlers()) {
|
||||||
if (ch.ptrs_proc != nullptr) {
|
if (ch.fix_pointers) {
|
||||||
Debug(sl, 3, "Fixing pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
|
Debug(sl, 3, "Fixing pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
|
||||||
ch.ptrs_proc();
|
ch.FixPointers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,6 +407,47 @@ struct ChunkHandler {
|
|||||||
ChunkSaveLoadProc *ptrs_proc; ///< Manipulate pointers in the chunk.
|
ChunkSaveLoadProc *ptrs_proc; ///< Manipulate pointers in the chunk.
|
||||||
ChunkSaveLoadProc *load_check_proc; ///< Load procedure for game preview.
|
ChunkSaveLoadProc *load_check_proc; ///< Load procedure for game preview.
|
||||||
ChunkType type; ///< Type of the chunk. @see ChunkType
|
ChunkType type; ///< Type of the chunk. @see ChunkType
|
||||||
|
|
||||||
|
bool fix_pointers = false;
|
||||||
|
bool load_check = false;
|
||||||
|
|
||||||
|
ChunkHandler(uint32 id, ChunkType type) : id(id), type(type) {}
|
||||||
|
|
||||||
|
ChunkHandler(uint32 id, ChunkSaveLoadProc *save_proc, ChunkSaveLoadProc *load_proc, ChunkSaveLoadProc *ptrs_proc, ChunkSaveLoadProc *load_check_proc, ChunkType type)
|
||||||
|
: id(id), save_proc(save_proc), load_proc(load_proc), ptrs_proc(ptrs_proc), load_check_proc(load_check_proc), type(type)
|
||||||
|
{
|
||||||
|
this->fix_pointers = ptrs_proc != nullptr;
|
||||||
|
this->load_check = load_check_proc != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~ChunkHandler() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the chunk.
|
||||||
|
* Must be overridden, unless Chunk type is CH_READONLY.
|
||||||
|
*/
|
||||||
|
virtual void Save() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the chunk.
|
||||||
|
* Must be overridden.
|
||||||
|
*/
|
||||||
|
virtual void Load() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fix the pointers.
|
||||||
|
* Pointers are saved using the index of the pointed object.
|
||||||
|
* On load, pointers are filled with indices and need to be fixed to point to the real object.
|
||||||
|
* Must be overridden if the chunk saves any pointer.
|
||||||
|
*/
|
||||||
|
virtual void FixPointers() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the chunk for game preview.
|
||||||
|
* Default implementation just skips the data.
|
||||||
|
* @param len Number of bytes to skip.
|
||||||
|
*/
|
||||||
|
virtual void LoadCheck(size_t len = 0) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A table of ChunkHandler entries. */
|
/** A table of ChunkHandler entries. */
|
||||||
|
Loading…
Reference in New Issue
Block a user