Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
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