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 "../stdafx.h"
00016 #include "../station_base.h"
00017 #include "../cargo_type.h"
00018 #include "../thread/thread.h"
00019 #include "../settings_type.h"
00020 #include "../date_func.h"
00021 #include "linkgraph_type.h"
00022 #include <list>
00023 #include <vector>
00024 #include <set>
00025 
00026 struct SaveLoad;
00027 class Path;
00028 
00029 typedef std::set<Path *> PathSet;
00030 typedef std::map<NodeID, Path *> PathViaMap;
00031 typedef std::map<StationID, int> FlowViaMap;
00032 typedef std::map<StationID, FlowViaMap> FlowMap;
00033 
00039 class Node {
00040 public:
00041   uint supply;             
00042   uint undelivered_supply; 
00043   uint demand;             
00044   StationID station;       
00045   PathSet paths;           
00046   FlowMap flows;           
00047 
00051   ~Node() {this->Init();}
00052 
00053   void Init(StationID st = INVALID_STATION, uint sup = 0, uint dem = 0);
00054   void ExportFlows(CargoID cargo);
00055 
00056 private:
00057   void ExportNewFlows(FlowMap::iterator &it, FlowStatSet &via_set, CargoID cargo);
00058 };
00059 
00066 class Edge {
00067 public:
00068   uint distance;           
00069   uint capacity;           
00070   uint demand;             
00071   uint unsatisfied_demand; 
00072   uint flow;               
00073   NodeID next_edge;        
00074 
00075   void Init(uint distance = 0, uint capacity = 0);
00076 };
00077 
00084 class LinkGraphComponent {
00085 private:
00086   typedef std::vector<Node> NodeVector;
00087   typedef std::vector<std::vector<Edge> > EdgeMatrix;
00088 
00089 public:
00090   LinkGraphComponent();
00091 
00092   void Init(LinkGraphComponentID id);
00093 
00100   FORCEINLINE Edge &GetEdge(NodeID from, NodeID to)
00101   {
00102     return this->edges[from][to];
00103   }
00104 
00110   FORCEINLINE Node &GetNode(NodeID num)
00111   {
00112     return this->nodes[num];
00113   }
00114 
00119   FORCEINLINE uint GetSize() const
00120   {
00121     return this->num_nodes;
00122   }
00123 
00124   void SetSize();
00125 
00126   NodeID AddNode(Station *st);
00127 
00128   FORCEINLINE void AddEdge(NodeID from, NodeID to, uint capacity);
00129 
00134   FORCEINLINE LinkGraphComponentID GetIndex() const
00135   {
00136     return this->index;
00137   }
00138 
00143   FORCEINLINE CargoID GetCargo() const
00144   {
00145     return this->cargo;
00146   }
00147 
00152   FORCEINLINE const LinkGraphSettings &GetSettings() const
00153   {
00154     return this->settings;
00155   }
00156 
00162   FORCEINLINE NodeID GetFirstEdge(NodeID from)
00163   {
00164     return edges[from][from].next_edge;
00165   }
00166 
00170   FORCEINLINE void Clear()
00171   {
00172     this->num_nodes = 0;
00173   }
00174 
00175 protected:
00176   LinkGraphSettings settings; 
00177   CargoID cargo;              
00178   uint num_nodes;             
00179   LinkGraphComponentID index; 
00180   NodeVector nodes;           
00181   EdgeMatrix edges;           
00182 };
00183 
00188 class ComponentHandler {
00189 public:
00193   virtual ~ComponentHandler() {}
00194 
00199   virtual void Run(LinkGraphComponent *component) = 0;
00200 };
00201 
00207 class LinkGraphJob : public LinkGraphComponent {
00208 private:
00209   typedef std::list<ComponentHandler *> HandlerList;
00210 
00211 public:
00212   LinkGraphJob() : thread(NULL) {}
00213 
00217   ~LinkGraphJob()
00218   {
00219     this->Join();
00220   }
00221 
00222   static void RunLinkGraphJob(void *j);
00223 
00228   static void AddHandler(ComponentHandler *handler)
00229   {
00230     LinkGraphJob::_handlers.push_back(handler);
00231   }
00232 
00233   static void ClearHandlers();
00234 
00235   void SpawnThread();
00236 
00237   void Join();
00238 
00239 private:
00240   static HandlerList _handlers;   
00241   ThreadObject *thread;           
00242 
00248   LinkGraphJob(const LinkGraphJob &other) : LinkGraphComponent(other) {NOT_REACHED();}
00249 };
00250 
00254 class LinkGraph : public LinkGraphJob {
00255 public:
00256   static const uint COMPONENTS_JOIN_TICK  = 21; 
00257   static const uint COMPONENTS_SPAWN_TICK = 58; 
00258 
00262   LinkGraph() : current_station_id(0) {}
00263 
00264   void Init(CargoID cargo);
00265 
00266   void NextComponent();
00267 
00268   void Join();
00269 
00270 private:
00271   StationID current_station_id; 
00272 
00273   friend const SaveLoad *GetLinkGraphDesc();
00274 
00275   void CreateComponent(Station *first);
00276 };
00277 
00281 class Path {
00282 public:
00283   Path(NodeID n, bool source = false);
00284 
00286   FORCEINLINE NodeID GetNode() const {return this->node;}
00287 
00289   FORCEINLINE NodeID GetOrigin() const {return this->origin;}
00290 
00292   FORCEINLINE Path *GetParent() {return this->parent;}
00293 
00295   FORCEINLINE uint GetCapacity() const {return this->capacity;}
00296 
00298   FORCEINLINE int GetFreeCapacity() const {return this->free_capacity;}
00299 
00303   FORCEINLINE int GetCapacityRatio() const {return (this->free_capacity << 4) / (this->capacity + 1);}
00304 
00306   FORCEINLINE uint GetDistance() const {return this->distance;}
00307 
00309   FORCEINLINE void ReduceFlow(uint f) {this->flow -= f;}
00310 
00312   FORCEINLINE void AddFlow(uint f) {this->flow += f;}
00313 
00315   FORCEINLINE uint GetFlow() const {return this->flow;}
00316 
00318   FORCEINLINE uint GetNumChildren() const {return this->num_children;}
00319 
00323   FORCEINLINE void UnFork()
00324   {
00325     if (this->parent != NULL) {
00326       this->parent->num_children--;
00327       this->parent = NULL;
00328     }
00329   }
00330   
00331   uint AddFlow(uint f, LinkGraphComponent *graph, bool only_positive);
00332   void Fork(Path *base, uint cap, int free_cap, uint dist);
00333 
00334 protected:
00335   uint distance;     
00336   uint capacity;     
00337   int free_capacity; 
00338   uint flow;         
00339   NodeID node;       
00340   NodeID origin;     
00341   uint num_children; 
00342   Path *parent;      
00343 };
00344 
00345 void InitializeLinkGraphs();
00346 extern LinkGraph _link_graphs[NUM_CARGO];
00347 
00348 #endif /* LINKGRAPH_H_ */