OpenTTD Source: src/saveload/linkgraph_sl.cpp Source File

OpenTTD Source 1.11.0-RC1

linkgraph_sl.cpp
Go to the documentation of this file.
1 /*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10 #include "../stdafx.h"
11 #include "../linkgraph/linkgraph.h"
12 #include "../linkgraph/linkgraphjob.h"
13 #include "../linkgraph/linkgraphschedule.h"
14 #include "../network/network.h"
15 #include "../settings_internal.h"
16 #include "saveload.h"
17
18 #include "../safeguards.h"
19
20 typedef LinkGraph::BaseNode Node;
21 typedef LinkGraph::BaseEdge Edge;
22
23 const SettingDesc *GetSettingDescription(uint index);
24
25 static uint16 _num_nodes;
26
31 const SaveLoad *GetLinkGraphDesc()
32 {
33 static const SaveLoad link_graph_desc[] = {
34 SLE_VAR(LinkGraph, last_compression, SLE_INT32),
35 SLEG_VAR(_num_nodes, SLE_UINT16),
36 SLE_VAR(LinkGraph, cargo, SLE_UINT8),
37 SLE_END()
38 };
39 return link_graph_desc;
40 }
41
51 const SaveLoad *GetLinkGraphJobDesc()
52 {
53 static std::vector<SaveLoad> saveloads;
54 static const char *prefix = "linkgraph.";
55
56 static const SaveLoad job_desc[] = {
57 SLE_VAR(LinkGraphJob, join_date, SLE_INT32),
58 SLE_VAR(LinkGraphJob, link_graph.index, SLE_UINT16),
59 SLE_END()
60 };
61
62 /* The member offset arithmetic below is only valid if the types in question
63 * are standard layout types. Otherwise, it would be undefined behaviour. */
64 static_assert(std::is_standard_layout<LinkGraphSettings>::value, "LinkGraphSettings needs to be a standard layout type");
65
66 /* We store the offset of each member of the #LinkGraphSettings in the
67 * extra data of the saveload struct. Use it together with the address
68 * of the settings struct inside the job to find the final memory address. */
69 static SaveLoadAddrProc * const proc = [](void *b, size_t extra) -> void * { return const_cast<void *>(static_cast<const void *>(reinterpret_cast<const char *>(std::addressof(static_cast<LinkGraphJob *>(b)->settings)) + extra)); };
70
71 /* Build the SaveLoad array on first call and don't touch it later on */
72 if (saveloads.size() == 0) {
73 size_t prefixlen = strlen(prefix);
74
75 int setting = 0;
76 const SettingDesc *desc = GetSettingDescription(setting);
77 while (desc->save.cmd != SL_END) {
78 if (desc->desc.name != nullptr && strncmp(desc->desc.name, prefix, prefixlen) == 0) {
79 SaveLoad sl = desc->save;
80 sl.address_proc = proc;
81 saveloads.push_back(sl);
82 }
83 desc = GetSettingDescription(++setting);
84 }
85
86 int i = 0;
87 do {
88 saveloads.push_back(job_desc[i++]);
89 } while (saveloads[saveloads.size() - 1].cmd != SL_END);
90 }
91
92 return &saveloads[0];
93 }
94
99 const SaveLoad *GetLinkGraphScheduleDesc()
100 {
101 static const SaveLoad schedule_desc[] = {
102 SLE_LST(LinkGraphSchedule, schedule, REF_LINK_GRAPH),
103 SLE_LST(LinkGraphSchedule, running, REF_LINK_GRAPH_JOB),
104 SLE_END()
105 };
106 return schedule_desc;
107 }
108
109 /* Edges and nodes are saved in the correct order, so we don't need to save their IDs. */
110
114 static const SaveLoad _node_desc[] = {
115 SLE_CONDVAR(Node, xy, SLE_UINT32, SLV_191, SL_MAX_VERSION),
116 SLE_VAR(Node, supply, SLE_UINT32),
117 SLE_VAR(Node, demand, SLE_UINT32),
118 SLE_VAR(Node, station, SLE_UINT16),
119 SLE_VAR(Node, last_update, SLE_INT32),
120 SLE_END()
121 };
122
126 static const SaveLoad _edge_desc[] = {
127 SLE_CONDNULL(4, SL_MIN_VERSION, SLV_191), // distance
128 SLE_VAR(Edge, capacity, SLE_UINT32),
129 SLE_VAR(Edge, usage, SLE_UINT32),
130 SLE_VAR(Edge, last_unrestricted_update, SLE_INT32),
131 SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION),
132 SLE_VAR(Edge, next_edge, SLE_UINT16),
133 SLE_END()
134 };
135
140 void SaveLoad_LinkGraph(LinkGraph &lg)
141 {
142 uint size = lg.Size();
143 for (NodeID from = 0; from < size; ++from) {
144 Node *node = &lg.nodes[from];
145 SlObject(node, _node_desc);
146 if (IsSavegameVersionBefore(SLV_191)) {
147 /* We used to save the full matrix ... */
148 for (NodeID to = 0; to < size; ++to) {
149 SlObject(&lg.edges[from][to], _edge_desc);
150 }
151 } else {
152 /* ... but as that wasted a lot of space we save a sparse matrix now. */
153 for (NodeID to = from; to != INVALID_NODE; to = lg.edges[from][to].next_edge) {
154 SlObject(&lg.edges[from][to], _edge_desc);
155 }
156 }
157 }
158 }
159
164 static void DoSave_LGRJ(LinkGraphJob *lgj)
165 {
166 SlObject(lgj, GetLinkGraphJobDesc());
167 _num_nodes = lgj->Size();
168 SlObject(const_cast<LinkGraph *>(&lgj->Graph()), GetLinkGraphDesc());
169 SaveLoad_LinkGraph(const_cast<LinkGraph &>(lgj->Graph()));
170 }
171
176 static void DoSave_LGRP(LinkGraph *lg)
177 {
178 _num_nodes = lg->Size();
179 SlObject(lg, GetLinkGraphDesc());
180 SaveLoad_LinkGraph(*lg);
181 }
182
186 static void Load_LGRP()
187 {
188 int index;
189 while ((index = SlIterateArray()) != -1) {
190 if (!LinkGraph::CanAllocateItem()) {
191 /* Impossible as they have been present in previous game. */
192 NOT_REACHED();
193 }
194 LinkGraph *lg = new (index) LinkGraph();
195 SlObject(lg, GetLinkGraphDesc());
196 lg->Init(_num_nodes);
197 SaveLoad_LinkGraph(*lg);
198 }
199 }
200
204 static void Load_LGRJ()
205 {
206 int index;
207 while ((index = SlIterateArray()) != -1) {
208 if (!LinkGraphJob::CanAllocateItem()) {
209 /* Impossible as they have been present in previous game. */
210 NOT_REACHED();
211 }
212 LinkGraphJob *lgj = new (index) LinkGraphJob();
213 SlObject(lgj, GetLinkGraphJobDesc());
214 LinkGraph &lg = const_cast<LinkGraph &>(lgj->Graph());
215 SlObject(&lg, GetLinkGraphDesc());
216 lg.Init(_num_nodes);
217 SaveLoad_LinkGraph(lg);
218 }
219 }
220
224 static void Load_LGRS()
225 {
226 SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc());
227 }
228
233 void AfterLoadLinkGraphs()
234 {
235 if (IsSavegameVersionBefore(SLV_191)) {
236 for (LinkGraph *lg : LinkGraph::Iterate()) {
237 for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) {
238 const Station *st = Station::GetIfValid((*lg)[node_id].Station());
239 if (st != nullptr) (*lg)[node_id].UpdateLocation(st->xy);
240 }
241 }
242
243 for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
244 LinkGraph *lg = &(const_cast<LinkGraph &>(lgj->Graph()));
245 for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) {
246 const Station *st = Station::GetIfValid((*lg)[node_id].Station());
247 if (st != nullptr) (*lg)[node_id].UpdateLocation(st->xy);
248 }
249 }
250 }
251
252 LinkGraphSchedule::instance.SpawnAll();
253
254 if (!_networking || _network_server) {
255 AfterLoad_LinkGraphPauseControl();
256 }
257 }
258
262 static void Save_LGRP()
263 {
264 for (LinkGraph *lg : LinkGraph::Iterate()) {
265 SlSetArrayIndex(lg->index);
266 SlAutolength((AutolengthProc*)DoSave_LGRP, lg);
267 }
268 }
269
273 static void Save_LGRJ()
274 {
275 for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
276 SlSetArrayIndex(lgj->index);
277 SlAutolength((AutolengthProc*)DoSave_LGRJ, lgj);
278 }
279 }
280
284 static void Save_LGRS()
285 {
286 SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc());
287 }
288
292 static void Ptrs_LGRS()
293 {
294 SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc());
295 }
296
297 extern const ChunkHandler _linkgraph_chunk_handlers[] = {
298 { 'LGRP', Save_LGRP, Load_LGRP, nullptr, nullptr, CH_ARRAY },
299 { 'LGRJ', Save_LGRJ, Load_LGRJ, nullptr, nullptr, CH_ARRAY },
300 { 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, nullptr, CH_LAST }
301 };
SLV_187
@ SLV_187
187 25899 Linkgraph - restricted flows
Definition: saveload.h:267
Save_LGRS
static void Save_LGRS()
Save the link graph schedule.
Definition: linkgraph_sl.cpp:284
LinkGraph::edges
EdgeMatrix edges
Edges in the component.
Definition: linkgraph.h:535
LinkGraph
A connected component of a link graph.
Definition: linkgraph.h:39
LinkGraph::Node
Updatable node class.
Definition: linkgraph.h:373
SL_MIN_VERSION
@ SL_MIN_VERSION
First savegame version.
Definition: saveload.h:31
Load_LGRS
static void Load_LGRS()
Load the link graph schedule.
Definition: linkgraph_sl.cpp:224
LinkGraph::nodes
NodeVector nodes
Nodes in the component.
Definition: linkgraph.h:534
Station
Station data structure.
Definition: station_base.h:450
LinkGraphJob
Class for calculation jobs to be run on link graphs.
Definition: linkgraphjob.h:30
_network_server
bool _network_server
network-server is active
Definition: network.cpp:53
LinkGraphSchedule
Definition: linkgraphschedule.h:36
SettingDesc::save
SaveLoad save
Internal structure (going to savegame, parts to config)
Definition: settings_internal.h:111
LinkGraphSchedule::instance
static LinkGraphSchedule instance
Static instance of LinkGraphSchedule.
Definition: linkgraphschedule.h:52
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition: pool_type.hpp:227
SLE_CONDVAR
#define SLE_CONDVAR(base, variable, type, from, to)
Storage of a variable in some savegame versions.
Definition: saveload.h:551
CH_LAST
@ CH_LAST
Last chunk in this array.
Definition: saveload.h:410
SaveLoad_LinkGraph
void SaveLoad_LinkGraph(LinkGraph &lg)
Save/load a link graph.
Definition: linkgraph_sl.cpp:140
saveload.h
AfterLoad_LinkGraphPauseControl
void AfterLoad_LinkGraphPauseControl()
Pause the game on load if we would do a join with the next link graph job, but it is still running,...
Definition: linkgraphschedule.cpp:193
Load_LGRJ
static void Load_LGRJ()
Load all link graph jobs.
Definition: linkgraph_sl.cpp:204
LinkGraphSchedule::SpawnAll
void SpawnAll()
Start all threads in the running list.
Definition: linkgraphschedule.cpp:110
ChunkHandler
Handlers and description of chunk.
Definition: saveload.h:379
LinkGraph::Init
void Init(uint size)
Resize the component and fill it with empty nodes and edges.
Definition: linkgraph.cpp:280
SLE_CONDNULL
#define SLE_CONDNULL(length, from, to)
Empty space in some savegame versions.
Definition: saveload.h:677
LinkGraph::Edge
An updatable edge class.
Definition: linkgraph.h:292
LinkGraphJob::Graph
const LinkGraph & Graph() const
Get a reference to the underlying link graph.
Definition: linkgraphjob.h:359
GetLinkGraphJobDesc
const SaveLoad * GetLinkGraphJobDesc()
Get a SaveLoad array for a link graph job.
Definition: linkgraph_sl.cpp:51
Save_LGRJ
static void Save_LGRJ()
Save all link graph jobs.
Definition: linkgraph_sl.cpp:273
SLE_END
#define SLE_END()
End marker of a struct/class save or load.
Definition: saveload.h:686
LinkGraph::BaseEdge
An edge in the link graph.
Definition: linkgraph.h:62
SaveLoad::cmd
SaveLoadType cmd
the action to take with the saved/loaded type, All types need different action
Definition: saveload.h:517
LinkGraph::Size
uint Size() const
Get the current size of the component.
Definition: linkgraph.h:498
settings
fluid_settings_t * settings
FluidSynth settings handle.
Definition: fluidsynth.cpp:21
IsSavegameVersionBefore
static bool IsSavegameVersionBefore(SaveLoadVersion major, byte minor=0)
Checks whether the savegame is below major.
Definition: saveload.h:815
_networking
bool _networking
are we in networking mode?
Definition: network.cpp:52
SLE_LST
#define SLE_LST(base, variable, type)
Storage of a list in every savegame version.
Definition: saveload.h:663
SlObject
void SlObject(void *object, const SaveLoad *sld)
Main SaveLoad function.
Definition: saveload.cpp:1612
Save_LGRP
static void Save_LGRP()
Save all link graphs.
Definition: linkgraph_sl.cpp:262
SlAutolength
void SlAutolength(AutolengthProc *proc, void *arg)
Do something of which I have no idea what it is :P.
Definition: saveload.cpp:1640
GetLinkGraphScheduleDesc
const SaveLoad * GetLinkGraphScheduleDesc()
Get a SaveLoad array for the link graph schedule.
Definition: linkgraph_sl.cpp:99
SL_MAX_VERSION
@ SL_MAX_VERSION
Highest possible saveload version.
Definition: saveload.h:328
REF_LINK_GRAPH_JOB
@ REF_LINK_GRAPH_JOB
Load/save a reference to a link graph job.
Definition: saveload.h:401
SLEG_VAR
#define SLEG_VAR(variable, type)
Storage of a global variable in every savegame version.
Definition: saveload.h:761
LinkGraphJob::Size
uint Size() const
Get the size of the underlying link graph.
Definition: linkgraphjob.h:335
SLE_VAR
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
Definition: saveload.h:621
_edge_desc
static const SaveLoad _edge_desc[]
SaveLoad desc for a link graph edge.
Definition: linkgraph_sl.cpp:126
Pool::PoolItem<&_link_graph_pool >::Iterate
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:378
SettingDesc
Definition: settings_internal.h:109
AfterLoadLinkGraphs
void AfterLoadLinkGraphs()
Spawn the threads for running link graph calculations.
Definition: linkgraph_sl.cpp:233
_node_desc
static const SaveLoad _node_desc[]
SaveLoad desc for a link graph node.
Definition: linkgraph_sl.cpp:114
Pool::PoolItem<&_link_graph_pool >::CanAllocateItem
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
Definition: pool_type.hpp:299
SettingDesc::desc
SettingDescBase desc
Settings structure (going to configuration file)
Definition: settings_internal.h:110
BaseStation::xy
TileIndex xy
Base tile of the station.
Definition: base_station_base.h:53
Ptrs_LGRS
static void Ptrs_LGRS()
Substitute pointers in link graph schedule.
Definition: linkgraph_sl.cpp:292
REF_LINK_GRAPH
@ REF_LINK_GRAPH
Load/save a reference to a link graph.
Definition: saveload.h:400
DoSave_LGRJ
static void DoSave_LGRJ(LinkGraphJob *lgj)
Save a link graph job.
Definition: linkgraph_sl.cpp:164
SpecializedStation< Station, false >::GetIfValid
static Station * GetIfValid(size_t index)
Returns station if the index is a valid index for this station type.
Definition: base_station_base.h:228
SettingDescBase::name
const char * name
name of the setting. Used in configuration file and for console
Definition: settings_internal.h:92
SLV_191
@ SLV_191
191 26636 FS#6026 Fix disaster vehicle storage (No bump) 191 26646 FS#6041 Linkgraph - store location...
Definition: saveload.h:272
DoSave_LGRP
static void DoSave_LGRP(LinkGraph *lg)
Save a link graph.
Definition: linkgraph_sl.cpp:176
SaveLoad::address_proc
SaveLoadAddrProc * address_proc
callback proc the get the actual variable address in memory
Definition: saveload.h:523
LinkGraph::BaseNode
Node of the link graph.
Definition: linkgraph.h:47
GetLinkGraphDesc
const SaveLoad * GetLinkGraphDesc()
Get a SaveLoad array for a link graph.
Definition: linkgraph_sl.cpp:31
SaveLoad
SaveLoad type struct.
Definition: saveload.h:516
Load_LGRP
static void Load_LGRP()
Load all link graphs.
Definition: linkgraph_sl.cpp:186
SlIterateArray
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition: saveload.cpp:631