diff --git a/src/linkgraph/linkgraph.cpp b/src/linkgraph/linkgraph.cpp index 1230204542..c84c62b7e6 100644 --- a/src/linkgraph/linkgraph.cpp +++ b/src/linkgraph/linkgraph.cpp @@ -164,12 +164,11 @@ NodeID LinkGraph::AddNode(const Station *st) * @param usage Usage to be added. * @param mode Update mode to be used. */ -void LinkGraph::Node::AddEdge(NodeID to, uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode) +void LinkGraph::BaseNode::AddEdge(NodeID to, uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode) { - assert(this->index != to); assert(!this->HasEdgeTo(to)); - BaseEdge &edge = *this->node.edges.emplace(std::upper_bound(this->node.edges.begin(), this->node.edges.end(), to), to); + BaseEdge &edge = *this->edges.emplace(std::upper_bound(this->edges.begin(), this->edges.end(), to), to); edge.capacity = capacity; edge.usage = usage; edge.travel_time_sum = static_cast(travel_time) * capacity; @@ -184,14 +183,14 @@ void LinkGraph::Node::AddEdge(NodeID to, uint capacity, uint usage, uint32 trave * @param usage Usage to be added. * @param mode Update mode to be used. */ -void LinkGraph::Node::UpdateEdge(NodeID to, uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode) +void LinkGraph::BaseNode::UpdateEdge(NodeID to, uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode) { assert(capacity > 0); assert(usage <= capacity); if (!this->HasEdgeTo(to)) { this->AddEdge(to, capacity, usage, travel_time, mode); } else { - (*this)[to].Update(capacity, usage, travel_time, mode); + this->GetEdge(to)->Update(capacity, usage, travel_time, mode); } } @@ -199,10 +198,10 @@ void LinkGraph::Node::UpdateEdge(NodeID to, uint capacity, uint usage, uint32 tr * Remove an outgoing edge from this node. * @param to ID of destination node. */ -void LinkGraph::Node::RemoveEdge(NodeID to) +void LinkGraph::BaseNode::RemoveEdge(NodeID to) { - auto [first, last] = std::equal_range(this->node.edges.begin(), this->node.edges.end(), to); - this->node.edges.erase(first, last); + auto [first, last] = std::equal_range(this->edges.begin(), this->edges.end(), to); + this->edges.erase(first, last); } /** @@ -215,33 +214,33 @@ void LinkGraph::Node::RemoveEdge(NodeID to) * @param travel_time Travel time to be added, in ticks. * @param mode Update mode to be applied. */ -void LinkGraph::Edge::Update(uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode) +void LinkGraph::BaseEdge::Update(uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode) { - assert(this->edge.capacity > 0); + assert(this->capacity > 0); assert(capacity >= usage); if (mode & EUM_INCREASE) { - if (this->edge.travel_time_sum == 0) { - this->edge.travel_time_sum = static_cast(this->edge.capacity + capacity) * travel_time; + if (this->travel_time_sum == 0) { + this->travel_time_sum = static_cast(this->capacity + capacity) * travel_time; } else if (travel_time == 0) { - this->edge.travel_time_sum += this->edge.travel_time_sum / this->edge.capacity * capacity; + this->travel_time_sum += this->travel_time_sum / this->capacity * capacity; } else { - this->edge.travel_time_sum += static_cast(travel_time) * capacity; + this->travel_time_sum += static_cast(travel_time) * capacity; } - this->edge.capacity += capacity; - this->edge.usage += usage; + this->capacity += capacity; + this->usage += usage; } else if (mode & EUM_REFRESH) { - if (this->edge.travel_time_sum == 0) { - this->edge.capacity = std::max(this->edge.capacity, capacity); - this->edge.travel_time_sum = static_cast(travel_time) * this->edge.capacity; - } else if (capacity > this->edge.capacity) { - this->edge.travel_time_sum = this->edge.travel_time_sum / this->edge.capacity * capacity; - this->edge.capacity = capacity; + if (this->travel_time_sum == 0) { + this->capacity = std::max(this->capacity, capacity); + this->travel_time_sum = static_cast(travel_time) * this->capacity; + } else if (capacity > this->capacity) { + this->travel_time_sum = this->travel_time_sum / this->capacity * capacity; + this->capacity = capacity; } - this->edge.usage = std::max(this->edge.usage, usage); + this->usage = std::max(this->usage, usage); } - if (mode & EUM_UNRESTRICTED) this->edge.last_unrestricted_update = _date; - if (mode & EUM_RESTRICTED) this->edge.last_restricted_update = _date; + if (mode & EUM_UNRESTRICTED) this->last_unrestricted_update = _date; + if (mode & EUM_RESTRICTED) this->last_restricted_update = _date; } /** diff --git a/src/linkgraph/linkgraph.h b/src/linkgraph/linkgraph.h index cd9c176930..d9f8f9d9a7 100644 --- a/src/linkgraph/linkgraph.h +++ b/src/linkgraph/linkgraph.h @@ -56,6 +56,16 @@ public: */ uint32 TravelTime() const { return this->travel_time_sum / this->capacity; } + /** + * Get the date of the last update to any part of the edge's capacity. + * @return Last update. + */ + Date LastUpdate() const { return std::max(this->last_unrestricted_update, this->last_restricted_update); } + + void Update(uint capacity, uint usage, uint32 time, EdgeUpdateMode mode); + void Restrict() { this->last_unrestricted_update = INVALID_DATE; } + void Release() { this->last_restricted_update = INVALID_DATE; } + /** Comparison operator based on \c dest_node. */ bool operator <(const BaseEdge &rhs) const { @@ -88,357 +98,6 @@ public: std::vector edges; ///< Sorted list of outgoing edges from this node. BaseNode(TileIndex xy = INVALID_TILE, StationID st = INVALID_STATION, uint demand = 0); - }; - - /** - * Wrapper for an edge (const or not) allowing retrieval, but no modification. - * @tparam Tedge Actual edge class, may be "const BaseEdge" or just "BaseEdge". - */ - template - class EdgeWrapper { - protected: - Tedge &edge; ///< Actual edge to be used. - - public: - - /** - * Wrap a an edge. - * @param edge Edge to be wrapped. - */ - EdgeWrapper (Tedge &edge) : edge(edge) {} - - /** - * Get edge's capacity. - * @return Capacity. - */ - uint Capacity() const { return this->edge.capacity; } - - /** - * Get edge's usage. - * @return Usage. - */ - uint Usage() const { return this->edge.usage; } - - /** - * Get edge's average travel time. - * @return Travel time, in ticks. - */ - uint32 TravelTime() const { return this->edge.TravelTime(); } - - /** - * Get the date of the last update to the edge's unrestricted capacity. - * @return Last update. - */ - Date LastUnrestrictedUpdate() const { return this->edge.last_unrestricted_update; } - - /** - * Get the date of the last update to the edge's restricted capacity. - * @return Last update. - */ - Date LastRestrictedUpdate() const { return this->edge.last_restricted_update; } - - /** - * Get the date of the last update to any part of the edge's capacity. - * @return Last update. - */ - Date LastUpdate() const { return std::max(this->edge.last_unrestricted_update, this->edge.last_restricted_update); } - }; - - /** - * Wrapper for a node (const or not) allowing retrieval, but no modification. - * @tparam Tnode Actual node class, may be "const BaseNode" or just "BaseNode". - */ - template - class NodeWrapper { - protected: - Tnode &node; ///< Node being wrapped. - NodeID index; ///< ID of wrapped node. - - auto GetEdge(NodeID dest) const - { - return std::lower_bound(this->node.edges.begin(), this->node.edges.end(), dest); - } - public: - - /** - * Wrap a node. - * @param node Node to be wrapped. - * @param index ID of node to be wrapped. - */ - NodeWrapper(Tnode &node, NodeID index) : node(node), index(index) {} - - /** - * Get supply of wrapped node. - * @return Supply. - */ - uint Supply() const { return this->node.supply; } - - /** - * Get demand of wrapped node. - * @return Demand. - */ - uint Demand() const { return this->node.demand; } - - /** - * Get ID of station belonging to wrapped node. - * @return ID of node's station. - */ - StationID Station() const { return this->node.station; } - - /** - * Get node's last update. - * @return Last update. - */ - Date LastUpdate() const { return this->node.last_update; } - - /** - * Get the location of the station associated with the node. - * @return Location of the station. - */ - TileIndex XY() const { return this->node.xy; } - - /** - * Check if an edge to a destination is present. - * @param dest Wanted edge destination. - * @return True if an edge is present. - */ - bool HasEdgeTo(NodeID dest) const - { - return std::binary_search(this->node.edges.begin(), this->node.edges.end(), dest); - } - }; - - /** - * Base class for iterating across outgoing edges of a node. Only the real - * edges (those with capacity) are iterated. The ones with only distance - * information are skipped. - * @tparam Tedge Actual edge class. May be "BaseEdge" or "const BaseEdge". - * @tparam Titer Actual iterator class. - */ - template - class BaseEdgeIterator { - protected: - span base; ///< Array of edges being iterated. - size_t current; ///< Current offset in edges array. - - /** - * A "fake" pointer to enable operator-> on temporaries. As the objects - * returned from operator* aren't references but real objects, we have - * to return something that implements operator->, but isn't a pointer - * from operator->. A fake pointer. - */ - class FakePointer : public std::pair { - public: - - /** - * Construct a fake pointer from a pair of NodeID and edge. - * @param pair Pair to be "pointed" to (in fact shallow-copied). - */ - FakePointer(const std::pair &pair) : std::pair(pair) {} - - /** - * Retrieve the pair by operator->. - * @return Pair being "pointed" to. - */ - std::pair *operator->() { return this; } - }; - - public: - /** - * Constructor. - * @param base Array of edges to be iterated. - * @param end Make the iterator the end sentinel? - */ - BaseEdgeIterator(span base, bool end) : base(base), current(end ? base.size() : 0) {} - - /** - * Prefix-increment. - * @return This. - */ - Titer &operator++() - { - if (this->current < this->base.size()) this->current++; - return static_cast(*this); - } - - /** - * Postfix-increment. - * @return Version of this before increment. - */ - Titer operator++(int) - { - Titer ret(static_cast(*this)); - ++(*this); - return ret; - } - - /** - * Compare with some other edge iterator. The other one may be of a - * child class. - * @tparam Tother Class of other iterator. - * @param other Instance of other iterator. - * @return If the iterators have the same edge array and current node. - */ - template - bool operator==(const Tother &other) - { - return this->base.data() == other.base.data() && this->current == other.current; - } - - /** - * Compare for inequality with some other edge iterator. The other one - * may be of a child class. - * @tparam Tother Class of other iterator. - * @param other Instance of other iterator. - * @return If either the edge arrays or the current nodes differ. - */ - template - bool operator!=(const Tother &other) - { - return this->base.data() != other.base.data() || this->current != other.current; - } - - /** - * Dereference with operator*. - * @return Pair of current target NodeID and edge object. - */ - std::pair operator*() const - { - return std::pair(this->base[this->current].dest_node, Tedge_wrapper(this->base[this->current])); - } - - /** - * Dereference with operator->. - * @return Fake pointer to Pair of current target NodeID and edge object. - */ - FakePointer operator->() const { - return FakePointer(this->operator*()); - } - }; - - /** - * A constant edge class. - */ - typedef EdgeWrapper ConstEdge; - - /** - * An updatable edge class. - */ - class Edge : public EdgeWrapper { - public: - /** - * Constructor - * @param edge Edge to be wrapped. - */ - Edge(BaseEdge &edge) : EdgeWrapper(edge) {} - void Update(uint capacity, uint usage, uint32 time, EdgeUpdateMode mode); - void Restrict() { this->edge.last_unrestricted_update = INVALID_DATE; } - void Release() { this->edge.last_restricted_update = INVALID_DATE; } - }; - - /** - * An iterator for const edges. Cannot be typedef'ed because of - * template-reference to ConstEdgeIterator itself. - */ - class ConstEdgeIterator : public BaseEdgeIterator { - public: - /** - * Constructor. - * @param edges Array of edges to be iterated over. - * @param end Make the iterator the end sentinel? - */ - ConstEdgeIterator(span edges, bool end) : - BaseEdgeIterator(edges, end) {} - }; - - /** - * An iterator for non-const edges. Cannot be typedef'ed because of - * template-reference to EdgeIterator itself. - */ - class EdgeIterator : public BaseEdgeIterator { - public: - /** - * Constructor. - * @param edges Array of edges to be iterated over. - * @param end Make the iterator the end sentinel? - */ - EdgeIterator(span edges, bool end) : - BaseEdgeIterator(edges, end) {} - }; - - /** - * Constant node class. Only retrieval operations are allowed on both the - * node itself and its edges. - */ - class ConstNode : public NodeWrapper { - public: - /** - * Constructor. - * @param lg LinkGraph to get the node from. - * @param node ID of the node. - */ - ConstNode(const LinkGraph *lg, NodeID node) : NodeWrapper(lg->nodes[node], node) {} - - /** - * Get a ConstEdge. This is not a reference as the wrapper objects are - * not actually persistent. - * @param to ID of end node of edge. - * @return Constant edge wrapper. - */ - ConstEdge operator[](NodeID to) const - { - assert(this->HasEdgeTo(to)); - return ConstEdge(*this->GetEdge(to)); - } - - /** - * Get an iterator pointing to the start of the edges array. - * @return Constant edge iterator. - */ - ConstEdgeIterator Begin() const { return ConstEdgeIterator(this->node.edges, false); } - - /** - * Get an iterator pointing beyond the end of the edges array. - * @return Constant edge iterator. - */ - ConstEdgeIterator End() const { return ConstEdgeIterator(this->node.edges, true); } - }; - - /** - * Updatable node class. The node itself as well as its edges can be modified. - */ - class Node : public NodeWrapper { - public: - /** - * Constructor. - * @param lg LinkGraph to get the node from. - * @param node ID of the node. - */ - Node(LinkGraph *lg, NodeID node) : NodeWrapper(lg->nodes[node], node) {} - - /** - * Get an Edge. This is not a reference as the wrapper objects are not - * actually persistent. - * @param to ID of end node of edge. - * @return Edge wrapper. - */ - Edge operator[](NodeID to) - { - assert(this->HasEdgeTo(to)); - return Edge(*this->GetEdge(to)); - } - - /** - * Get an iterator pointing to the start of the edges array. - * @return Edge iterator. - */ - EdgeIterator Begin() { return EdgeIterator(this->node.edges, false); } - - /** - * Get an iterator pointing beyond the end of the edges array. - * @return Constant edge iterator. - */ - EdgeIterator End() { return EdgeIterator(this->node.edges, true); } /** * Update the node's supply and set last_update to the current date. @@ -446,8 +105,8 @@ public: */ void UpdateSupply(uint supply) { - this->node.supply += supply; - this->node.last_update = _date; + this->supply += supply; + this->last_update = _date; } /** @@ -456,7 +115,7 @@ public: */ void UpdateLocation(TileIndex xy) { - this->node.xy = xy; + this->xy = xy; } /** @@ -465,12 +124,45 @@ public: */ void SetDemand(uint demand) { - this->node.demand = demand; + this->demand = demand; } void AddEdge(NodeID to, uint capacity, uint usage, uint32 time, EdgeUpdateMode mode); void UpdateEdge(NodeID to, uint capacity, uint usage, uint32 time, EdgeUpdateMode mode); void RemoveEdge(NodeID to); + + /** + * Check if an edge to a destination is present. + * @param dest Wanted edge destination. + * @return True if an edge is present. + */ + bool HasEdgeTo(NodeID dest) const + { + return std::binary_search(this->edges.begin(), this->edges.end(), dest); + } + + BaseEdge &operator[](NodeID to) + { + assert(this->HasEdgeTo(to)); + return *GetEdge(to); + } + + const BaseEdge &operator[](NodeID to) const + { + assert(this->HasEdgeTo(to)); + return *GetEdge(to); + } + + private: + std::vector::iterator GetEdge(NodeID dest) + { + return std::lower_bound(this->edges.begin(), this->edges.end(), dest); + } + + std::vector::const_iterator GetEdge(NodeID dest) const + { + return std::lower_bound(this->edges.begin(), this->edges.end(), dest); + } }; typedef std::vector NodeVector; @@ -523,14 +215,14 @@ public: * @param num ID of the node. * @return the Requested node. */ - inline Node operator[](NodeID num) { return Node(this, num); } + inline BaseNode &operator[](NodeID num) { return this->nodes[num]; } /** * Get a const reference to a node with the specified id. * @param num ID of the node. * @return the Requested node. */ - inline ConstNode operator[](NodeID num) const { return ConstNode(this, num); } + inline const BaseNode &operator[](NodeID num) const { return this->nodes[num]; } /** * Get the current size of the component. @@ -564,8 +256,6 @@ public: void RemoveNode(NodeID id); protected: - friend class LinkGraph::ConstNode; - friend class LinkGraph::Node; friend SaveLoadTable GetLinkGraphDesc(); friend SaveLoadTable GetLinkGraphJobDesc(); friend class SlLinkgraphNode; diff --git a/src/linkgraph/linkgraph_base.h b/src/linkgraph/linkgraph_base.h index eb86c0c64e..0eed6063af 100644 --- a/src/linkgraph/linkgraph_base.h +++ b/src/linkgraph/linkgraph_base.h @@ -13,13 +13,11 @@ #include "linkgraph.h" #include "linkgraphschedule.h" -typedef LinkGraph::Node Node; -typedef LinkGraph::Edge Edge; -typedef LinkGraph::EdgeIterator EdgeIterator; +typedef LinkGraph::BaseNode Node; +typedef LinkGraph::BaseEdge Edge; -typedef LinkGraph::ConstNode ConstNode; -typedef LinkGraph::ConstEdge ConstEdge; -typedef LinkGraph::ConstEdgeIterator ConstEdgeIterator; +typedef const LinkGraph::BaseNode ConstNode; +typedef const LinkGraph::BaseEdge ConstEdge; #endif /* LINKGRAPH_BASE_H */ diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index 2f0c941553..73cdf9ba48 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -88,10 +88,10 @@ void LinkGraphOverlay::RebuildCache() if (!LinkGraph::IsValidID(sta->goods[c].link_graph)) continue; const LinkGraph &lg = *LinkGraph::Get(sta->goods[c].link_graph); - ConstNode from_node = lg[sta->goods[c].node]; - supply += lg.Monthly(from_node.Supply()); - for (ConstEdgeIterator i = from_node.Begin(); i != from_node.End(); ++i) { - StationID to = lg[i->first].Station(); + ConstNode &from_node = lg[sta->goods[c].node]; + supply += lg.Monthly(from_node.supply); + for (const Edge &edge : from_node.edges) { + StationID to = lg[edge.dest_node].station; assert(from != to); if (!Station::IsValidID(to) || seen_links.find(to) != seen_links.end()) { continue; @@ -218,8 +218,8 @@ void LinkGraphOverlay::AddLinks(const Station *from, const Station *to) } const LinkGraph &lg = *LinkGraph::Get(ge.link_graph); if (lg[ge.node].HasEdgeTo(to->goods[c].node)) { - ConstEdge edge = lg[ge.node][to->goods[c].node]; - this->AddStats(c, lg.Monthly(edge.Capacity()), lg.Monthly(edge.Usage()), + ConstEdge &edge = lg[ge.node][to->goods[c].node]; + this->AddStats(c, lg.Monthly(edge.capacity), lg.Monthly(edge.usage), ge.flows.GetFlowVia(to->index), edge.TravelTime() / DAY_TICKS, from->owner == OWNER_NONE || to->owner == OWNER_NONE, diff --git a/src/linkgraph/linkgraphjob.cpp b/src/linkgraph/linkgraphjob.cpp index 2a59ea9948..5902e01e73 100644 --- a/src/linkgraph/linkgraphjob.cpp +++ b/src/linkgraph/linkgraphjob.cpp @@ -138,7 +138,7 @@ LinkGraphJob::~LinkGraphJob() * from the new flows. This avoids flow cycles between old and * new flows. */ while (!erased.IsEmpty()) ge.flows.erase(erased.Pop()); - } else if ((*lg)[node_id][dest_id].LastUnrestrictedUpdate() == INVALID_DATE) { + } else if ((*lg)[node_id][dest_id].last_restricted_update == INVALID_DATE) { /* Edge is fully restricted. */ flows.RestrictFlows(to); } diff --git a/src/saveload/linkgraph_sl.cpp b/src/saveload/linkgraph_sl.cpp index c3abf88c32..fc6059f97a 100644 --- a/src/saveload/linkgraph_sl.cpp +++ b/src/saveload/linkgraph_sl.cpp @@ -234,7 +234,7 @@ void AfterLoadLinkGraphs() if (IsSavegameVersionBefore(SLV_191)) { for (LinkGraph *lg : LinkGraph::Iterate()) { for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) { - const Station *st = Station::GetIfValid((*lg)[node_id].Station()); + const Station *st = Station::GetIfValid((*lg)[node_id].station); if (st != nullptr) (*lg)[node_id].UpdateLocation(st->xy); } } @@ -242,7 +242,7 @@ void AfterLoadLinkGraphs() for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) { LinkGraph *lg = &(const_cast(lgj->Graph())); for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) { - const Station *st = Station::GetIfValid((*lg)[node_id].Station()); + const Station *st = Station::GetIfValid((*lg)[node_id].station); if (st != nullptr) (*lg)[node_id].UpdateLocation(st->xy); } } diff --git a/src/station.cpp b/src/station.cpp index 3922af085d..a9ccfc4329 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -104,7 +104,7 @@ Station::~Station() if (lg == nullptr) continue; for (NodeID node = 0; node < lg->Size(); ++node) { - Station *st = Station::Get((*lg)[node].Station()); + Station *st = Station::Get((*lg)[node].station); st->goods[c].flows.erase(this->index); if ((*lg)[node].HasEdgeTo(this->goods[c].node) && (*lg)[node][this->goods[c].node].LastUpdate() != INVALID_DATE) { st->goods[c].flows.DeleteFlows(this->index); diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 986e0f6f52..526bbd6c8c 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -3719,12 +3719,10 @@ void DeleteStaleLinks(Station *from) GoodsEntry &ge = from->goods[c]; LinkGraph *lg = LinkGraph::GetIfValid(ge.link_graph); if (lg == nullptr) continue; - Node node = (*lg)[ge.node]; std::vector to_remove{}; - for (EdgeIterator it(node.Begin()); it != node.End(); ++it) { - Edge edge = it->second; - Station *to = Station::Get((*lg)[it->first].Station()); - assert(to->goods[c].node == it->first); + for (Edge &edge : (*lg)[ge.node].edges) { + Station *to = Station::Get((*lg)[edge.dest_node].station); + assert(to->goods[c].node == edge.dest_node); assert(_date >= edge.LastUpdate()); uint timeout = LinkGraph::MIN_TIMEOUT_DISTANCE + (DistanceManhattan(from->xy, to->xy) >> 3); if ((uint)(_date - edge.LastUpdate()) > timeout) { @@ -3782,16 +3780,16 @@ void DeleteStaleLinks(Station *from) ge.flows.DeleteFlows(to->index); RerouteCargo(from, c, to->index, from->index); } - } else if (edge.LastUnrestrictedUpdate() != INVALID_DATE && (uint)(_date - edge.LastUnrestrictedUpdate()) > timeout) { + } else if (edge.last_unrestricted_update != INVALID_DATE && (uint)(_date - edge.last_unrestricted_update) > timeout) { edge.Restrict(); ge.flows.RestrictFlows(to->index); RerouteCargo(from, c, to->index, from->index); - } else if (edge.LastRestrictedUpdate() != INVALID_DATE && (uint)(_date - edge.LastRestrictedUpdate()) > timeout) { + } else if (edge.last_restricted_update != INVALID_DATE && (uint)(_date - edge.last_restricted_update) > timeout) { edge.Release(); } } /* Remove dead edges. */ - for (NodeID r : to_remove) node.RemoveEdge(r); + for (NodeID r : to_remove) (*lg)[ge.node].RemoveEdge(r); assert(_date >= lg->LastCompression()); if ((uint)(_date - lg->LastCompression()) > LinkGraph::COMPRESSION_INTERVAL) { diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 6f3cf7076f..99a55e48f8 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -1837,7 +1837,7 @@ struct StationViewWindow : public Window { const LinkGraph *lg = LinkGraph::GetIfValid(ge->link_graph); SetDParam(0, cs->name); - SetDParam(1, lg != nullptr ? lg->Monthly((*lg)[ge->node].Supply()) : 0); + SetDParam(1, lg != nullptr ? lg->Monthly((*lg)[ge->node].supply) : 0); SetDParam(2, STR_CARGO_RATING_APPALLING + (ge->rating >> 5)); SetDParam(3, ToPercent8(ge->rating)); DrawString(tr.Indent(WidgetDimensions::scaled.hsep_indent, rtl), STR_STATION_VIEW_CARGO_SUPPLY_RATING);