OpenTTD Source: src/linkgraph/linkgraph.h Source File

OpenTTD Source 15.0-RC2

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
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
21class LinkGraph;
22
27 using LinkGraphPool = Pool<LinkGraph, LinkGraphID, 32>;
29extern LinkGraphPool _link_graph_pool;
30
37 class 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;
46 TimerGameEconomy::Date last_unrestricted_update{};
47 TimerGameEconomy::Date last_restricted_update{};
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
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 = 0;
92 uint demand = 0;
93 StationID station = StationID::Invalid();
94 TileIndex xy = INVALID_TILE;
95 TimerGameEconomy::Date last_update{};
96
97 std::vector<BaseEdge> edges;
98
99 BaseNode(TileIndex xy = INVALID_TILE, StationID st = StationID::Invalid(), uint demand = 0);
100
105 void UpdateSupply(uint supply)
106 {
107 this->supply += supply;
108 this->last_update = TimerGameEconomy::date;
109 }
110
115 void UpdateLocation(TileIndex xy)
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, EdgeUpdateModes modes);
130 void UpdateEdge(NodeID to, uint capacity, uint usage, uint32_t time, EdgeUpdateModes modes);
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 static inline 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() {}
197 LinkGraph(CargoType cargo) : cargo(cargo), last_compression(TimerGameEconomy::date) {}
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 CargoType 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
257protected:
258 friend SaveLoadTable GetLinkGraphDesc();
259 friend SaveLoadTable GetLinkGraphJobDesc();
260 friend class SlLinkgraphNode;
261 friend class SlLinkgraphEdge;
262 friend class LinkGraphJob;
263
264 CargoType cargo = INVALID_CARGO;
265 TimerGameEconomy::Date last_compression{};
266 NodeVector nodes{};
267};
268
269#endif /* LINKGRAPH_H */
CargoType
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:21
EnumBitSet
Enum-as-bit-set wrapper.
Definition enum_type.hpp:177
LinkGraphJob
Class for calculation jobs to be run on link graphs.
Definition linkgraphjob.h:29
LinkGraph
A connected component of a link graph.
Definition linkgraph.h:37
LinkGraph::operator[]
const BaseNode & operator[](NodeID num) const
Get a const reference to a node with the specified id.
Definition linkgraph.h:224
LinkGraph::Merge
void Merge(LinkGraph *other)
Merge a link graph with another one.
Definition linkgraph.cpp:90
LinkGraph::Init
void Init(uint size)
Resize the component and fill it with empty nodes and edges.
Definition linkgraph.cpp:251
LinkGraph::cargo
CargoType cargo
Cargo of this component's link graph.
Definition linkgraph.h:264
LinkGraph::Monthly
uint Monthly(uint base) const
Scale a value to its monthly equivalent, based on last compression.
Definition linkgraph.h:249
LinkGraph::nodes
NodeVector nodes
Nodes in the component.
Definition linkgraph.h:266
LinkGraph::GetLinkGraphDesc
friend SaveLoadTable GetLinkGraphDesc()
Get a SaveLoad array for a link graph.
Definition linkgraph_sl.cpp:136
LinkGraph::ShiftDates
void ShiftDates(TimerGameEconomy::Date interval)
Shift all dates by given interval.
Definition linkgraph.cpp:53
LinkGraph::LastCompression
TimerGameEconomy::Date LastCompression() const
Get date of last compression.
Definition linkgraph.h:236
LinkGraph::AddNode
NodeID AddNode(const Station *st)
Add a node to the component and create empty edges associated with it.
Definition linkgraph.cpp:149
LinkGraph::operator[]
BaseNode & operator[](NodeID num)
Get a node with the specified id.
Definition linkgraph.h:217
LinkGraph::Size
NodeID Size() const
Get the current size of the component.
Definition linkgraph.h:230
LinkGraph::Cargo
CargoType Cargo() const
Get the cargo type this component's link graph refers to.
Definition linkgraph.h:242
LinkGraph::MIN_TIMEOUT_DISTANCE
static const uint MIN_TIMEOUT_DISTANCE
Minimum effective distance for timeout calculation.
Definition linkgraph.h:170
LinkGraph::RemoveNode
void RemoveNode(NodeID id)
Remove a node from the link graph by overwriting it with the last node.
Definition linkgraph.cpp:116
LinkGraph::STALE_LINK_DEPOT_TIMEOUT
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
LinkGraph::COMPRESSION_INTERVAL
static constexpr TimerGameEconomy::Date COMPRESSION_INTERVAL
Minimum number of days between subsequent compressions of a LG.
Definition linkgraph.h:176
LinkGraph::Scale
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
LinkGraph::LinkGraph
LinkGraph(CargoType cargo)
Real constructor.
Definition linkgraph.h:197
LinkGraph::GetLinkGraphJobDesc
friend SaveLoadTable GetLinkGraphJobDesc()
Get a SaveLoad array for a link graph job.
Definition linkgraph_sl.cpp:180
LinkGraph::last_compression
TimerGameEconomy::Date last_compression
Last time the capacities and supplies were compressed.
Definition linkgraph.h:265
LinkGraph::LinkGraph
LinkGraph()
Bare constructor, only for save/load.
Definition linkgraph.h:192
SlLinkgraphEdge
Definition linkgraph_sl.cpp:31
SlLinkgraphNode
Definition linkgraph_sl.cpp:96
TimerGameConst< struct Economy >::INVALID_DATE
static constexpr TimerGame< struct Economy >::Date INVALID_DATE
Representation of an invalid date.
Definition timer_game_common.h:193
TimerGameEconomy
Timer that is increased every 27ms, and counts towards economy time units, expressed in days / months...
Definition timer_game_economy.h:32
TimerGameEconomy::date
static Date date
Current date in days (day counter).
Definition timer_game_economy.h:38
_link_graph_pool
LinkGraphPool _link_graph_pool
The actual pool with link graphs.
linkgraph_type.h
Declaration of link graph types used for cargo distribution.
SaveLoadTable
std::span< const struct SaveLoad > SaveLoadTable
A table of SaveLoad entries.
Definition saveload.h:530
LinkGraph::BaseEdge
An edge in the link graph.
Definition linkgraph.h:42
LinkGraph::BaseEdge::last_restricted_update
TimerGameEconomy::Date last_restricted_update
When the restricted part of the link was last updated.
Definition linkgraph.h:47
LinkGraph::BaseEdge::LastUpdate
TimerGameEconomy::Date LastUpdate() const
Get the date of the last update to any part of the edge's capacity.
Definition linkgraph.h:62
LinkGraph::BaseEdge::TravelTime
uint32_t TravelTime() const
Get edge's average travel time.
Definition linkgraph.h:56
LinkGraph::BaseEdge::travel_time_sum
uint64_t travel_time_sum
Sum of the travel times of the link, in ticks.
Definition linkgraph.h:45
LinkGraph::BaseEdge::dest_node
NodeID dest_node
Destination of the edge.
Definition linkgraph.h:48
LinkGraph::BaseEdge::usage
uint usage
Usage of the link.
Definition linkgraph.h:44
LinkGraph::BaseEdge::Update
void Update(uint capacity, uint usage, uint32_t time, EdgeUpdateModes modes)
Update an edge.
Definition linkgraph.cpp:217
LinkGraph::BaseEdge::last_unrestricted_update
TimerGameEconomy::Date last_unrestricted_update
When the unrestricted part of the link was last updated.
Definition linkgraph.h:46
LinkGraph::BaseEdge::capacity
uint capacity
Capacity of the link.
Definition linkgraph.h:43
LinkGraph::BaseNode
Node of the link graph.
Definition linkgraph.h:90
LinkGraph::BaseNode::station
StationID station
Station ID.
Definition linkgraph.h:93
LinkGraph::BaseNode::SetDemand
void SetDemand(uint demand)
Set the node's demand.
Definition linkgraph.h:124
LinkGraph::BaseNode::last_update
TimerGameEconomy::Date last_update
When the supply was last updated.
Definition linkgraph.h:95
LinkGraph::BaseNode::UpdateLocation
void UpdateLocation(TileIndex xy)
Update the node's location on the map.
Definition linkgraph.h:115
LinkGraph::BaseNode::edges
std::vector< BaseEdge > edges
Sorted list of outgoing edges from this node.
Definition linkgraph.h:97
LinkGraph::BaseNode::supply
uint supply
Supply at the station.
Definition linkgraph.h:91
LinkGraph::BaseNode::RemoveEdge
void RemoveEdge(NodeID to)
Remove an outgoing edge from this node.
Definition linkgraph.cpp:201
LinkGraph::BaseNode::AddEdge
void AddEdge(NodeID to, uint capacity, uint usage, uint32_t time, EdgeUpdateModes modes)
Fill an edge with values from a link.
Definition linkgraph.cpp:167
LinkGraph::BaseNode::xy
TileIndex xy
Location of the station referred to by the node.
Definition linkgraph.h:94
LinkGraph::BaseNode::demand
uint demand
Acceptance at the station.
Definition linkgraph.h:92
LinkGraph::BaseNode::UpdateEdge
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.
Definition linkgraph.cpp:186
LinkGraph::BaseNode::HasEdgeTo
bool HasEdgeTo(NodeID dest) const
Check if an edge to a destination is present.
Definition linkgraph.h:138
LinkGraph::BaseNode::UpdateSupply
void UpdateSupply(uint supply)
Update the node's supply and set last_update to the current date.
Definition linkgraph.h:105
PoolID< uint16_t, struct StationIDTag, 64000, 0xFFFF >
Pool::PoolItem
Base class for all PoolItems.
Definition pool_type.hpp:285
Pool
Base class for all pools.
Definition pool_type.hpp:133
Station
Station data structure.
Definition station_base.h:500
StrongType::Typedef
Templated helper to make a type-safe 'typedef' representing a single POD value.
Definition strong_typedef_type.hpp:130
INVALID_TILE
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95