OpenTTD Source 20260721-master-g25ec12c62d
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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#ifndef LINKGRAPH_H
11#define LINKGRAPH_H
12
13#include "../core/pool_type.hpp"
14#include "../station_base.h"
15#include "../cargotype.h"
18#include "linkgraph_type.h"
19#include <utility>
20
21class LinkGraph;
22
29extern LinkGraphPool _link_graph_pool;
30
37class LinkGraph : public LinkGraphPool::PoolItem<&_link_graph_pool> {
38public:
42 struct BaseEdge {
43 uint capacity = 0;
44 uint usage = 0;
45 uint64_t travel_time_sum = 0;
48 NodeID dest_node = INVALID_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, EdgeUpdateModes modes);
65 void Restrict() { this->last_unrestricted_update = EconomyTime::INVALID_DATE; }
66 void Release() { this->last_restricted_update = EconomyTime::INVALID_DATE; }
67
73 bool operator <(const BaseEdge &rhs) const
74 {
75 return this->dest_node < rhs.dest_node;
76 }
77
78 bool operator <(NodeID rhs) const
79 {
80 return this->dest_node < rhs;
81 }
82
83 friend inline bool operator <(NodeID lhs, const LinkGraph::BaseEdge &rhs)
84 {
85 return lhs < rhs.dest_node;
86 }
87 };
88
94 struct BaseNode {
95 uint supply = 0;
96 uint demand = 0;
97 StationID station = StationID::Invalid();
100
101 std::vector<BaseEdge> edges;
102
103 BaseNode(TileIndex xy = INVALID_TILE, StationID st = StationID::Invalid(), uint demand = 0);
104
110 {
111 this->supply += supply;
112 this->last_update = TimerGameEconomy::date;
113 }
114
120 {
121 this->xy = xy;
122 }
123
128 void SetDemand(uint demand)
129 {
130 this->demand = demand;
131 }
132
133 void AddEdge(NodeID to, uint capacity, uint usage, uint32_t time, EdgeUpdateModes modes);
134 void UpdateEdge(NodeID to, uint capacity, uint usage, uint32_t time, EdgeUpdateModes modes);
135 void RemoveEdge(NodeID to);
136
142 bool HasEdgeTo(NodeID dest) const
143 {
144 return std::binary_search(this->edges.begin(), this->edges.end(), dest);
145 }
146
147 BaseEdge &operator[](NodeID to)
148 {
149 assert(this->HasEdgeTo(to));
150 return *GetEdge(to);
151 }
152
153 const BaseEdge &operator[](NodeID to) const
154 {
155 assert(this->HasEdgeTo(to));
156 return *GetEdge(to);
157 }
158
159 private:
160 std::vector<BaseEdge>::iterator GetEdge(NodeID dest)
161 {
162 return std::lower_bound(this->edges.begin(), this->edges.end(), dest);
163 }
164
165 std::vector<BaseEdge>::const_iterator GetEdge(NodeID dest) const
166 {
167 return std::lower_bound(this->edges.begin(), this->edges.end(), dest);
168 }
169 };
170
171 typedef std::vector<BaseNode> NodeVector;
172
174 static const uint MIN_TIMEOUT_DISTANCE = 32;
175
178
181
190 static inline uint Scale(uint val, TimerGameEconomy::Date target_age, TimerGameEconomy::Date orig_age)
191 {
192 return val > 0 ? std::max(1U, val * target_age.base() / orig_age.base()) : 0;
193 }
194
202
203 void Init(uint size);
204 void ShiftDates(TimerGameEconomy::Date interval);
205 void Compress();
206 void Merge(LinkGraph *other);
207
208 /* Splitting link graphs is intentionally not implemented.
209 * The overhead in determining connectedness would probably outweigh the
210 * benefit of having to deal with smaller graphs. In real world examples
211 * networks generally grow. Only rarely a network is permanently split.
212 * Reacting to temporary splits here would obviously create performance
213 * problems and detecting the temporary or permanent nature of splits isn't
214 * trivial. */
215
221 inline BaseNode &operator[](NodeID num) { return this->nodes[num]; }
222
228 inline const BaseNode &operator[](NodeID num) const { return this->nodes[num]; }
229
234 inline NodeID Size() const { return (NodeID)this->nodes.size(); }
235
241
246 inline CargoType Cargo() const { return this->cargo; }
247
253 inline uint Monthly(uint base) const
254 {
255 return base * 30 / (TimerGameEconomy::date - this->last_compression + 1).base();
256 }
257
258 NodeID AddNode(const Station *st);
259 void RemoveNode(NodeID id);
260
261protected:
264 friend class SlLinkgraphNode;
265 friend class SlLinkgraphEdge;
266 friend class LinkGraphJob;
267
268 CargoType cargo = INVALID_CARGO;
270 NodeVector nodes{};
271};
272
273#endif /* LINKGRAPH_H */
CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:22
Types/functions related to cargoes.
Class for calculation jobs to be run on link graphs.
A connected component of a link graph.
Definition linkgraph.h:37
const BaseNode & operator[](NodeID num) const
Get a const reference to a node with the specified id.
Definition linkgraph.h:228
void Merge(LinkGraph *other)
Merge a link graph with another one.
Definition linkgraph.cpp:91
void Init(uint size)
Resize the component and fill it with empty nodes and edges.
CargoType cargo
Cargo of this component's link graph.
Definition linkgraph.h:268
uint Monthly(uint base) const
Scale a value to its monthly equivalent, based on last compression.
Definition linkgraph.h:253
NodeVector nodes
Nodes in the component.
Definition linkgraph.h:270
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:54
TimerGameEconomy::Date LastCompression() const
Get date of last compression.
Definition linkgraph.h:240
NodeID AddNode(const Station *st)
Add a node to the component and create empty edges associated with it.
BaseNode & operator[](NodeID num)
Get a node with the specified id.
Definition linkgraph.h:221
NodeID Size() const
Get the current size of the component.
Definition linkgraph.h:234
CargoType Cargo() const
Get the cargo type this component's link graph refers to.
Definition linkgraph.h:246
static const uint MIN_TIMEOUT_DISTANCE
Minimum effective distance for timeout calculation.
Definition linkgraph.h:174
void RemoveNode(NodeID id)
Remove a node from the link graph by overwriting it with the last node.
static constexpr TimerGameEconomy::Date STALE_LINK_DEPOT_TIMEOUT
Number of days before deleting links served only by vehicles stopped in depot.
Definition linkgraph.h:177
static constexpr TimerGameEconomy::Date COMPRESSION_INTERVAL
Minimum number of days between subsequent compressions of a LG.
Definition linkgraph.h:180
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:190
LinkGraph(LinkGraphID index, CargoType cargo=INVALID_CARGO)
Real constructor.
Definition linkgraph.h:200
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:269
static constexpr TimerGame< struct Economy >::Date 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).
StrongType::Typedef< int32_t, DateTag< struct Economy >, StrongType::Compare, StrongType::Integer > Date
LinkGraphPool _link_graph_pool
The actual pool with link graphs.
Pool< LinkGraph, LinkGraphID, 32 > LinkGraphPool
Type of the pool for link graph components.
Definition linkgraph.h:27
Declaration of link graph types used for cargo distribution.
EnumBitSet< EdgeUpdateMode, uint8_t > EdgeUpdateModes
Bitset of EdgeUpdateMode elements.
Label< struct NodeIDTag > NodeID
Label type of the nodes in the AllowedSubtags.
Definition of Pool, structure used to access PoolItems, and PoolItem, base structure for Vehicle,...
Types often used outside the saveload code related to saving and loading games.
std::span< const struct SaveLoad > SaveLoadTable
A table of SaveLoad entries.
Base classes/functions for stations.
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:73
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
void Update(uint capacity, uint usage, uint32_t time, EdgeUpdateModes modes)
Update an edge.
BaseEdge(NodeID dest_node=INVALID_NODE)
Create an edge.
Definition linkgraph.cpp:39
TimerGameEconomy::Date last_unrestricted_update
When the unrestricted part of the link was last updated.
Definition linkgraph.h:46
uint capacity
Capacity of the link.
Definition linkgraph.h:43
Node of the link graph.
Definition linkgraph.h:94
StationID station
Station ID.
Definition linkgraph.h:97
void SetDemand(uint demand)
Set the node's demand.
Definition linkgraph.h:128
TimerGameEconomy::Date last_update
When the supply was last updated.
Definition linkgraph.h:99
BaseNode(TileIndex xy=INVALID_TILE, StationID st=StationID::Invalid(), uint demand=0)
Create a node or clear it.
Definition linkgraph.cpp:26
void UpdateLocation(TileIndex xy)
Update the node's location on the map.
Definition linkgraph.h:119
std::vector< BaseEdge > edges
Sorted list of outgoing edges from this node.
Definition linkgraph.h:101
uint supply
Supply at the station.
Definition linkgraph.h:95
void RemoveEdge(NodeID to)
Remove an outgoing edge from this node.
void AddEdge(NodeID to, uint capacity, uint usage, uint32_t time, EdgeUpdateModes modes)
Fill an edge with values from a link.
TileIndex xy
Location of the station referred to by the node.
Definition linkgraph.h:98
uint demand
Acceptance at the station.
Definition linkgraph.h:96
void UpdateEdge(NodeID to, uint capacity, uint usage, uint32_t time, EdgeUpdateModes modes)
Creates an edge if none exists yet or updates an existing edge.
bool HasEdgeTo(NodeID dest) const
Check if an edge to a destination is present.
Definition linkgraph.h:142
void UpdateSupply(uint supply)
Update the node's supply and set last_update to the current date.
Definition linkgraph.h:109
Base class for all pools.
Station data structure.
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:100
Definition of the game-economy-timer.