OpenTTD
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 "../settings_internal.h"
15 #include "saveload.h"
16 
17 #include "../safeguards.h"
18 
21 
22 const SettingDesc *GetSettingDescription(uint index);
23 
24 static uint16 _num_nodes;
25 
31 {
32  static const SaveLoad link_graph_desc[] = {
33  SLE_VAR(LinkGraph, last_compression, SLE_INT32),
34  SLEG_VAR(_num_nodes, SLE_UINT16),
35  SLE_VAR(LinkGraph, cargo, SLE_UINT8),
36  SLE_END()
37  };
38  return link_graph_desc;
39 }
40 
51 {
52  static std::vector<SaveLoad> saveloads;
53  static const char *prefix = "linkgraph.";
54 
55  /* Build the SaveLoad array on first call and don't touch it later on */
56  if (saveloads.size() == 0) {
57  size_t offset_gamesettings = cpp_offsetof(GameSettings, linkgraph);
58  size_t offset_component = cpp_offsetof(LinkGraphJob, settings);
59 
60  size_t prefixlen = strlen(prefix);
61 
62  int setting = 0;
63  const SettingDesc *desc = GetSettingDescription(setting);
64  while (desc->save.cmd != SL_END) {
65  if (desc->desc.name != nullptr && strncmp(desc->desc.name, prefix, prefixlen) == 0) {
66  SaveLoad sl = desc->save;
67  char *&address = reinterpret_cast<char *&>(sl.address);
68  address -= offset_gamesettings;
69  address += offset_component;
70  saveloads.push_back(sl);
71  }
72  desc = GetSettingDescription(++setting);
73  }
74 
75  const SaveLoad job_desc[] = {
76  SLE_VAR(LinkGraphJob, join_date, SLE_INT32),
77  SLE_VAR(LinkGraphJob, link_graph.index, SLE_UINT16),
78  SLE_END()
79  };
80 
81  int i = 0;
82  do {
83  saveloads.push_back(job_desc[i++]);
84  } while (saveloads[saveloads.size() - 1].cmd != SL_END);
85  }
86 
87  return &saveloads[0];
88 }
89 
95 {
96  static const SaveLoad schedule_desc[] = {
99  SLE_END()
100  };
101  return schedule_desc;
102 }
103 
104 /* Edges and nodes are saved in the correct order, so we don't need to save their IDs. */
105 
109 static const SaveLoad _node_desc[] = {
110  SLE_CONDVAR(Node, xy, SLE_UINT32, SLV_191, SL_MAX_VERSION),
111  SLE_VAR(Node, supply, SLE_UINT32),
112  SLE_VAR(Node, demand, SLE_UINT32),
113  SLE_VAR(Node, station, SLE_UINT16),
114  SLE_VAR(Node, last_update, SLE_INT32),
115  SLE_END()
116 };
117 
121 static const SaveLoad _edge_desc[] = {
122  SLE_CONDNULL(4, SL_MIN_VERSION, SLV_191), // distance
123  SLE_VAR(Edge, capacity, SLE_UINT32),
124  SLE_VAR(Edge, usage, SLE_UINT32),
125  SLE_VAR(Edge, last_unrestricted_update, SLE_INT32),
126  SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION),
127  SLE_VAR(Edge, next_edge, SLE_UINT16),
128  SLE_END()
129 };
130 
136 {
137  uint size = lg.Size();
138  for (NodeID from = 0; from < size; ++from) {
139  Node *node = &lg.nodes[from];
140  SlObject(node, _node_desc);
142  /* We used to save the full matrix ... */
143  for (NodeID to = 0; to < size; ++to) {
144  SlObject(&lg.edges[from][to], _edge_desc);
145  }
146  } else {
147  /* ... but as that wasted a lot of space we save a sparse matrix now. */
148  for (NodeID to = from; to != INVALID_NODE; to = lg.edges[from][to].next_edge) {
149  SlObject(&lg.edges[from][to], _edge_desc);
150  }
151  }
152  }
153 }
154 
159 static void DoSave_LGRJ(LinkGraphJob *lgj)
160 {
162  _num_nodes = lgj->Size();
163  SlObject(const_cast<LinkGraph *>(&lgj->Graph()), GetLinkGraphDesc());
164  SaveLoad_LinkGraph(const_cast<LinkGraph &>(lgj->Graph()));
165 }
166 
171 static void DoSave_LGRP(LinkGraph *lg)
172 {
173  _num_nodes = lg->Size();
174  SlObject(lg, GetLinkGraphDesc());
175  SaveLoad_LinkGraph(*lg);
176 }
177 
181 static void Load_LGRP()
182 {
183  int index;
184  while ((index = SlIterateArray()) != -1) {
186  /* Impossible as they have been present in previous game. */
187  NOT_REACHED();
188  }
189  LinkGraph *lg = new (index) LinkGraph();
190  SlObject(lg, GetLinkGraphDesc());
191  lg->Init(_num_nodes);
192  SaveLoad_LinkGraph(*lg);
193  }
194 }
195 
199 static void Load_LGRJ()
200 {
201  int index;
202  while ((index = SlIterateArray()) != -1) {
204  /* Impossible as they have been present in previous game. */
205  NOT_REACHED();
206  }
207  LinkGraphJob *lgj = new (index) LinkGraphJob();
209  LinkGraph &lg = const_cast<LinkGraph &>(lgj->Graph());
210  SlObject(&lg, GetLinkGraphDesc());
211  lg.Init(_num_nodes);
212  SaveLoad_LinkGraph(lg);
213  }
214 }
215 
219 static void Load_LGRS()
220 {
222 }
223 
229 {
231  for (LinkGraph *lg : LinkGraph::Iterate()) {
232  for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) {
233  const Station *st = Station::GetIfValid((*lg)[node_id].Station());
234  if (st != nullptr) (*lg)[node_id].UpdateLocation(st->xy);
235  }
236  }
237 
238  for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
239  LinkGraph *lg = &(const_cast<LinkGraph &>(lgj->Graph()));
240  for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) {
241  const Station *st = Station::GetIfValid((*lg)[node_id].Station());
242  if (st != nullptr) (*lg)[node_id].UpdateLocation(st->xy);
243  }
244  }
245  }
246 
248 }
249 
253 static void Save_LGRP()
254 {
255  for (LinkGraph *lg : LinkGraph::Iterate()) {
256  SlSetArrayIndex(lg->index);
257  SlAutolength((AutolengthProc*)DoSave_LGRP, lg);
258  }
259 }
260 
264 static void Save_LGRJ()
265 {
266  for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
267  SlSetArrayIndex(lgj->index);
268  SlAutolength((AutolengthProc*)DoSave_LGRJ, lgj);
269  }
270 }
271 
275 static void Save_LGRS()
276 {
278 }
279 
283 static void Ptrs_LGRS()
284 {
286 }
287 
288 extern const ChunkHandler _linkgraph_chunk_handlers[] = {
289  { 'LGRP', Save_LGRP, Load_LGRP, nullptr, nullptr, CH_ARRAY },
290  { 'LGRJ', Save_LGRJ, Load_LGRJ, nullptr, nullptr, CH_ARRAY },
291  { 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, nullptr, CH_LAST }
292 };
#define SLE_CONDNULL(length, from, to)
Empty space in some savegame versions.
Definition: saveload.h:642
static void Load_LGRJ()
Load all link graph jobs.
const SaveLoad * GetLinkGraphDesc()
Get a SaveLoad array for a link graph.
static void DoSave_LGRJ(LinkGraphJob *lgj)
Save a link graph job.
static bool IsSavegameVersionBefore(SaveLoadVersion major, byte minor=0)
Checks whether the savegame is below major.
Definition: saveload.h:763
An edge in the link graph.
Definition: linkgraph.h:61
static void Ptrs_LGRS()
Substitute pointers in link graph schedule.
All settings together for the game.
void SpawnAll()
Start all threads in the running list.
#define SLE_LST(base, variable, type)
Storage of a list in every savegame version.
Definition: saveload.h:628
fluid_settings_t * settings
FluidSynth settings handle.
Definition: fluidsynth.cpp:20
Load/save a reference to a link graph job.
Definition: saveload.h:382
Tindex index
Index of this pool item.
Definition: pool_type.hpp:189
191 26636 FS#6026 Fix disaster vehicle storage (No bump) 191 26646 FS#6041 Linkgraph - store location...
Definition: saveload.h:271
void * address
address of variable OR offset of variable in the struct (max offset is 65536)
Definition: saveload.h:507
#define SLEG_VAR(variable, type)
Storage of a global variable in every savegame version.
Definition: saveload.h:716
const char * name
name of the setting. Used in configuration file and for console
static void Load_LGRS()
Load the link graph schedule.
A connected component of a link graph.
Definition: linkgraph.h:38
const SaveLoad * GetLinkGraphJobDesc()
Get a SaveLoad array for a link graph job.
SaveLoad save
Internal structure (going to savegame, parts to config)
uint Size() const
Get the current size of the component.
Definition: linkgraph.h:497
Functions/types related to saving and loading games.
#define SLE_CONDVAR(base, variable, type, from, to)
Storage of a variable in some savegame versions.
Definition: saveload.h:534
static const SaveLoad _node_desc[]
SaveLoad desc for a link graph node.
Updatable node class.
Definition: linkgraph.h:372
Highest possible saveload version.
Definition: saveload.h:305
static void Save_LGRP()
Save all link graphs.
static LinkGraphSchedule instance
Static instance of LinkGraphSchedule.
static const SaveLoad _edge_desc[]
SaveLoad desc for a link graph edge.
First savegame version.
Definition: saveload.h:30
static void Save_LGRJ()
Save all link graph jobs.
EdgeMatrix edges
Edges in the component.
Definition: linkgraph.h:534
const SaveLoad * GetLinkGraphScheduleDesc()
Get a SaveLoad array for the link graph schedule.
void AfterLoadLinkGraphs()
Spawn the threads for running link graph calculations.
An updatable edge class.
Definition: linkgraph.h:291
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition: saveload.cpp:637
Handlers and description of chunk.
Definition: saveload.h:356
#define SLE_END()
End marker of a struct/class save or load.
Definition: saveload.h:651
void Init(uint size)
Resize the component and fill it with empty nodes and edges.
Definition: linkgraph.cpp:281
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:340
static void Save_LGRS()
Save the link graph schedule.
Node of the link graph.
Definition: linkgraph.h:46
TileIndex xy
Base tile of the station.
SaveLoadType cmd
the action to take with the saved/loaded type, All types need different action
Definition: saveload.h:498
void SlObject(void *object, const SaveLoad *sld)
Main SaveLoad function.
Definition: saveload.cpp:1546
uint Size() const
Get the size of the underlying link graph.
Definition: linkgraphjob.h:310
const LinkGraph & Graph() const
Get a reference to the underlying link graph.
Definition: linkgraphjob.h:334
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() ...
Definition: pool_type.hpp:261
void SlAutolength(AutolengthProc *proc, void *arg)
Do something of which I have no idea what it is :P.
Definition: saveload.cpp:1574
SaveLoad type struct.
Definition: saveload.h:496
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
Definition: saveload.h:594
static void Load_LGRP()
Load all link graphs.
Load/save a reference to a link graph.
Definition: saveload.h:381
static void DoSave_LGRP(LinkGraph *lg)
Save a link graph.
187 25899 Linkgraph - restricted flows
Definition: saveload.h:266
NodeVector nodes
Nodes in the component.
Definition: linkgraph.h:533
SettingDescBase desc
Settings structure (going to configuration file)
Station data structure.
Definition: station_base.h:450
Class for calculation jobs to be run on link graphs.
Definition: linkgraphjob.h:29
Last chunk in this array.
Definition: saveload.h:391
void SaveLoad_LinkGraph(LinkGraph &lg)
Save/load a link graph.
static Station * GetIfValid(size_t index)
Returns station if the index is a valid index for this station type.