OpenTTD Source  20241120-master-g6d3adc6169
linkgraph.h
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 #ifndef LINKGRAPH_H
11 #define LINKGRAPH_H
12 
13 #include "../core/pool_type.hpp"
14 #include "../station_base.h"
15 #include "../cargotype.h"
16 #include "../timer/timer_game_economy.h"
17 #include "../saveload/saveload.h"
18 #include "linkgraph_type.h"
19 #include <utility>
20 
21 class LinkGraph;
22 
30 
37 class LinkGraph : public LinkGraphPool::PoolItem<&_link_graph_pool> {
38 public:
42  struct BaseEdge {
43  uint capacity;
44  uint usage;
45  uint64_t travel_time_sum;
48  NodeID dest_node;
49 
50  BaseEdge(NodeID dest_node = INVALID_NODE);
51 
56  uint32_t TravelTime() const { return this->travel_time_sum / this->capacity; }
57 
62  TimerGameEconomy::Date LastUpdate() const { return std::max(this->last_unrestricted_update, this->last_restricted_update); }
63 
64  void Update(uint capacity, uint usage, uint32_t time, EdgeUpdateMode mode);
65  void Restrict() { this->last_unrestricted_update = EconomyTime::INVALID_DATE; }
66  void Release() { this->last_restricted_update = EconomyTime::INVALID_DATE; }
67 
69  bool operator <(const BaseEdge &rhs) const
70  {
71  return this->dest_node < rhs.dest_node;
72  }
73 
74  bool operator <(NodeID rhs) const
75  {
76  return this->dest_node < rhs;
77  }
78 
79  friend inline bool operator <(NodeID lhs, const LinkGraph::BaseEdge &rhs)
80  {
81  return lhs < rhs.dest_node;
82  }
83  };
84 
90  struct BaseNode {
91  uint supply;
92  uint demand;
93  StationID station;
96 
97  std::vector<BaseEdge> edges;
98 
99  BaseNode(TileIndex xy = INVALID_TILE, StationID st = INVALID_STATION, uint demand = 0);
100 
105  void UpdateSupply(uint supply)
106  {
107  this->supply += supply;
108  this->last_update = TimerGameEconomy::date;
109  }
110 
116  {
117  this->xy = xy;
118  }
119 
124  void SetDemand(uint demand)
125  {
126  this->demand = demand;
127  }
128 
129  void AddEdge(NodeID to, uint capacity, uint usage, uint32_t time, EdgeUpdateMode mode);
130  void UpdateEdge(NodeID to, uint capacity, uint usage, uint32_t time, EdgeUpdateMode mode);
131  void RemoveEdge(NodeID to);
132 
138  bool HasEdgeTo(NodeID dest) const
139  {
140  return std::binary_search(this->edges.begin(), this->edges.end(), dest);
141  }
142 
143  BaseEdge &operator[](NodeID to)
144  {
145  assert(this->HasEdgeTo(to));
146  return *GetEdge(to);
147  }
148 
149  const BaseEdge &operator[](NodeID to) const
150  {
151  assert(this->HasEdgeTo(to));
152  return *GetEdge(to);
153  }
154 
155  private:
156  std::vector<BaseEdge>::iterator GetEdge(NodeID dest)
157  {
158  return std::lower_bound(this->edges.begin(), this->edges.end(), dest);
159  }
160 
161  std::vector<BaseEdge>::const_iterator GetEdge(NodeID dest) const
162  {
163  return std::lower_bound(this->edges.begin(), this->edges.end(), dest);
164  }
165  };
166 
167  typedef std::vector<BaseNode> NodeVector;
168 
170  static const uint MIN_TIMEOUT_DISTANCE = 32;
171 
173  static constexpr TimerGameEconomy::Date STALE_LINK_DEPOT_TIMEOUT = 1024;
174 
176  static constexpr TimerGameEconomy::Date COMPRESSION_INTERVAL = 256;
177 
186  inline static uint Scale(uint val, TimerGameEconomy::Date target_age, TimerGameEconomy::Date orig_age)
187  {
188  return val > 0 ? std::max(1U, val * target_age.base() / orig_age.base()) : 0;
189  }
190 
192  LinkGraph() : cargo(INVALID_CARGO), last_compression(0) {}
198 
199  void Init(uint size);
200  void ShiftDates(TimerGameEconomy::Date interval);
201  void Compress();
202  void Merge(LinkGraph *other);
203 
204  /* Splitting link graphs is intentionally not implemented.
205  * The overhead in determining connectedness would probably outweigh the
206  * benefit of having to deal with smaller graphs. In real world examples
207  * networks generally grow. Only rarely a network is permanently split.
208  * Reacting to temporary splits here would obviously create performance
209  * problems and detecting the temporary or permanent nature of splits isn't
210  * trivial. */
211 
217  inline BaseNode &operator[](NodeID num) { return this->nodes[num]; }
218 
224  inline const BaseNode &operator[](NodeID num) const { return this->nodes[num]; }
225 
230  inline NodeID Size() const { return (NodeID)this->nodes.size(); }
231 
236  inline TimerGameEconomy::Date LastCompression() const { return this->last_compression; }
237 
242  inline CargoID Cargo() const { return this->cargo; }
243 
249  inline uint Monthly(uint base) const
250  {
251  return base * 30 / (TimerGameEconomy::date - this->last_compression + 1).base();
252  }
253 
254  NodeID AddNode(const Station *st);
255  void RemoveNode(NodeID id);
256 
257 protected:
260  friend class SlLinkgraphNode;
261  friend class SlLinkgraphEdge;
262  friend class LinkGraphJob;
263 
265  TimerGameEconomy::Date last_compression;
266  NodeVector nodes;
267 };
268 
269 #endif /* LINKGRAPH_H */
uint8_t CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:22
Class for calculation jobs to be run on link graphs.
Definition: linkgraphjob.h:29
A connected component of a link graph.
Definition: linkgraph.h:37
LinkGraph(CargoID cargo)
Real constructor.
Definition: linkgraph.h:197
const BaseNode & operator[](NodeID num) const
Get a const reference to a node with the specified id.
Definition: linkgraph.h:224
void Merge(LinkGraph *other)
Merge a link graph with another one.
Definition: linkgraph.cpp:90
void Init(uint size)
Resize the component and fill it with empty nodes and edges.
Definition: linkgraph.cpp:251
CargoID cargo
Cargo of this component's link graph.
Definition: linkgraph.h:264
uint Monthly(uint base) const
Scale a value to its monthly equivalent, based on last compression.
Definition: linkgraph.h:249
NodeVector nodes
Nodes in the component.
Definition: linkgraph.h:266
friend SaveLoadTable GetLinkGraphDesc()
Get a SaveLoad array for a link graph.
void ShiftDates(TimerGameEconomy::Date interval)
Shift all dates by given interval.
Definition: linkgraph.cpp:53
TimerGameEconomy::Date LastCompression() const
Get date of last compression.
Definition: linkgraph.h:236
NodeID AddNode(const Station *st)
Add a node to the component and create empty edges associated with it.
Definition: linkgraph.cpp:149
NodeID Size() const
Get the current size of the component.
Definition: linkgraph.h:230
static const uint MIN_TIMEOUT_DISTANCE
Minimum effective distance for timeout calculation.
Definition: linkgraph.h:170
void RemoveNode(NodeID id)
Remove a node from the link graph by overwriting it with the last node.
Definition: linkgraph.cpp:116
BaseNode & operator[](NodeID num)
Get a node with the specified id.
Definition: linkgraph.h:217
static constexpr TimerGameEconomy::Date STALE_LINK_DEPOT_TIMEOUT
Number of days before deleting links served only by vehicles stopped in depot.
Definition: linkgraph.h:173
static constexpr TimerGameEconomy::Date COMPRESSION_INTERVAL
Minimum number of days between subsequent compressions of a LG.
Definition: linkgraph.h:176
static uint Scale(uint val, TimerGameEconomy::Date target_age, TimerGameEconomy::Date orig_age)
Scale a value from a link graph of age orig_age for usage in one of age target_age.
Definition: linkgraph.h:186
CargoID Cargo() const
Get the cargo ID this component's link graph refers to.
Definition: linkgraph.h:242
friend SaveLoadTable GetLinkGraphJobDesc()
Get a SaveLoad array for a link graph job.
TimerGameEconomy::Date last_compression
Last time the capacities and supplies were compressed.
Definition: linkgraph.h:265
LinkGraph()
Bare constructor, only for save/load.
Definition: linkgraph.h:192
static constexpr TimerGame< struct Economy >::Date INVALID_DATE
Representation of an invalid date.
Timer that is increased every 27ms, and counts towards economy time units, expressed in days / months...
static Date date
Current date in days (day counter).
Pool< LinkGraph, LinkGraphID, 32, 0xFFFF > LinkGraphPool
Type of the pool for link graph components.
Definition: linkgraph.h:21
LinkGraphPool _link_graph_pool
The actual pool with link graphs.
Declaration of link graph types used for cargo distribution.
EdgeUpdateMode
Special modes for updating links.
std::span< const struct SaveLoad > SaveLoadTable
A table of SaveLoad entries.
Definition: saveload.h:513
An edge in the link graph.
Definition: linkgraph.h:42
TimerGameEconomy::Date last_restricted_update
When the restricted part of the link was last updated.
Definition: linkgraph.h:47
TimerGameEconomy::Date LastUpdate() const
Get the date of the last update to any part of the edge's capacity.
Definition: linkgraph.h:62
bool operator<(const BaseEdge &rhs) const
Comparison operator based on dest_node.
Definition: linkgraph.h:69
uint32_t TravelTime() const
Get edge's average travel time.
Definition: linkgraph.h:56
uint64_t travel_time_sum
Sum of the travel times of the link, in ticks.
Definition: linkgraph.h:45
NodeID dest_node
Destination of the edge.
Definition: linkgraph.h:48
uint usage
Usage of the link.
Definition: linkgraph.h:44
BaseEdge(NodeID dest_node=INVALID_NODE)
Create an edge.
Definition: linkgraph.cpp:38
TimerGameEconomy::Date last_unrestricted_update
When the unrestricted part of the link was last updated.
Definition: linkgraph.h:46
void Update(uint capacity, uint usage, uint32_t time, EdgeUpdateMode mode)
Update an edge.
Definition: linkgraph.cpp:217
uint capacity
Capacity of the link.
Definition: linkgraph.h:43
Node of the link graph.
Definition: linkgraph.h:90
StationID station
Station ID.
Definition: linkgraph.h:93
void SetDemand(uint demand)
Set the node's demand.
Definition: linkgraph.h:124
TimerGameEconomy::Date last_update
When the supply was last updated.
Definition: linkgraph.h:95
void AddEdge(NodeID to, uint capacity, uint usage, uint32_t time, EdgeUpdateMode mode)
Fill an edge with values from a link.
Definition: linkgraph.cpp:167
void UpdateLocation(TileIndex xy)
Update the node's location on the map.
Definition: linkgraph.h:115
std::vector< BaseEdge > edges
Sorted list of outgoing edges from this node.
Definition: linkgraph.h:97
void UpdateEdge(NodeID to, uint capacity, uint usage, uint32_t time, EdgeUpdateMode mode)
Creates an edge if none exists yet or updates an existing edge.
Definition: linkgraph.cpp:186
uint supply
Supply at the station.
Definition: linkgraph.h:91
void RemoveEdge(NodeID to)
Remove an outgoing edge from this node.
Definition: linkgraph.cpp:201
TileIndex xy
Location of the station referred to by the node.
Definition: linkgraph.h:94
uint demand
Acceptance at the station.
Definition: linkgraph.h:92
BaseNode(TileIndex xy=INVALID_TILE, StationID st=INVALID_STATION, uint demand=0)
Create a node or clear it.
Definition: linkgraph.cpp:26
bool HasEdgeTo(NodeID dest) const
Check if an edge to a destination is present.
Definition: linkgraph.h:138
void UpdateSupply(uint supply)
Update the node's supply and set last_update to the current date.
Definition: linkgraph.h:105
Base class for all PoolItems.
Definition: pool_type.hpp:237
Base class for all pools.
Definition: pool_type.hpp:80
Station data structure.
Definition: station_base.h:439
Templated helper to make a type-safe 'typedef' representing a single POD value.
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:95