# linkgraph.h

Go to the documentation of this file.

    00001 /* $Id: linkgraph.h 26393 2014-03-06 21:19:41Z fonsinchen $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * 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.
    00006  * 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.
    00007  * 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/>.
    00008  */
    00009
    00012 #ifndef LINKGRAPH_H
    00013 #define LINKGRAPH_H
    00014
    00015 #include "../core/pool_type.hpp"
    00016 #include "../core/smallmap_type.hpp"
    00017 #include "../core/smallmatrix_type.hpp"
    00018 #include "../station_base.h"
    00019 #include "../cargotype.h"
    00020 #include "../date_func.h"
    00021 #include "linkgraph_type.h"
    00022
    00023 struct SaveLoad;
    00024 class LinkGraph;
    00025
    00030 typedef Pool<LinkGraph, LinkGraphID, 32, 0xFFFF> LinkGraphPool;
    00032 extern LinkGraphPool _link_graph_pool;
    00033
    00040 class LinkGraph : public LinkGraphPool::PoolItem<&_link_graph_pool> {
    00041 public:
    00042
    00054   enum UpdateMode {
    00055     REFRESH_RESTRICTED = UINT_MAX - 1,
    00056     REFRESH_UNRESTRICTED = UINT_MAX
    00057   };
    00058
    00064   struct BaseNode {
    00065     uint supply;
    00066     uint demand;
    00067     StationID station;
    00068     Date last_update;
    00069     void Init(StationID st = INVALID_STATION, uint demand = 0);
    00070   };
    00071
    00078   struct BaseEdge {
    00079     uint distance;
    00080     uint capacity;
    00081     uint usage;
    00082     Date last_unrestricted_update;
    00083     Date last_restricted_update;
    00084     NodeID next_edge;
    00085     void Init(uint distance = 0);
    00086   };
    00087
    00092   template<typename Tedge>
    00093   class EdgeWrapper {
    00094   protected:
    00095     Tedge &edge;
    00096
    00097   public:
    00098
    00103     EdgeWrapper (Tedge &edge) : edge(edge) {}
    00104
    00109     uint Capacity() const { return this->edge.capacity; }
    00110
    00115     uint Usage() const { return this->edge.usage; }
    00116
    00121     uint Distance() const { return this->edge.distance; }
    00122
    00127     Date LastUnrestrictedUpdate() const { return this->edge.last_unrestricted_update; }
    00128
    00133     Date LastRestrictedUpdate() const { return this->edge.last_restricted_update; }
    00134
    00139     Date LastUpdate() const { return max(this->edge.last_unrestricted_update, this->edge.last_restricted_update); }
    00140   };
    00141
    00147   template<typename Tnode, typename Tedge>
    00148   class NodeWrapper {
    00149   protected:
    00150     Tnode &node;
    00151     Tedge *edges;
    00152     NodeID index;
    00153
    00154   public:
    00155
    00162     NodeWrapper(Tnode &node, Tedge *edges, NodeID index) : node(node),
    00163       edges(edges), index(index) {}
    00164
    00169     uint Supply() const { return this->node.supply; }
    00170
    00175     uint Demand() const { return this->node.demand; }
    00176
    00181     StationID Station() const { return this->node.station; }
    00182
    00187     Date LastUpdate() const { return this->node.last_update; }
    00188   };
    00189
    00197   template <class Tedge, class Tedge_wrapper, class Titer>
    00198   class BaseEdgeIterator {
    00199   protected:
    00200     Tedge *base;
    00201     NodeID current;
    00202
    00209     class FakePointer : public SmallPair<NodeID, Tedge_wrapper> {
    00210     public:
    00211
    00216       FakePointer(const SmallPair<NodeID, Tedge_wrapper> &pair) : SmallPair<NodeID, Tedge_wrapper>(pair) {}
    00217
    00222       SmallPair<NodeID, Tedge_wrapper> *operator->() { return this; }
    00223     };
    00224
    00225   public:
    00231     BaseEdgeIterator (Tedge *base, NodeID current) :
    00232       base(base),
    00233       current(current == INVALID_NODE ? current : base[current].next_edge)
    00234     {}
    00235
    00240     Titer &operator++()
    00241     {
    00242       this->current = this->base[this->current].next_edge;
    00243       return static_cast<Titer &>(*this);
    00244     }
    00245
    00250     Titer operator++(int)
    00251     {
    00252       Titer ret(static_cast<Titer &>(*this));
    00253       this->current = this->base[this->current].next_edge;
    00254       return ret;
    00255     }
    00256
    00264     template<class Tother>
    00265     bool operator==(const Tother &other)
    00266     {
    00267       return this->base == other.base && this->current == other.current;
    00268     }
    00269
    00277     template<class Tother>
    00278     bool operator!=(const Tother &other)
    00279     {
    00280       return this->base != other.base || this->current != other.current;
    00281     }
    00282
    00287     SmallPair<NodeID, Tedge_wrapper> operator*() const
    00288     {
    00289       return SmallPair<NodeID, Tedge_wrapper>(this->current, Tedge_wrapper(this->base[this->current]));
    00290     }
    00291
    00296     FakePointer operator->() const {
    00297       return FakePointer(this->operator*());
    00298     }
    00299   };
    00300
    00304   typedef EdgeWrapper<const BaseEdge> ConstEdge;
    00305
    00309   class Edge : public EdgeWrapper<BaseEdge> {
    00310   public:
    00315     Edge(BaseEdge &edge) : EdgeWrapper<BaseEdge>(edge) {}
    00316     void Update(uint capacity, uint usage);
    00317     void Restrict() { this->edge.last_unrestricted_update = INVALID_DATE; }
    00318     void Release() { this->edge.last_restricted_update = INVALID_DATE; }
    00319   };
    00320
    00325   class ConstEdgeIterator : public BaseEdgeIterator<const BaseEdge, ConstEdge, ConstEdgeIterator> {
    00326   public:
    00332     ConstEdgeIterator(const BaseEdge *edges, NodeID current) :
    00333       BaseEdgeIterator<const BaseEdge, ConstEdge, ConstEdgeIterator>(edges, current) {}
    00334   };
    00335
    00340   class EdgeIterator : public BaseEdgeIterator<BaseEdge, Edge, EdgeIterator> {
    00341   public:
    00347     EdgeIterator(BaseEdge *edges, NodeID current) :
    00348       BaseEdgeIterator<BaseEdge, Edge, EdgeIterator>(edges, current) {}
    00349   };
    00350
    00355   class ConstNode : public NodeWrapper<const BaseNode, const BaseEdge> {
    00356   public:
    00362     ConstNode(const LinkGraph *lg, NodeID node) :
    00363       NodeWrapper<const BaseNode, const BaseEdge>(lg->nodes[node], lg->edges[node], node)
    00364     {}
    00365
    00372     ConstEdge operator[](NodeID to) const { return ConstEdge(this->edges[to]); }
    00373
    00378     ConstEdgeIterator Begin() const { return ConstEdgeIterator(this->edges, this->index); }
    00379
    00384     ConstEdgeIterator End() const { return ConstEdgeIterator(this->edges, INVALID_NODE); }
    00385   };
    00386
    00390   class Node : public NodeWrapper<BaseNode, BaseEdge> {
    00391   public:
    00397     Node(LinkGraph *lg, NodeID node) :
    00398       NodeWrapper<BaseNode, BaseEdge>(lg->nodes[node], lg->edges[node], node)
    00399     {}
    00400
    00407     Edge operator[](NodeID to) { return Edge(this->edges[to]); }
    00408
    00413     EdgeIterator Begin() { return EdgeIterator(this->edges, this->index); }
    00414
    00419     EdgeIterator End() { return EdgeIterator(this->edges, INVALID_NODE); }
    00420
    00425     void UpdateSupply(uint supply)
    00426     {
    00427       this->node.supply += supply;
    00428       this->node.last_update = _date;
    00429     }
    00430
    00435     void SetDemand(uint demand)
    00436     {
    00437       this->node.demand = demand;
    00438     }
    00439
    00440     void AddEdge(NodeID to, uint capacity, uint usage = 0);
    00441     void UpdateEdge(NodeID to, uint capacity, uint usage = 0);
    00442     void RemoveEdge(NodeID to);
    00443   };
    00444
    00445   typedef SmallVector<BaseNode, 16> NodeVector;
    00446   typedef SmallMatrix<BaseEdge> EdgeMatrix;
    00447
    00449   static const uint MIN_TIMEOUT_DISTANCE = 32;
    00450
    00452   static const uint COMPRESSION_INTERVAL = 256;
    00453
    00462   inline static uint Scale(uint val, uint target_age, uint orig_age)
    00463   {
    00464     return val > 0 ? max(1U, val * target_age / orig_age) : 0;
    00465   }
    00466
    00468   LinkGraph() : cargo(INVALID_CARGO), last_compression(0) {}
    00473   LinkGraph(CargoID cargo) : cargo(cargo), last_compression(_date) {}
    00474
    00475   void Init(uint size);
    00476   void ShiftDates(int interval);
    00477   void Compress();
    00478   void Merge(LinkGraph *other);
    00479
    00480   /* Splitting link graphs is intentionally not implemented.
    00481    * The overhead in determining connectedness would probably outweigh the
    00482    * benefit of having to deal with smaller graphs. In real world examples
    00483    * networks generally grow. Only rarely a network is permanently split.
    00484    * Reacting to temporary splits here would obviously create performance
    00485    * problems and detecting the temporary or permanent nature of splits isn't
    00486    * trivial. */
    00487
    00493   inline Node operator[](NodeID num) { return Node(this, num); }
    00494
    00500   inline ConstNode operator[](NodeID num) const { return ConstNode(this, num); }
    00501
    00506   inline uint Size() const { return this->nodes.Length(); }
    00507
    00512   inline Date LastCompression() const { return this->last_compression; }
    00513
    00518   inline CargoID Cargo() const { return this->cargo; }
    00519
    00525   inline uint Monthly(uint base) const
    00526   {
    00527     return base * 30 / (_date - this->last_compression + 1);
    00528   }
    00529
    00530   NodeID AddNode(const Station *st);
    00531   void RemoveNode(NodeID id);
    00532   void UpdateDistances(NodeID id, TileIndex xy);
    00533
    00534 protected:
    00535   friend class LinkGraph::ConstNode;
    00536   friend class LinkGraph::Node;
    00537   friend const SaveLoad *GetLinkGraphDesc();
    00538   friend const SaveLoad *GetLinkGraphJobDesc();
    00539   friend void SaveLoad_LinkGraph(LinkGraph &lg);
    00540
    00541   CargoID cargo;
    00542   Date last_compression;
    00543   NodeVector nodes;
    00544   EdgeMatrix edges;
    00545 };
    00546
    00547 #define FOR_ALL_LINK_GRAPHS(var) FOR_ALL_ITEMS_FROM(LinkGraph, link_graph_index, var, 0)
    00548
    00549 #endif /* LINKGRAPH_H */