# linkgraph.h

Go to the documentation of this file.

    00001 /* $Id$ */
    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 "../cargo_type.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, 0xFFFFFF> LinkGraphPool;
    00032 extern LinkGraphPool _link_graph_pool;
    00033
    00040 class LinkGraph : public LinkGraphPool::PoolItem<&_link_graph_pool> {
    00041 public:
    00042
    00048   struct BaseNode {
    00049     uint supply;
    00050     uint demand;
    00051     StationID station;
    00052     Date last_update;
    00053     void Init(StationID st = INVALID_STATION, uint demand = 0);
    00054   };
    00055
    00062   struct BaseEdge {
    00063     uint distance;
    00064     uint capacity;
    00065     uint usage;
    00066     Date last_update;
    00067     NodeID next_edge;
    00068     void Init(uint distance = 0);
    00069   };
    00070
    00075   template<typename Tedge>
    00076   class EdgeWrapper {
    00077   protected:
    00078     Tedge &edge;
    00079
    00080   public:
    00081
    00086     EdgeWrapper (Tedge &edge) : edge(edge) {}
    00087
    00092     uint Capacity() const { return this->edge.capacity; }
    00093
    00098     uint Usage() const { return this->edge.usage; }
    00099
    00104     uint Distance() const { return this->edge.distance; }
    00105
    00110     Date LastUpdate() const { return this->edge.last_update; }
    00111   };
    00112
    00118   template<typename Tnode, typename Tedge>
    00119   class NodeWrapper {
    00120   protected:
    00121     Tnode &node;
    00122     Tedge *edges;
    00123     NodeID index;
    00124
    00125   public:
    00126
    00133     NodeWrapper(Tnode &node, Tedge *edges, NodeID index) : node(node),
    00134       edges(edges), index(index) {}
    00135
    00140     uint Supply() const { return this->node.supply; }
    00141
    00146     uint Demand() const { return this->node.demand; }
    00147
    00152     StationID Station() const { return this->node.station; }
    00153
    00158     Date LastUpdate() const { return this->node.last_update; }
    00159   };
    00160
    00168   template <class Tedge, class Tedge_wrapper, class Titer>
    00169   class BaseEdgeIterator {
    00170   protected:
    00171     Tedge *base;
    00172     NodeID current;
    00173
    00180     class FakePointer : public SmallPair<NodeID, Tedge_wrapper> {
    00181     public:
    00182
    00187       FakePointer(const SmallPair<NodeID, Tedge_wrapper> &pair) : SmallPair<NodeID, Tedge_wrapper>(pair) {}
    00188
    00193       SmallPair<NodeID, Tedge_wrapper> *operator->() { return this; }
    00194     };
    00195
    00196   public:
    00202     BaseEdgeIterator (Tedge *base, NodeID current) :
    00203       base(base),
    00204       current(current == INVALID_NODE ? current : base[current].next_edge)
    00205     {}
    00206
    00211     Titer &operator++()
    00212     {
    00213       this->current = this->base[this->current].next_edge;
    00214       return static_cast<Titer &>(*this);
    00215     }
    00216
    00221     Titer operator++(int)
    00222     {
    00223       Titer ret(static_cast<Titer &>(*this));
    00224       this->current = this->base[this->current].next_edge;
    00225       return ret;
    00226     }
    00227
    00235     template<class Tother>
    00236     bool operator==(const Tother &other)
    00237     {
    00238       return this->base == other.base && this->current == other.current;
    00239     }
    00240
    00248     template<class Tother>
    00249     bool operator!=(const Tother &other)
    00250     {
    00251       return this->base != other.base || this->current != other.current;
    00252     }
    00253
    00258     SmallPair<NodeID, Tedge_wrapper> operator*() const
    00259     {
    00260       return SmallPair<NodeID, Tedge_wrapper>(this->current, Tedge_wrapper(this->base[this->current]));
    00261     }
    00262
    00267     FakePointer operator->() const {
    00268       return FakePointer(this->operator*());
    00269     }
    00270   };
    00271
    00275   typedef EdgeWrapper<const BaseEdge> ConstEdge;
    00276
    00280   class Edge : public EdgeWrapper<BaseEdge> {
    00281   public:
    00286     Edge(BaseEdge &edge) : EdgeWrapper<BaseEdge>(edge) {}
    00287     void Update(uint capacity, uint usage);
    00288   };
    00289
    00294   class ConstEdgeIterator : public BaseEdgeIterator<const BaseEdge, ConstEdge, ConstEdgeIterator> {
    00295   public:
    00301     ConstEdgeIterator(const BaseEdge *edges, NodeID current) :
    00302       BaseEdgeIterator<const BaseEdge, ConstEdge, ConstEdgeIterator>(edges, current) {}
    00303   };
    00304
    00309   class EdgeIterator : public BaseEdgeIterator<BaseEdge, Edge, EdgeIterator> {
    00310   public:
    00316     EdgeIterator(BaseEdge *edges, NodeID current) :
    00317       BaseEdgeIterator<BaseEdge, Edge, EdgeIterator>(edges, current) {}
    00318   };
    00319
    00324   class ConstNode : public NodeWrapper<const BaseNode, const BaseEdge> {
    00325   public:
    00331     ConstNode(const LinkGraph *lg, NodeID node) :
    00332       NodeWrapper<const BaseNode, const BaseEdge>(lg->nodes[node], lg->edges[node], node)
    00333     {}
    00334
    00341     ConstEdge operator[](NodeID to) const { return ConstEdge(this->edges[to]); }
    00342
    00347     ConstEdgeIterator Begin() const { return ConstEdgeIterator(this->edges, this->index); }
    00348
    00353     ConstEdgeIterator End() const { return ConstEdgeIterator(this->edges, INVALID_NODE); }
    00354   };
    00355
    00359   class Node : public NodeWrapper<BaseNode, BaseEdge> {
    00360   public:
    00366     Node(LinkGraph *lg, NodeID node) :
    00367       NodeWrapper<BaseNode, BaseEdge>(lg->nodes[node], lg->edges[node], node)
    00368     {}
    00369
    00376     Edge operator[](NodeID to) { return Edge(this->edges[to]); }
    00377
    00382     EdgeIterator Begin() { return EdgeIterator(this->edges, this->index); }
    00383
    00388     EdgeIterator End() { return EdgeIterator(this->edges, INVALID_NODE); }
    00389
    00394     void UpdateSupply(uint supply)
    00395     {
    00396       this->node.supply += supply;
    00397       this->node.last_update = _date;
    00398     }
    00399
    00404     void SetDemand(uint demand)
    00405     {
    00406       this->node.demand = demand;
    00407     }
    00408
    00409     void AddEdge(NodeID to, uint capacity, uint usage = 0);
    00410     void UpdateEdge(NodeID to, uint capacity, uint usage = 0);
    00411     void RemoveEdge(NodeID to);
    00412   };
    00413
    00414   typedef SmallVector<BaseNode, 16> NodeVector;
    00415   typedef SmallMatrix<BaseEdge> EdgeMatrix;
    00416
    00418   static const uint MIN_TIMEOUT_DISTANCE = 48;
    00419
    00421   static const uint COMPRESSION_TICK = 58;
    00422
    00431   inline static uint Scale(uint val, uint target_age, uint orig_age)
    00432   {
    00433     return val > 0 ? max(1U, val * target_age / orig_age) : 0;
    00434   }
    00435
    00437   LinkGraph() : cargo(INVALID_CARGO), last_compression(0) {}
    00442   LinkGraph(CargoID cargo) : cargo(cargo), last_compression(_date) {}
    00443
    00444   void Init(uint size);
    00445   void Compress();
    00446   void Merge(LinkGraph *other);
    00447
    00448   /* Splitting link graphs is intentionally not implemented.
    00449    * The overhead in determining connectedness would probably outweigh the
    00450    * benefit of having to deal with smaller graphs. In real world examples
    00451    * networks generally grow. Only rarely a network is permanently split.
    00452    * Reacting to temporary splits here would obviously create performance
    00453    * problems and detecting the temporary or permanent nature of splits isn't
    00454    * trivial. */
    00455
    00461   inline Node operator[](NodeID num) { return Node(this, num); }
    00462
    00468   inline ConstNode operator[](NodeID num) const { return ConstNode(this, num); }
    00469
    00474   inline uint Size() const { return this->nodes.Length(); }
    00475
    00480   inline Date LastCompression() const { return this->last_compression; }
    00481
    00486   inline CargoID Cargo() const { return this->cargo; }
    00487
    00493   inline uint Monthly(uint base) const
    00494   {
    00495     return base * 30 / (_date - this->last_compression + 1);
    00496   }
    00497
    00498   NodeID AddNode(const Station *st);
    00499   void RemoveNode(NodeID id);
    00500
    00501 protected:
    00502   friend class LinkGraph::ConstNode;
    00503   friend class LinkGraph::Node;
    00504   friend const SaveLoad *GetLinkGraphDesc();
    00505   friend const SaveLoad *GetLinkGraphJobDesc();
    00506   friend void SaveLoad_LinkGraph(LinkGraph &lg);
    00507
    00508   CargoID cargo;
    00509   Date last_compression;
    00510   NodeVector nodes;
    00511   EdgeMatrix edges;
    00512 };
    00513
    00514 #define FOR_ALL_LINK_GRAPHS(var) FOR_ALL_ITEMS_FROM(LinkGraph, link_graph_index, var, 0)
    00515
    00516 #endif /* LINKGRAPH_H */