mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-11 13:10:45 +00:00
Saveload: Use table format for link graph chunks
This commit is contained in:
parent
4a12c79c5c
commit
662cae111c
@ -382,10 +382,10 @@ public:
|
||||
protected:
|
||||
friend class LinkGraph::ConstNode;
|
||||
friend class LinkGraph::Node;
|
||||
friend SaveLoadTable GetLinkGraphDesc();
|
||||
friend SaveLoadTable GetLinkGraphJobDesc();
|
||||
friend void Save_LinkGraph(LinkGraph &lg);
|
||||
friend void Load_LinkGraph(LinkGraph &lg);
|
||||
friend struct LinkGraphNodeStructHandler;
|
||||
friend struct LinkGraphNonTableHelper;
|
||||
friend NamedSaveLoadTable GetLinkGraphDesc();
|
||||
friend NamedSaveLoadTable GetLinkGraphJobDesc();
|
||||
|
||||
friend upstream_sl::SaveLoadTable upstream_sl::GetLinkGraphDesc();
|
||||
friend upstream_sl::SaveLoadTable upstream_sl::GetLinkGraphJobDesc();
|
||||
|
@ -128,7 +128,7 @@ private:
|
||||
|
||||
typedef std::vector<NodeAnnotation> NodeAnnotationVector;
|
||||
|
||||
friend SaveLoadTable GetLinkGraphJobDesc();
|
||||
friend NamedSaveLoadTable GetLinkGraphJobDesc();
|
||||
friend upstream_sl::SaveLoadTable upstream_sl::GetLinkGraphJobDesc();
|
||||
friend void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj);
|
||||
friend void LinkGraphFixupAfterLoad(bool compression_was_date);
|
||||
|
@ -46,7 +46,7 @@ private:
|
||||
~LinkGraphSchedule();
|
||||
typedef std::list<LinkGraph *> GraphList;
|
||||
typedef std::list<std::unique_ptr<LinkGraphJob>> JobList;
|
||||
friend SaveLoadTable GetLinkGraphScheduleDesc();
|
||||
friend NamedSaveLoadTable GetLinkGraphScheduleDesc();
|
||||
friend upstream_sl::SaveLoadTable upstream_sl::GetLinkGraphScheduleDesc();
|
||||
|
||||
protected:
|
||||
|
@ -183,7 +183,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
||||
{ XSLFI_NEW_SIGNAL_STYLES, XSCF_NULL, 4, 4, "new_signal_styles", nullptr, nullptr, "XBST,NSID" },
|
||||
{ XSLFI_NO_TREE_COUNTER, XSCF_IGNORABLE_ALL, 1, 1, "no_tree_counter", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TOWN_SETTING_OVERRIDE, XSCF_NULL, 1, 1, "town_setting_override", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_LINKGRAPH_SPARSE_EDGES, XSCF_NULL, 1, 1, "linkgraph_sparse_edges", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_LINKGRAPH_SPARSE_EDGES, XSCF_NULL, 2, 2, "linkgraph_sparse_edges", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_AUX_TILE_LOOP, XSCF_NULL, 1, 1, "aux_tile_loop", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_NEWGRF_ENTITY_EXTRA, XSCF_NULL, 2, 2, "newgrf_entity_extra", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TNNC_CHUNK, XSCF_IGNORABLE_ALL, 0, 1, "tnnc_chunk", nullptr, nullptr, "TNNC" },
|
||||
@ -220,6 +220,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
||||
{ XSLFI_TABLE_NEWGRF_SL, XSCF_NULL, 2, 2, "table_newgrf_sl", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TABLE_INDUSTRY_SL, XSCF_NULL, 2, 2, "table_industry_sl", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TABLE_STATION_SL, XSCF_NULL, 1, 1, "table_station_sl", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TABLE_LINKGRAPH_SL, XSCF_NULL, 1, 1, "table_linkgraph_sl", nullptr, nullptr, nullptr },
|
||||
|
||||
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr }, // This is the end marker
|
||||
};
|
||||
|
@ -176,6 +176,7 @@ enum SlXvFeatureIndex {
|
||||
///< v2: INDY
|
||||
XSLFI_TABLE_STATION_SL, ///< Use table format for station chunks:
|
||||
///< v1: STNN
|
||||
XSLFI_TABLE_LINKGRAPH_SL, ///< Use table format for link graph chunks:
|
||||
|
||||
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
|
||||
XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk
|
||||
|
@ -21,23 +21,153 @@ typedef LinkGraph::BaseNode Node;
|
||||
typedef LinkGraph::BaseEdge Edge;
|
||||
|
||||
static uint16_t _num_nodes;
|
||||
static uint16_t _to_node;
|
||||
|
||||
/* Edges and nodes are saved in the correct order, so we don't need to save their IDs. */
|
||||
|
||||
/**
|
||||
* SaveLoad desc for a link graph edge.
|
||||
*/
|
||||
static const NamedSaveLoad _edge_desc[] = {
|
||||
NSLT("to", SLTAG(SLTAG_CUSTOM_0, SLEG_VAR(_to_node, SLE_UINT16))),
|
||||
NSL("", SLE_CONDNULL(4, SL_MIN_VERSION, SLV_191)), // distance
|
||||
NSL("capacity", SLE_VAR(Edge, capacity, SLE_UINT32)),
|
||||
NSL("usage", SLE_VAR(Edge, usage, SLE_UINT32)),
|
||||
NSL("travel_time_sum", SLE_CONDVAR_X(Edge, travel_time_sum, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_TRAVEL_TIME))),
|
||||
NSL("last_unrestricted_update", SLE_VAR(Edge, last_unrestricted_update, SLE_INT32)),
|
||||
NSL("last_restricted_update", SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION)),
|
||||
NSL("last_aircraft_update", SLE_CONDVAR_X(Edge, last_aircraft_update, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_AIRCRAFT))),
|
||||
//SLE_VAR(Edge, next_edge, SLE_UINT16), // Removed since XSLFI_LINKGRAPH_SPARSE_EDGES
|
||||
};
|
||||
|
||||
struct LinkGraphEdgeStructHandler final : public HeaderOnlySaveLoadStructHandler {
|
||||
NamedSaveLoadTable GetDescription() const override
|
||||
{
|
||||
return _edge_desc;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* SaveLoad desc for a link graph node.
|
||||
*/
|
||||
static const NamedSaveLoad _node_desc[] = {
|
||||
NSL("xy", SLE_CONDVAR(Node, xy, SLE_UINT32, SLV_191, SL_MAX_VERSION)),
|
||||
NSL("supply", SLE_VAR(Node, supply, SLE_UINT32)),
|
||||
NSL("demand", SLE_VAR(Node, demand, SLE_UINT32)),
|
||||
NSL("station", SLE_VAR(Node, station, SLE_UINT16)),
|
||||
NSL("last_update", SLE_VAR(Node, last_update, SLE_INT32)),
|
||||
NSLTAG(SLTAG_CUSTOM_0, NSLT_STRUCTLIST<LinkGraphEdgeStructHandler>("edges")),
|
||||
};
|
||||
|
||||
struct LinkGraphNodeStructHandler final : public TypedSaveLoadStructHandler<LinkGraphNodeStructHandler, LinkGraph> {
|
||||
SaveLoadTable edge_description;
|
||||
|
||||
NamedSaveLoadTable GetDescription() const override
|
||||
{
|
||||
return _node_desc;
|
||||
}
|
||||
|
||||
void Save(LinkGraph *lg) const override
|
||||
{
|
||||
uint16_t size = lg->Size();
|
||||
SlSetStructListLength(size);
|
||||
|
||||
auto edge_iter = lg->edges.begin();
|
||||
auto edge_end = lg->edges.end();
|
||||
for (NodeID from = 0; from < size; ++from) {
|
||||
Node *node = &lg->nodes[from];
|
||||
SlObjectSaveFiltered(node, this->GetLoadDescription());
|
||||
|
||||
auto edge_start = edge_iter;
|
||||
uint count = 0;
|
||||
while (edge_iter != edge_end && edge_iter->first.first == from) {
|
||||
count++;
|
||||
++edge_iter;
|
||||
}
|
||||
SlWriteSimpleGamma(count);
|
||||
auto edge_end = edge_iter;
|
||||
for (auto it = edge_start; it != edge_end; ++it) {
|
||||
SlWriteUint16(it->first.second);
|
||||
Edge *edge = &it->second;
|
||||
SlObjectSaveFiltered(edge, this->edge_description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Load(LinkGraph *lg) const override
|
||||
{
|
||||
uint num_nodes = SlGetStructListLength(UINT16_MAX);
|
||||
lg->Init(num_nodes);
|
||||
|
||||
for (NodeID from = 0; from < num_nodes; ++from) {
|
||||
Node *node = &lg->nodes[from];
|
||||
SlObjectLoadFiltered(node, this->GetLoadDescription());
|
||||
|
||||
uint num_edges = SlGetStructListLength(UINT16_MAX);
|
||||
for (uint i = 0; i < num_edges; i++) {
|
||||
NodeID to = SlReadUint16();
|
||||
SlObjectLoadFiltered(&lg->edges[std::make_pair(from, to)], this->edge_description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoadedTableDescription() override
|
||||
{
|
||||
if (!SlXvIsFeaturePresent(XSLFI_LINKGRAPH_SPARSE_EDGES, 2)) {
|
||||
SlErrorCorrupt("XSLFI_LINKGRAPH_SPARSE_EDGES v2 unexpectedly not present");
|
||||
}
|
||||
|
||||
assert(!this->table_data.empty() && this->table_data.back().label_tag == SLTAG_CUSTOM_0);
|
||||
this->edge_description = this->table_data.back().struct_handler->GetLoadDescription();
|
||||
assert (!this->edge_description.empty() && this->edge_description.front().label_tag == SLTAG_CUSTOM_0);
|
||||
this->edge_description = this->edge_description.subspan(1);
|
||||
this->table_data.pop_back();
|
||||
}
|
||||
|
||||
void SavedTableDescription() override
|
||||
{
|
||||
if (this->table_data.empty() || this->table_data.back().label_tag != SLTAG_CUSTOM_0) SlErrorCorrupt("Link graph node format not as expected");
|
||||
this->edge_description = this->table_data.back().struct_handler->GetLoadDescription();
|
||||
if (this->edge_description.empty() || this->edge_description.front().label_tag != SLTAG_CUSTOM_0) SlErrorCorrupt("Link graph edge format not as expected");
|
||||
this->edge_description = this->edge_description.subspan(1);
|
||||
this->table_data.pop_back();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a SaveLoad array for a link graph.
|
||||
* @return SaveLoad array for link graph.
|
||||
*/
|
||||
SaveLoadTable GetLinkGraphDesc()
|
||||
NamedSaveLoadTable GetLinkGraphDesc()
|
||||
{
|
||||
static const SaveLoad link_graph_desc[] = {
|
||||
SLE_CONDVAR_X(LinkGraph, last_compression, SLE_VAR_I64 | SLE_FILE_I32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 0, 3)),
|
||||
SLE_CONDVAR_X(LinkGraph, last_compression, SLE_INT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 4, 5)),
|
||||
SLE_CONDVAR_X(LinkGraph, last_compression, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 6)),
|
||||
SLEG_VAR(_num_nodes, SLE_UINT16),
|
||||
SLE_VAR(LinkGraph, cargo, SLE_UINT8),
|
||||
static const NamedSaveLoad link_graph_desc[] = {
|
||||
NSL("last_compression", SLE_CONDVAR_X(LinkGraph, last_compression, SLE_VAR_I64 | SLE_FILE_I32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 0, 3))),
|
||||
NSL("last_compression", SLE_CONDVAR_X(LinkGraph, last_compression, SLE_INT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 4, 5))),
|
||||
NSL("last_compression", SLE_CONDVAR_X(LinkGraph, last_compression, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 6))),
|
||||
NSL("", SLEG_VAR(_num_nodes, SLE_UINT16)),
|
||||
NSL("cargo", SLE_VAR(LinkGraph, cargo, SLE_UINT8)),
|
||||
NSLT_STRUCTLIST<LinkGraphNodeStructHandler>("nodes"),
|
||||
};
|
||||
return link_graph_desc;
|
||||
}
|
||||
|
||||
struct LinkGraphJobStructHandler final : public TypedSaveLoadStructHandler<LinkGraphJobStructHandler, LinkGraphJob> {
|
||||
NamedSaveLoadTable GetDescription() const override
|
||||
{
|
||||
return GetLinkGraphDesc();
|
||||
}
|
||||
|
||||
void Save(LinkGraphJob *lgj) const override
|
||||
{
|
||||
SlObjectSaveFiltered(const_cast<LinkGraph *>(&lgj->Graph()), this->GetLoadDescription());
|
||||
}
|
||||
|
||||
void Load(LinkGraphJob *lgj) const override
|
||||
{
|
||||
SlObjectLoadFiltered(const_cast<LinkGraph *>(&lgj->Graph()), this->GetLoadDescription());
|
||||
}
|
||||
};
|
||||
|
||||
void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj)
|
||||
{
|
||||
lgj->join_tick *= DAY_TICKS;
|
||||
@ -63,9 +193,9 @@ void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj)
|
||||
* Of course the settings have to be saved and loaded, too, to avoid desyncs.
|
||||
* @return Array of SaveLoad structs.
|
||||
*/
|
||||
SaveLoadTable GetLinkGraphJobDesc()
|
||||
NamedSaveLoadTable GetLinkGraphJobDesc()
|
||||
{
|
||||
static std::vector<SaveLoad> saveloads;
|
||||
static std::vector<NamedSaveLoad> saveloads;
|
||||
|
||||
/* Build the SaveLoad array on first call and don't touch it later on */
|
||||
if (saveloads.size() == 0) {
|
||||
@ -80,17 +210,18 @@ SaveLoadTable GetLinkGraphJobDesc()
|
||||
address -= offset_gamesettings;
|
||||
address += offset_component;
|
||||
}
|
||||
saveloads.push_back(sl);
|
||||
saveloads.push_back(NSL(desc->name, sl));
|
||||
}
|
||||
|
||||
const SaveLoad job_desc[] = {
|
||||
SLE_CONDVAR_X(LinkGraphJob, join_tick, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 0, 4)),
|
||||
SLE_CONDVAR_X(LinkGraphJob, join_tick, SLE_FILE_I64 | SLE_VAR_U64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 5, 5)),
|
||||
SLE_CONDVAR_X(LinkGraphJob, join_tick, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 6)),
|
||||
SLE_CONDVAR_X(LinkGraphJob, start_tick, SLE_FILE_I32 | SLE_VAR_U64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 1, 4)),
|
||||
SLE_CONDVAR_X(LinkGraphJob, start_tick, SLE_FILE_I64 | SLE_VAR_U64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 5, 5)),
|
||||
SLE_CONDVAR_X(LinkGraphJob, start_tick, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 6)),
|
||||
SLE_VAR(LinkGraphJob, link_graph.index, SLE_UINT16),
|
||||
const NamedSaveLoad job_desc[] = {
|
||||
NSL("join_tick", SLE_CONDVAR_X(LinkGraphJob, join_tick, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 0, 4))),
|
||||
NSL("join_tick", SLE_CONDVAR_X(LinkGraphJob, join_tick, SLE_FILE_I64 | SLE_VAR_U64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 5, 5))),
|
||||
NSL("join_tick", SLE_CONDVAR_X(LinkGraphJob, join_tick, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 6))),
|
||||
NSL("start_tick", SLE_CONDVAR_X(LinkGraphJob, start_tick, SLE_FILE_I32 | SLE_VAR_U64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 1, 4))),
|
||||
NSL("start_tick", SLE_CONDVAR_X(LinkGraphJob, start_tick, SLE_FILE_I64 | SLE_VAR_U64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 5, 5))),
|
||||
NSL("start_tick", SLE_CONDVAR_X(LinkGraphJob, start_tick, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 6))),
|
||||
NSL("link_graph.index", SLE_VAR(LinkGraphJob, link_graph.index, SLE_UINT16)),
|
||||
NSLT_STRUCT<LinkGraphJobStructHandler>("linkgraph"),
|
||||
};
|
||||
|
||||
for (auto &sld : job_desc) {
|
||||
@ -105,91 +236,46 @@ SaveLoadTable GetLinkGraphJobDesc()
|
||||
* Get a SaveLoad array for the link graph schedule.
|
||||
* @return SaveLoad array for the link graph schedule.
|
||||
*/
|
||||
SaveLoadTable GetLinkGraphScheduleDesc()
|
||||
NamedSaveLoadTable GetLinkGraphScheduleDesc()
|
||||
{
|
||||
static const SaveLoad schedule_desc[] = {
|
||||
SLE_REFLIST(LinkGraphSchedule, schedule, REF_LINK_GRAPH),
|
||||
SLE_REFLIST(LinkGraphSchedule, running, REF_LINK_GRAPH_JOB),
|
||||
static const NamedSaveLoad schedule_desc[] = {
|
||||
NSL("schedule", SLE_REFLIST(LinkGraphSchedule, schedule, REF_LINK_GRAPH)),
|
||||
NSL("running", SLE_REFLIST(LinkGraphSchedule, running, REF_LINK_GRAPH_JOB)),
|
||||
};
|
||||
return schedule_desc;
|
||||
}
|
||||
|
||||
/* Edges and nodes are saved in the correct order, so we don't need to save their IDs. */
|
||||
struct LinkGraphNonTableHelper {
|
||||
std::vector<SaveLoad> node_desc;
|
||||
std::vector<SaveLoad> edge_desc;
|
||||
std::vector<SaveLoad> graph_desc;
|
||||
|
||||
/**
|
||||
* SaveLoad desc for a link graph node.
|
||||
*/
|
||||
static const SaveLoad _node_desc[] = {
|
||||
SLE_CONDVAR(Node, xy, SLE_UINT32, SLV_191, SL_MAX_VERSION),
|
||||
SLE_VAR(Node, supply, SLE_UINT32),
|
||||
SLE_VAR(Node, demand, SLE_UINT32),
|
||||
SLE_VAR(Node, station, SLE_UINT16),
|
||||
SLE_VAR(Node, last_update, SLE_INT32),
|
||||
};
|
||||
|
||||
/**
|
||||
* SaveLoad desc for a link graph edge.
|
||||
*/
|
||||
static const SaveLoad _edge_desc[] = {
|
||||
SLE_CONDNULL(4, SL_MIN_VERSION, SLV_191), // distance
|
||||
SLE_VAR(Edge, capacity, SLE_UINT32),
|
||||
SLE_VAR(Edge, usage, SLE_UINT32),
|
||||
SLE_CONDVAR_X(Edge, travel_time_sum, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_TRAVEL_TIME)),
|
||||
SLE_VAR(Edge, last_unrestricted_update, SLE_INT32),
|
||||
SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION),
|
||||
SLE_CONDVAR_X(Edge, last_aircraft_update, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_AIRCRAFT)),
|
||||
// SLE_VAR(Edge, next_edge, SLE_UINT16), // Removed since XSLFI_LINKGRAPH_SPARSE_EDGES
|
||||
};
|
||||
|
||||
std::vector<SaveLoad> _filtered_node_desc;
|
||||
std::vector<SaveLoad> _filtered_edge_desc;
|
||||
std::vector<SaveLoad> _filtered_job_desc;
|
||||
|
||||
static void FilterDescs()
|
||||
{
|
||||
_filtered_node_desc = SlFilterObject(_node_desc);
|
||||
_filtered_edge_desc = SlFilterObject(_edge_desc);
|
||||
_filtered_job_desc = SlFilterObject(GetLinkGraphJobDesc());
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a link graph.
|
||||
* @param lg Link graph to be saved or loaded.
|
||||
*/
|
||||
void Save_LinkGraph(LinkGraph &lg)
|
||||
{
|
||||
uint16_t size = lg.Size();
|
||||
auto edge_iter = lg.edges.begin();
|
||||
auto edge_end = lg.edges.end();
|
||||
for (NodeID from = 0; from < size; ++from) {
|
||||
Node *node = &lg.nodes[from];
|
||||
SlObjectSaveFiltered(node, _filtered_node_desc);
|
||||
|
||||
while (edge_iter != edge_end && edge_iter->first.first == from) {
|
||||
SlWriteUint16(edge_iter->first.second);
|
||||
Edge *edge = &edge_iter->second;
|
||||
SlObjectSaveFiltered(edge, _filtered_edge_desc);
|
||||
++edge_iter;
|
||||
}
|
||||
SlWriteUint16(INVALID_NODE);
|
||||
void Setup()
|
||||
{
|
||||
if (SlXvIsFeaturePresent(XSLFI_LINKGRAPH_SPARSE_EDGES, 2)) SlErrorCorrupt("XSLFI_LINKGRAPH_SPARSE_EDGES v2 should not be present for non-table chunks");
|
||||
this->node_desc = SlFilterNamedSaveLoadTable(_node_desc);
|
||||
this->edge_desc = SlFilterNamedSaveLoadTable(_edge_desc);
|
||||
this->graph_desc = SlFilterNamedSaveLoadTable(GetLinkGraphDesc());
|
||||
}
|
||||
}
|
||||
|
||||
void Load_LinkGraph(LinkGraph &lg);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load a link graph.
|
||||
* @param lg Link graph to be saved or loaded.
|
||||
*/
|
||||
void Load_LinkGraph(LinkGraph &lg)
|
||||
void LinkGraphNonTableHelper::Load_LinkGraph(LinkGraph &lg)
|
||||
{
|
||||
uint size = lg.Size();
|
||||
if (SlXvIsFeaturePresent(XSLFI_LINKGRAPH_SPARSE_EDGES)) {
|
||||
for (NodeID from = 0; from < size; ++from) {
|
||||
Node *node = &lg.nodes[from];
|
||||
SlObjectLoadFiltered(node, _filtered_node_desc);
|
||||
SlObjectLoadFiltered(node, this->node_desc);
|
||||
while (true) {
|
||||
NodeID to = SlReadUint16();
|
||||
if (to == INVALID_NODE) break;
|
||||
SlObjectLoadFiltered(&lg.edges[std::make_pair(from, to)], _filtered_edge_desc);
|
||||
SlObjectLoadFiltered(&lg.edges[std::make_pair(from, to)], this->edge_desc);
|
||||
}
|
||||
}
|
||||
} else if (IsSavegameVersionBefore(SLV_191)) {
|
||||
@ -199,10 +285,10 @@ void Load_LinkGraph(LinkGraph &lg)
|
||||
temp_next_edges.resize(size);
|
||||
for (NodeID from = 0; from < size; ++from) {
|
||||
Node *node = &lg.nodes[from];
|
||||
SlObjectLoadFiltered(node, _filtered_node_desc);
|
||||
SlObjectLoadFiltered(node, this->node_desc);
|
||||
/* We used to save the full matrix ... */
|
||||
for (NodeID to = 0; to < size; ++to) {
|
||||
SlObjectLoadFiltered(&temp_edges[to], _filtered_edge_desc);
|
||||
SlObjectLoadFiltered(&temp_edges[to], this->edge_desc);
|
||||
temp_next_edges[to] = SlReadUint16();
|
||||
}
|
||||
for (NodeID to = from; to != INVALID_NODE; to = temp_next_edges[to]) {
|
||||
@ -212,46 +298,28 @@ void Load_LinkGraph(LinkGraph &lg)
|
||||
} else {
|
||||
for (NodeID from = 0; from < size; ++from) {
|
||||
Node *node = &lg.nodes[from];
|
||||
SlObjectLoadFiltered(node, _filtered_node_desc);
|
||||
SlObjectLoadFiltered(node, this->node_desc);
|
||||
/* ... but as that wasted a lot of space we save a sparse matrix now. */
|
||||
for (NodeID to = from; to != INVALID_NODE;) {
|
||||
if (to >= size) SlErrorCorrupt("Link graph structure overflow");
|
||||
SlObjectLoadFiltered(&lg.edges[std::make_pair(from, to)], _filtered_edge_desc);
|
||||
SlObjectLoadFiltered(&lg.edges[std::make_pair(from, to)], this->edge_desc);
|
||||
to = SlReadUint16();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a link graph job.
|
||||
* @param lgj LinkGraphJob to be saved.
|
||||
*/
|
||||
static void DoSave_LGRJ(LinkGraphJob *lgj)
|
||||
{
|
||||
SlObjectSaveFiltered(lgj, _filtered_job_desc);
|
||||
_num_nodes = lgj->Size();
|
||||
SlObject(const_cast<LinkGraph *>(&lgj->Graph()), GetLinkGraphDesc());
|
||||
Save_LinkGraph(const_cast<LinkGraph &>(lgj->Graph()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a link graph.
|
||||
* @param lg LinkGraph to be saved.
|
||||
*/
|
||||
static void DoSave_LGRP(LinkGraph *lg)
|
||||
{
|
||||
_num_nodes = lg->Size();
|
||||
SlObject(lg, GetLinkGraphDesc());
|
||||
Save_LinkGraph(*lg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all link graphs.
|
||||
*/
|
||||
static void Load_LGRP()
|
||||
{
|
||||
FilterDescs();
|
||||
SaveLoadTableData slt = SlTableHeaderOrRiff(GetLinkGraphDesc());
|
||||
const bool is_table = SlIsTableChunk();
|
||||
|
||||
LinkGraphNonTableHelper helper;
|
||||
if (!is_table) helper.Setup();
|
||||
|
||||
int index;
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
if (!LinkGraph::CanAllocateItem()) {
|
||||
@ -259,9 +327,11 @@ static void Load_LGRP()
|
||||
NOT_REACHED();
|
||||
}
|
||||
LinkGraph *lg = new (index) LinkGraph();
|
||||
SlObject(lg, GetLinkGraphDesc());
|
||||
lg->Init(_num_nodes);
|
||||
Load_LinkGraph(*lg);
|
||||
SlObjectLoadFiltered(lg, slt);
|
||||
if (!is_table) {
|
||||
lg->Init(_num_nodes);
|
||||
helper.Load_LinkGraph(*lg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,7 +340,12 @@ static void Load_LGRP()
|
||||
*/
|
||||
static void Load_LGRJ()
|
||||
{
|
||||
FilterDescs();
|
||||
SaveLoadTableData slt = SlTableHeaderOrRiff(GetLinkGraphJobDesc());
|
||||
const bool is_table = SlIsTableChunk();
|
||||
|
||||
LinkGraphNonTableHelper helper;
|
||||
if (!is_table) helper.Setup();
|
||||
|
||||
int index;
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
if (!LinkGraphJob::CanAllocateItem()) {
|
||||
@ -278,26 +353,20 @@ static void Load_LGRJ()
|
||||
NOT_REACHED();
|
||||
}
|
||||
LinkGraphJob *lgj = new (index) LinkGraphJob();
|
||||
SlObjectLoadFiltered(lgj, _filtered_job_desc);
|
||||
SlObjectLoadFiltered(lgj, slt);
|
||||
if (SlXvIsFeatureMissing(XSLFI_LINKGRAPH_DAY_SCALE)) {
|
||||
extern void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj);
|
||||
GetLinkGraphJobDayLengthScaleAfterLoad(lgj);
|
||||
}
|
||||
LinkGraph &lg = const_cast<LinkGraph &>(lgj->Graph());
|
||||
SlObject(&lg, GetLinkGraphDesc());
|
||||
lg.Init(_num_nodes);
|
||||
Load_LinkGraph(lg);
|
||||
if (!is_table) {
|
||||
LinkGraph &lg = const_cast<LinkGraph &>(lgj->Graph());
|
||||
SlObjectLoadFiltered(&lg, helper.graph_desc);
|
||||
lg.Init(_num_nodes);
|
||||
helper.Load_LinkGraph(lg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the link graph schedule.
|
||||
*/
|
||||
static void Load_LGRS()
|
||||
{
|
||||
SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc());
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn the threads for running link graph calculations.
|
||||
* Has to be done after loading as the cargo classes might have changed.
|
||||
@ -333,10 +402,11 @@ void AfterLoadLinkGraphs()
|
||||
*/
|
||||
static void Save_LGRP()
|
||||
{
|
||||
FilterDescs();
|
||||
SaveLoadTableData slt = SlTableHeader(GetLinkGraphDesc());
|
||||
|
||||
for (LinkGraph *lg : LinkGraph::Iterate()) {
|
||||
SlSetArrayIndex(lg->index);
|
||||
SlAutolength(DoSave_LGRP, lg);
|
||||
SlObjectSaveFiltered(lg, slt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -345,19 +415,28 @@ static void Save_LGRP()
|
||||
*/
|
||||
static void Save_LGRJ()
|
||||
{
|
||||
FilterDescs();
|
||||
SaveLoadTableData slt = SlTableHeader(GetLinkGraphJobDesc());
|
||||
|
||||
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
|
||||
SlSetArrayIndex(lgj->index);
|
||||
SlAutolength(DoSave_LGRJ, lgj);
|
||||
SlObjectSaveFiltered(lgj, slt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the link graph schedule.
|
||||
*/
|
||||
static void Load_LGRS()
|
||||
{
|
||||
SlLoadTableOrRiffFiltered(GetLinkGraphScheduleDesc(), &LinkGraphSchedule::instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the link graph schedule.
|
||||
*/
|
||||
static void Save_LGRS()
|
||||
{
|
||||
SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc());
|
||||
SlSaveTableObjectChunk(GetLinkGraphScheduleDesc(), &LinkGraphSchedule::instance);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -365,13 +444,14 @@ static void Save_LGRS()
|
||||
*/
|
||||
static void Ptrs_LGRS()
|
||||
{
|
||||
SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc());
|
||||
SaveLoadTableData slt = SlPrepareNamedSaveLoadTableForPtrOrNull(GetLinkGraphScheduleDesc());
|
||||
SlObjectPtrOrNullFiltered(&LinkGraphSchedule::instance, slt);
|
||||
}
|
||||
|
||||
static const ChunkHandler linkgraph_chunk_handlers[] = {
|
||||
{ 'LGRP', Save_LGRP, Load_LGRP, nullptr, nullptr, CH_ARRAY },
|
||||
{ 'LGRJ', Save_LGRJ, Load_LGRJ, nullptr, nullptr, CH_ARRAY },
|
||||
{ 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, nullptr, CH_RIFF }
|
||||
{ 'LGRP', Save_LGRP, Load_LGRP, nullptr, nullptr, CH_TABLE },
|
||||
{ 'LGRJ', Save_LGRJ, Load_LGRJ, nullptr, nullptr, CH_TABLE },
|
||||
{ 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, nullptr, CH_TABLE }
|
||||
};
|
||||
|
||||
extern const ChunkHandlerTable _linkgraph_chunk_handlers(linkgraph_chunk_handlers);
|
||||
|
Loading…
Reference in New Issue
Block a user