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) : base(base), current(current) {}
00203 
00208     Titer &operator++()
00209     {
00210       this->current = this->base[this->current].next_edge;
00211       return static_cast<Titer &>(*this);
00212     }
00213 
00218     Titer operator++(int)
00219     {
00220       Titer ret(static_cast<Titer &>(*this));
00221       this->current = this->base[this->current].next_edge;
00222       return ret;
00223     }
00224 
00232     template<class Tother>
00233     bool operator==(const Tother &other)
00234     {
00235       return this->base == other.base && this->current == other.current;
00236     }
00237 
00245     template<class Tother>
00246     bool operator!=(const Tother &other)
00247     {
00248       return this->base != other.base || this->current != other.current;
00249     }
00250 
00255     SmallPair<NodeID, Tedge_wrapper> operator*() const
00256     {
00257       return SmallPair<NodeID, Tedge_wrapper>(this->current, Tedge_wrapper(this->base[this->current]));
00258     }
00259 
00264     FakePointer operator->() const {
00265       return FakePointer(this->operator*());
00266     }
00267   };
00268 
00272   typedef EdgeWrapper<const BaseEdge> ConstEdge;
00273 
00277   class Edge : public EdgeWrapper<BaseEdge> {
00278   public:
00283     Edge(BaseEdge &edge) : EdgeWrapper<BaseEdge>(edge) {}
00284     void Update(uint capacity, uint usage);
00285   };
00286 
00291   class ConstEdgeIterator : public BaseEdgeIterator<const BaseEdge, ConstEdge, ConstEdgeIterator> {
00292   public:
00298     ConstEdgeIterator(const BaseEdge *edges, NodeID current) :
00299       BaseEdgeIterator<const BaseEdge, ConstEdge, ConstEdgeIterator>(edges, current) {}
00300   };
00301 
00306   class EdgeIterator : public BaseEdgeIterator<BaseEdge, Edge, EdgeIterator> {
00307   public:
00313     EdgeIterator(BaseEdge *edges, NodeID current) :
00314       BaseEdgeIterator<BaseEdge, Edge, EdgeIterator>(edges, current) {}
00315   };
00316 
00321   class ConstNode : public NodeWrapper<const BaseNode, const BaseEdge> {
00322   public:
00328     ConstNode(const LinkGraph *lg, NodeID node) :
00329       NodeWrapper<const BaseNode, const BaseEdge>(lg->nodes[node], lg->edges[node], node)
00330     {}
00331 
00338     ConstEdge operator[](NodeID to) const { return ConstEdge(this->edges[to]); }
00339 
00344     ConstEdgeIterator Begin() const { return ConstEdgeIterator(this->edges, index); }
00345 
00350     ConstEdgeIterator End() const { return ConstEdgeIterator(this->edges, INVALID_NODE); }
00351   };
00352 
00356   class Node : public NodeWrapper<BaseNode, BaseEdge> {
00357   public:
00363     Node(LinkGraph *lg, NodeID node) :
00364       NodeWrapper<BaseNode, BaseEdge>(lg->nodes[node], lg->edges[node], node)
00365     {}
00366 
00373     Edge operator[](NodeID to) { return Edge(this->edges[to]); }
00374 
00379     EdgeIterator Begin() { return EdgeIterator(this->edges, this->index); }
00380 
00385     EdgeIterator End() { return EdgeIterator(this->edges, INVALID_NODE); }
00386 
00391     void UpdateSupply(uint supply)
00392     {
00393       this->node.supply += supply;
00394       this->node.last_update = _date;
00395     }
00396 
00401     void SetDemand(uint demand)
00402     {
00403       this->node.demand = demand;
00404     }
00405 
00406     void AddEdge(NodeID to, uint capacity, uint usage = 0);
00407     void UpdateEdge(NodeID to, uint capacity, uint usage = 0);
00408     void RemoveEdge(NodeID to);
00409   };
00410 
00411   typedef SmallVector<BaseNode, 16> NodeVector;
00412   typedef SmallMatrix<BaseEdge> EdgeMatrix;
00413 
00415   static const uint MIN_TIMEOUT_DISTANCE = 48;
00416 
00418   static const uint COMPRESSION_TICK = 58;
00419 
00428   inline static uint Scale(uint val, uint target_age, uint orig_age)
00429   {
00430     return val > 0 ? max(1U, val * target_age / orig_age) : 0;
00431   }
00432 
00434   LinkGraph() : cargo(INVALID_CARGO), last_compression(0) {}
00439   LinkGraph(CargoID cargo) : cargo(cargo), last_compression(_date) {}
00440 
00441   void Init(uint size);
00442   void Compress();
00443   void Merge(LinkGraph *other);
00444 
00445   /* Splitting link graphs is intentionally not implemented.
00446    * The overhead in determining connectedness would probably outweigh the
00447    * benefit of having to deal with smaller graphs. In real world examples
00448    * networks generally grow. Only rarely a network is permanently split.
00449    * Reacting to temporary splits here would obviously create performance
00450    * problems and detecting the temporary or permanent nature of splits isn't
00451    * trivial. */
00452 
00458   inline Node operator[](NodeID num) { return Node(this, num); }
00459 
00465   inline ConstNode operator[](NodeID num) const { return ConstNode(this, num); }
00466 
00471   inline uint Size() const { return this->nodes.Length(); }
00472 
00477   inline Date LastCompression() const { return this->last_compression; }
00478 
00483   inline CargoID Cargo() const { return this->cargo; }
00484 
00490   inline uint Monthly(uint base) const
00491   {
00492     return base * 30 / (_date - this->last_compression + 1);
00493   }
00494 
00495   NodeID AddNode(const Station *st);
00496   void RemoveNode(NodeID id);
00497 
00498 protected:
00499   friend class LinkGraph::ConstNode;
00500   friend class LinkGraph::Node;
00501   friend const SaveLoad *GetLinkGraphDesc();
00502   friend const SaveLoad *GetLinkGraphJobDesc();
00503   friend void SaveLoad_LinkGraph(LinkGraph &lg);
00504 
00505   CargoID cargo;         
00506   Date last_compression; 
00507   NodeVector nodes;      
00508   EdgeMatrix edges;      
00509 };
00510 
00511 #define FOR_ALL_LINK_GRAPHS(var) FOR_ALL_ITEMS_FROM(LinkGraph, link_graph_index, var, 0)
00512 
00513 #endif /* LINKGRAPH_H */