linkgraph.h
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 "../station_base.h"
00016 #include "../cargo_type.h"
00017 #include "../thread/thread.h"
00018 #include "../settings_type.h"
00019 #include "../date_func.h"
00020 #include "linkgraph_type.h"
00021 #include <list>
00022 #include <vector>
00023 #include <set>
00024
00025 struct SaveLoad;
00026 class Path;
00027
00028 typedef std::set<Path *> PathSet;
00029 typedef std::map<NodeID, Path *> PathViaMap;
00030 typedef std::map<StationID, int> FlowViaMap;
00031 typedef std::map<StationID, FlowViaMap> FlowMap;
00032
00038 class Node {
00039 public:
00040 uint supply;
00041 uint undelivered_supply;
00042 uint demand;
00043 StationID station;
00044 PathSet paths;
00045 FlowMap flows;
00046
00050 ~Node() {this->Init();}
00051
00052 void Init(StationID st = INVALID_STATION, uint sup = 0, uint dem = 0);
00053 void ExportFlows(CargoID cargo);
00054
00055 private:
00056 void ExportNewFlows(FlowMap::iterator &it, FlowStatSet &via_set, CargoID cargo);
00057 };
00058
00065 class Edge {
00066 public:
00067 uint distance;
00068 uint capacity;
00069 uint demand;
00070 uint unsatisfied_demand;
00071 uint flow;
00072 NodeID next_edge;
00073
00074 void Init(uint distance = 0, uint capacity = 0);
00075 };
00076
00083 class LinkGraphComponent {
00084 private:
00085 typedef std::vector<Node> NodeVector;
00086 typedef std::vector<std::vector<Edge> > EdgeMatrix;
00087
00088 public:
00089 LinkGraphComponent();
00090
00091 void Init(LinkGraphComponentID id);
00092
00099 FORCEINLINE Edge &GetEdge(NodeID from, NodeID to)
00100 {
00101 return this->edges[from][to];
00102 }
00103
00109 FORCEINLINE Node &GetNode(NodeID num)
00110 {
00111 return this->nodes[num];
00112 }
00113
00118 FORCEINLINE uint GetSize() const
00119 {
00120 return this->num_nodes;
00121 }
00122
00123 void SetSize();
00124
00125 NodeID AddNode(Station *st);
00126
00127 void AddEdge(NodeID from, NodeID to, uint capacity);
00128
00133 FORCEINLINE LinkGraphComponentID GetIndex() const
00134 {
00135 return this->index;
00136 }
00137
00142 FORCEINLINE CargoID GetCargo() const
00143 {
00144 return this->cargo;
00145 }
00146
00151 FORCEINLINE const LinkGraphSettings &GetSettings() const
00152 {
00153 return this->settings;
00154 }
00155
00161 FORCEINLINE NodeID GetFirstEdge(NodeID from) {return edges[from][from].next_edge;}
00162
00166 FORCEINLINE void Clear()
00167 {
00168 this->num_nodes = 0;
00169 }
00170
00171 protected:
00172 LinkGraphSettings settings;
00173 CargoID cargo;
00174 uint num_nodes;
00175 LinkGraphComponentID index;
00176 NodeVector nodes;
00177 EdgeMatrix edges;
00178 };
00179
00184 class ComponentHandler {
00185 public:
00189 virtual ~ComponentHandler() {}
00190
00196 virtual void Run(LinkGraphComponent *component) = 0;
00197 };
00198
00204 class LinkGraphJob : public LinkGraphComponent {
00205 private:
00206 typedef std::list<ComponentHandler *> HandlerList;
00207
00208 public:
00209
00210 LinkGraphJob() : thread(NULL) {}
00211
00215 ~LinkGraphJob()
00216 {
00217 this->Join();
00218 }
00219
00220 static void RunLinkGraphJob(void *j);
00221
00226 static void AddHandler(ComponentHandler *handler)
00227 {
00228 LinkGraphJob::_handlers.push_back(handler);
00229 }
00230
00231 static void ClearHandlers();
00232
00233 void SpawnThread();
00234
00235 void Join();
00236
00237 private:
00238 static HandlerList _handlers;
00239 ThreadObject *thread;
00240
00246 LinkGraphJob(const LinkGraphJob &other) : LinkGraphComponent(other) {NOT_REACHED();}
00247 };
00248
00252 class LinkGraph : public LinkGraphJob {
00253 public:
00254
00255 static const uint COMPONENTS_JOIN_TICK = 21;
00256 static const uint COMPONENTS_SPAWN_TICK = 58;
00257
00261 LinkGraph() : current_station_id(0) {}
00262
00263 void Init(CargoID cargo);
00264
00265 void NextComponent();
00266
00267 void Join();
00268
00269 private:
00270 StationID current_station_id;
00271
00272 friend const SaveLoad *GetLinkGraphDesc();
00273
00274 void CreateComponent(Station *first);
00275 };
00276
00280 class Path {
00281 public:
00282 Path(NodeID n, bool source = false);
00283
00285 FORCEINLINE NodeID GetNode() const {return this->node;}
00286
00288 FORCEINLINE NodeID GetOrigin() const {return this->origin;}
00289
00291 FORCEINLINE Path *GetParent() {return this->parent;}
00292
00294 FORCEINLINE uint GetCapacity() const {return this->capacity;}
00295
00297 FORCEINLINE int GetFreeCapacity() const {return this->free_capacity;}
00298
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 Detach()
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