diff options
-rw-r--r-- | src/linkgraph/linkgraph.h | 3 | ||||
-rw-r--r-- | src/saveload/linkgraph_sl.cpp | 193 |
2 files changed, 106 insertions, 90 deletions
diff --git a/src/linkgraph/linkgraph.h b/src/linkgraph/linkgraph.h index 5eb85e4c3..a11b67a52 100644 --- a/src/linkgraph/linkgraph.h +++ b/src/linkgraph/linkgraph.h @@ -527,7 +527,8 @@ protected: friend class LinkGraph::Node; friend SaveLoadTable GetLinkGraphDesc(); friend SaveLoadTable GetLinkGraphJobDesc(); - friend void SaveLoad_LinkGraph(LinkGraph &lg); + friend class SlLinkgraphNode; + friend class SlLinkgraphEdge; CargoID cargo; ///< Cargo of this component's link graph. Date last_compression; ///< Last time the capacities and supplies were compressed. diff --git a/src/saveload/linkgraph_sl.cpp b/src/saveload/linkgraph_sl.cpp index 4fcc36e96..cf0292e6e 100644 --- a/src/saveload/linkgraph_sl.cpp +++ b/src/saveload/linkgraph_sl.cpp @@ -21,6 +21,79 @@ typedef LinkGraph::BaseNode Node; typedef LinkGraph::BaseEdge Edge; static uint16 _num_nodes; +static LinkGraph *_linkgraph; ///< Contains the current linkgraph being saved/loaded. +static NodeID _linkgraph_from; ///< Contains the current "from" node being saved/loaded. + +class SlLinkgraphEdge : public DefaultSaveLoadHandler<SlLinkgraphEdge, Node> { +public: + inline static const SaveLoad description[] = { + SLE_CONDNULL(4, SL_MIN_VERSION, SLV_191), // distance + SLE_VAR(Edge, capacity, SLE_UINT32), + SLE_VAR(Edge, usage, SLE_UINT32), + SLE_VAR(Edge, last_unrestricted_update, SLE_INT32), + SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION), + SLE_VAR(Edge, next_edge, SLE_UINT16), + }; + + void Save(Node *bn) const override + { + for (NodeID to = _linkgraph_from; to != INVALID_NODE; to = _linkgraph->edges[_linkgraph_from][to].next_edge) { + SlObject(&_linkgraph->edges[_linkgraph_from][to], this->GetDescription()); + } + } + + void Load(Node *bn) const override + { + uint16 max_size = _linkgraph->Size(); + + if (IsSavegameVersionBefore(SLV_191)) { + /* We used to save the full matrix ... */ + for (NodeID to = 0; to < max_size; ++to) { + SlObject(&_linkgraph->edges[_linkgraph_from][to], this->GetDescription()); + } + return; + } + + /* ... 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 (to >= max_size) SlErrorCorrupt("Link graph structure overflow"); + SlObject(&_linkgraph->edges[_linkgraph_from][to], this->GetDescription()); + } + } +}; + +class SlLinkgraphNode : public DefaultSaveLoadHandler<SlLinkgraphNode, LinkGraph> { +public: + inline static const SaveLoad description[] = { + 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), + SLEG_STRUCTLIST(SlLinkgraphEdge), + }; + + void Save(LinkGraph *lg) const override + { + _linkgraph = lg; + + for (NodeID from = 0; from < lg->Size(); ++from) { + _linkgraph_from = from; + SlObject(&lg->nodes[from], this->GetDescription()); + } + } + + void Load(LinkGraph *lg) const override + { + _linkgraph = lg; + + lg->Init(_num_nodes); + for (NodeID from = 0; from < _num_nodes; ++from) { + _linkgraph_from = from; + SlObject(&lg->nodes[from], this->GetDescription()); + } + } +}; /** * Get a SaveLoad array for a link graph. @@ -32,11 +105,35 @@ SaveLoadTable GetLinkGraphDesc() SLE_VAR(LinkGraph, last_compression, SLE_INT32), SLEG_VAR(_num_nodes, SLE_UINT16), SLE_VAR(LinkGraph, cargo, SLE_UINT8), + SLEG_STRUCTLIST(SlLinkgraphNode), }; return link_graph_desc; } /** + * Proxy to reuse LinkGraph to save/load a LinkGraphJob. + * One of the members of a LinkGraphJob is a LinkGraph, but SLEG_STRUCT() + * doesn't allow us to select a member. So instead, we add a bit of glue to + * accept a LinkGraphJob, get the LinkGraph, and use that to call the + * save/load routines for a regular LinkGraph. + */ +class SlLinkgraphJobProxy : public DefaultSaveLoadHandler<SlLinkgraphJobProxy, LinkGraphJob> { +public: + inline static const SaveLoad description[] = {{}}; // Needed to keep DefaultSaveLoadHandler happy. + SaveLoadTable GetDescription() const override { return GetLinkGraphDesc(); } + + void Save(LinkGraphJob *lgj) const override + { + SlObject(const_cast<LinkGraph *>(&lgj->Graph()), GetLinkGraphDesc()); + } + + void Load(LinkGraphJob *lgj) const override + { + SlObject(const_cast<LinkGraph *>(&lgj->Graph()), GetLinkGraphDesc()); + } +}; + +/** * Get a SaveLoad array for a link graph job. The settings struct is derived from * the global settings saveload array. The exact entries are calculated when the function * is called the first time. @@ -53,6 +150,7 @@ SaveLoadTable GetLinkGraphJobDesc() static const SaveLoad job_desc[] = { SLE_VAR(LinkGraphJob, join_date, SLE_INT32), SLE_VAR(LinkGraphJob, link_graph.index, SLE_UINT16), + SLEG_STRUCT(SlLinkgraphJobProxy), }; /* The member offset arithmetic below is only valid if the types in question @@ -93,56 +191,6 @@ SaveLoadTable GetLinkGraphScheduleDesc() return schedule_desc; } -/* Edges and nodes are saved in the correct order, so we don't need to save their IDs. */ - -/** - * 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_VAR(Edge, last_unrestricted_update, SLE_INT32), - SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION), - SLE_VAR(Edge, next_edge, SLE_UINT16), -}; - -/** - * Save/load a link graph. - * @param lg Link graph to be saved or loaded. - */ -void SaveLoad_LinkGraph(LinkGraph &lg) -{ - uint16 size = lg.Size(); - for (NodeID from = 0; from < size; ++from) { - Node *node = &lg.nodes[from]; - SlObject(node, _node_desc); - if (IsSavegameVersionBefore(SLV_191)) { - /* We used to save the full matrix ... */ - for (NodeID to = 0; to < size; ++to) { - SlObject(&lg.edges[from][to], _edge_desc); - } - } else { - /* ... but as that wasted a lot of space we save a sparse matrix now. */ - for (NodeID to = from; to != INVALID_NODE; to = lg.edges[from][to].next_edge) { - if (to >= size) SlErrorCorrupt("Link graph structure overflow"); - SlObject(&lg.edges[from][to], _edge_desc); - } - } - } -} - /** * Spawn the threads for running link graph calculations. * Has to be done after loading as the cargo classes might have changed. @@ -174,24 +222,15 @@ void AfterLoadLinkGraphs() } /** - * Save a link graph. - * @param lg LinkGraph to be saved. - */ -static void DoSave_LGRP(LinkGraph *lg) -{ - _num_nodes = lg->Size(); - SlObject(lg, GetLinkGraphDesc()); - SaveLoad_LinkGraph(*lg); -} - -/** * Save all link graphs. */ static void Save_LGRP() { for (LinkGraph *lg : LinkGraph::Iterate()) { + _num_nodes = lg->Size(); + SlSetArrayIndex(lg->index); - SlAutolength((AutolengthProc*)DoSave_LGRP, lg); + SlObject(lg, GetLinkGraphDesc()); } } @@ -202,37 +241,21 @@ static void Load_LGRP() { int index; while ((index = SlIterateArray()) != -1) { - if (!LinkGraph::CanAllocateItem()) { - /* Impossible as they have been present in previous game. */ - NOT_REACHED(); - } LinkGraph *lg = new (index) LinkGraph(); SlObject(lg, GetLinkGraphDesc()); - lg->Init(_num_nodes); - SaveLoad_LinkGraph(*lg); } } /** - * Save a link graph job. - * @param lgj LinkGraphJob to be saved. - */ -static void DoSave_LGRJ(LinkGraphJob *lgj) -{ - SlObject(lgj, GetLinkGraphJobDesc()); - _num_nodes = lgj->Size(); - SlObject(const_cast<LinkGraph *>(&lgj->Graph()), GetLinkGraphDesc()); - SaveLoad_LinkGraph(const_cast<LinkGraph &>(lgj->Graph())); -} - -/** * Save all link graph jobs. */ static void Save_LGRJ() { for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) { + _num_nodes = lgj->Size(); + SlSetArrayIndex(lgj->index); - SlAutolength((AutolengthProc*)DoSave_LGRJ, lgj); + SlObject(lgj, GetLinkGraphJobDesc()); } } @@ -243,16 +266,8 @@ static void Load_LGRJ() { int index; while ((index = SlIterateArray()) != -1) { - if (!LinkGraphJob::CanAllocateItem()) { - /* Impossible as they have been present in previous game. */ - NOT_REACHED(); - } LinkGraphJob *lgj = new (index) LinkGraphJob(); SlObject(lgj, GetLinkGraphJobDesc()); - LinkGraph &lg = const_cast<LinkGraph &>(lgj->Graph()); - SlObject(&lg, GetLinkGraphDesc()); - lg.Init(_num_nodes); - SaveLoad_LinkGraph(lg); } } |