forked from mirror/OpenTTD
Change: store length of SL_STRUCTLIST in the savegame
This wasn't consistently done, and often variables were used that were read by an earlier blob. By moving it next to the struct itself, the code becomes a bit more self-contained and easier to read. Additionally, this allows for external tooling to know how many structs to expect, instead of having to know where to find the length-field or a hard-coded value that can change at any moment.
This commit is contained in:
committed by
Patric Stout
parent
d0bcb9839a
commit
a146bcfe93
@@ -37,6 +37,12 @@ public:
|
||||
|
||||
void Save(Node *bn) const override
|
||||
{
|
||||
uint16 size = 0;
|
||||
for (NodeID to = _linkgraph_from; to != INVALID_NODE; to = _linkgraph->edges[_linkgraph_from][to].next_edge) {
|
||||
size++;
|
||||
}
|
||||
|
||||
SlSetStructListLength(size);
|
||||
for (NodeID to = _linkgraph_from; to != INVALID_NODE; to = _linkgraph->edges[_linkgraph_from][to].next_edge) {
|
||||
SlObject(&_linkgraph->edges[_linkgraph_from][to], this->GetDescription());
|
||||
}
|
||||
@@ -54,11 +60,18 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
size_t used_size = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? max_size : SlGetStructListLength(UINT16_MAX);
|
||||
|
||||
/* ... but as that wasted a lot of space we save a sparse matrix now. */
|
||||
for (NodeID to = _linkgraph_from; to != INVALID_NODE; to = _linkgraph->edges[_linkgraph_from][to].next_edge) {
|
||||
if (used_size == 0) SlErrorCorrupt("Link graph structure overflow");
|
||||
used_size--;
|
||||
|
||||
if (to >= max_size) SlErrorCorrupt("Link graph structure overflow");
|
||||
SlObject(&_linkgraph->edges[_linkgraph_from][to], this->GetDescription());
|
||||
}
|
||||
|
||||
if (!IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) && used_size > 0) SlErrorCorrupt("Corrupted link graph");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -77,6 +90,7 @@ public:
|
||||
{
|
||||
_linkgraph = lg;
|
||||
|
||||
SlSetStructListLength(lg->Size());
|
||||
for (NodeID from = 0; from < lg->Size(); ++from) {
|
||||
_linkgraph_from = from;
|
||||
SlObject(&lg->nodes[from], this->GetDescription());
|
||||
@@ -87,8 +101,9 @@ public:
|
||||
{
|
||||
_linkgraph = lg;
|
||||
|
||||
lg->Init(_num_nodes);
|
||||
for (NodeID from = 0; from < _num_nodes; ++from) {
|
||||
uint16 length = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? _num_nodes : (uint16)SlGetStructListLength(UINT16_MAX);
|
||||
lg->Init(length);
|
||||
for (NodeID from = 0; from < length; ++from) {
|
||||
_linkgraph_from = from;
|
||||
SlObject(&lg->nodes[from], this->GetDescription());
|
||||
}
|
||||
@@ -103,7 +118,7 @@ SaveLoadTable GetLinkGraphDesc()
|
||||
{
|
||||
static const SaveLoad link_graph_desc[] = {
|
||||
SLE_VAR(LinkGraph, last_compression, SLE_INT32),
|
||||
SLEG_VAR(_num_nodes, SLE_UINT16),
|
||||
SLEG_CONDVAR(_num_nodes, SLE_UINT16, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH),
|
||||
SLE_VAR(LinkGraph, cargo, SLE_UINT8),
|
||||
SLEG_STRUCTLIST(SlLinkgraphNode),
|
||||
};
|
||||
@@ -227,8 +242,6 @@ void AfterLoadLinkGraphs()
|
||||
static void Save_LGRP()
|
||||
{
|
||||
for (LinkGraph *lg : LinkGraph::Iterate()) {
|
||||
_num_nodes = lg->Size();
|
||||
|
||||
SlSetArrayIndex(lg->index);
|
||||
SlObject(lg, GetLinkGraphDesc());
|
||||
}
|
||||
@@ -252,8 +265,6 @@ static void Load_LGRP()
|
||||
static void Save_LGRJ()
|
||||
{
|
||||
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
|
||||
_num_nodes = lgj->Size();
|
||||
|
||||
SlSetArrayIndex(lgj->index);
|
||||
SlObject(lgj, GetLinkGraphJobDesc());
|
||||
}
|
||||
|
Reference in New Issue
Block a user