Codechange: Preparation for ChunkHandler subclassing

pull/332/head
glx22 3 years ago committed by Loïc Guilloux
parent 7e7a4aad72
commit f371a5ad70

@ -314,9 +314,9 @@ static void SlNullPointers()
_sl_version = SAVEGAME_VERSION;
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);
ch.ptrs_proc();
ch.FixPointers();
}
}
@ -2114,6 +2114,48 @@ void SlAutolength(AutolengthProc *proc, void *arg)
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.)
* @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);
/* 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) {
SlIterateArray();
}
@ -2138,12 +2180,12 @@ static void SlLoadChunk(const ChunkHandler &ch)
case CH_TABLE:
case CH_ARRAY:
_sl.array_index = 0;
ch.load_proc();
ch.Load();
if (_next_offs != 0) SlErrorCorrupt("Invalid array length");
break;
case CH_SPARSE_TABLE:
case CH_SPARSE_ARRAY:
ch.load_proc();
ch.Load();
if (_next_offs != 0) SlErrorCorrupt("Invalid array length");
break;
case CH_RIFF:
@ -2152,7 +2194,7 @@ static void SlLoadChunk(const ChunkHandler &ch)
len += SlReadUint16();
_sl.obj_len = len;
endoffs = _sl.reader->GetSize() + len;
ch.load_proc();
ch.Load();
if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
break;
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);
/* The header should always be at the start. Read the length; the
* load_check_proc() should as first action process the header. */
if (_sl.expect_table_header && ch.load_check_proc != nullptr) {
/* If load_check_proc() is nullptr, SlSkipArray() will already skip the header. */
* LoadCheck() should as first action process the header. */
if (_sl.expect_table_header) {
SlIterateArray();
}
@ -2189,19 +2230,11 @@ static void SlLoadCheckChunk(const ChunkHandler &ch)
case CH_TABLE:
case CH_ARRAY:
_sl.array_index = 0;
if (ch.load_check_proc != nullptr) {
ch.load_check_proc();
} else {
SlSkipArray();
}
ch.LoadCheck();
break;
case CH_SPARSE_TABLE:
case CH_SPARSE_ARRAY:
if (ch.load_check_proc != nullptr) {
ch.load_check_proc();
} else {
SlSkipArray();
}
ch.LoadCheck();
break;
case CH_RIFF:
/* Read length */
@ -2209,11 +2242,7 @@ static void SlLoadCheckChunk(const ChunkHandler &ch)
len += SlReadUint16();
_sl.obj_len = len;
endoffs = _sl.reader->GetSize() + len;
if (ch.load_check_proc) {
ch.load_check_proc();
} else {
SlSkipBytes(len);
}
ch.LoadCheck(len);
if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
break;
default:
@ -2233,9 +2262,6 @@ static void SlSaveChunk(const ChunkHandler &ch)
{
if (ch.type == CH_READONLY) return;
ChunkSaveLoadProc *proc = ch.save_proc;
assert(proc != nullptr);
SlWriteUint32(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) {
case CH_RIFF:
proc();
ch.Save();
break;
case CH_TABLE:
case CH_ARRAY:
_sl.last_array_index = 0;
SlWriteByte(_sl.block_mode);
proc();
ch.Save();
SlWriteArrayLength(0); // Terminate arrays
break;
case CH_SPARSE_TABLE:
case CH_SPARSE_ARRAY:
SlWriteByte(_sl.block_mode);
proc();
ch.Save();
SlWriteArrayLength(0); // Terminate arrays
break;
default: NOT_REACHED();
@ -2326,9 +2352,9 @@ static void SlFixPointers()
_sl.action = SLA_PTRS;
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);
ch.ptrs_proc();
ch.FixPointers();
}
}

@ -407,6 +407,47 @@ struct ChunkHandler {
ChunkSaveLoadProc *ptrs_proc; ///< Manipulate pointers in the chunk.
ChunkSaveLoadProc *load_check_proc; ///< Load procedure for game preview.
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. */

Loading…
Cancel
Save