00001
00002
00003
00004
00005
00006
00007
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 "../cargotype.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, 0xFFFF> LinkGraphPool;
00032 extern LinkGraphPool _link_graph_pool;
00033
00040 class LinkGraph : public LinkGraphPool::PoolItem<&_link_graph_pool> {
00041 public:
00042
00054 enum UpdateMode {
00055 REFRESH_RESTRICTED = UINT_MAX - 1,
00056 REFRESH_UNRESTRICTED = UINT_MAX
00057 };
00058
00064 struct BaseNode {
00065 uint supply;
00066 uint demand;
00067 StationID station;
00068 Date last_update;
00069 void Init(StationID st = INVALID_STATION, uint demand = 0);
00070 };
00071
00078 struct BaseEdge {
00079 uint distance;
00080 uint capacity;
00081 uint usage;
00082 Date last_unrestricted_update;
00083 Date last_restricted_update;
00084 NodeID next_edge;
00085 void Init(uint distance = 0);
00086 };
00087
00092 template<typename Tedge>
00093 class EdgeWrapper {
00094 protected:
00095 Tedge &edge;
00096
00097 public:
00098
00103 EdgeWrapper (Tedge &edge) : edge(edge) {}
00104
00109 uint Capacity() const { return this->edge.capacity; }
00110
00115 uint Usage() const { return this->edge.usage; }
00116
00121 uint Distance() const { return this->edge.distance; }
00122
00127 Date LastUnrestrictedUpdate() const { return this->edge.last_unrestricted_update; }
00128
00133 Date LastRestrictedUpdate() const { return this->edge.last_restricted_update; }
00134
00139 Date LastUpdate() const { return max(this->edge.last_unrestricted_update, this->edge.last_restricted_update); }
00140 };
00141
00147 template<typename Tnode, typename Tedge>
00148 class NodeWrapper {
00149 protected:
00150 Tnode &node;
00151 Tedge *edges;
00152 NodeID index;
00153
00154 public:
00155
00162 NodeWrapper(Tnode &node, Tedge *edges, NodeID index) : node(node),
00163 edges(edges), index(index) {}
00164
00169 uint Supply() const { return this->node.supply; }
00170
00175 uint Demand() const { return this->node.demand; }
00176
00181 StationID Station() const { return this->node.station; }
00182
00187 Date LastUpdate() const { return this->node.last_update; }
00188 };
00189
00197 template <class Tedge, class Tedge_wrapper, class Titer>
00198 class BaseEdgeIterator {
00199 protected:
00200 Tedge *base;
00201 NodeID current;
00202
00209 class FakePointer : public SmallPair<NodeID, Tedge_wrapper> {
00210 public:
00211
00216 FakePointer(const SmallPair<NodeID, Tedge_wrapper> &pair) : SmallPair<NodeID, Tedge_wrapper>(pair) {}
00217
00222 SmallPair<NodeID, Tedge_wrapper> *operator->() { return this; }
00223 };
00224
00225 public:
00231 BaseEdgeIterator (Tedge *base, NodeID current) :
00232 base(base),
00233 current(current == INVALID_NODE ? current : base[current].next_edge)
00234 {}
00235
00240 Titer &operator++()
00241 {
00242 this->current = this->base[this->current].next_edge;
00243 return static_cast<Titer &>(*this);
00244 }
00245
00250 Titer operator++(int)
00251 {
00252 Titer ret(static_cast<Titer &>(*this));
00253 this->current = this->base[this->current].next_edge;
00254 return ret;
00255 }
00256
00264 template<class Tother>
00265 bool operator==(const Tother &other)
00266 {
00267 return this->base == other.base && this->current == other.current;
00268 }
00269
00277 template<class Tother>
00278 bool operator!=(const Tother &other)
00279 {
00280 return this->base != other.base || this->current != other.current;
00281 }
00282
00287 SmallPair<NodeID, Tedge_wrapper> operator*() const
00288 {
00289 return SmallPair<NodeID, Tedge_wrapper>(this->current, Tedge_wrapper(this->base[this->current]));
00290 }
00291
00296 FakePointer operator->() const {
00297 return FakePointer(this->operator*());
00298 }
00299 };
00300
00304 typedef EdgeWrapper<const BaseEdge> ConstEdge;
00305
00309 class Edge : public EdgeWrapper<BaseEdge> {
00310 public:
00315 Edge(BaseEdge &edge) : EdgeWrapper<BaseEdge>(edge) {}
00316 void Update(uint capacity, uint usage);
00317 void Restrict() { this->edge.last_unrestricted_update = INVALID_DATE; }
00318 void Release() { this->edge.last_restricted_update = INVALID_DATE; }
00319 };
00320
00325 class ConstEdgeIterator : public BaseEdgeIterator<const BaseEdge, ConstEdge, ConstEdgeIterator> {
00326 public:
00332 ConstEdgeIterator(const BaseEdge *edges, NodeID current) :
00333 BaseEdgeIterator<const BaseEdge, ConstEdge, ConstEdgeIterator>(edges, current) {}
00334 };
00335
00340 class EdgeIterator : public BaseEdgeIterator<BaseEdge, Edge, EdgeIterator> {
00341 public:
00347 EdgeIterator(BaseEdge *edges, NodeID current) :
00348 BaseEdgeIterator<BaseEdge, Edge, EdgeIterator>(edges, current) {}
00349 };
00350
00355 class ConstNode : public NodeWrapper<const BaseNode, const BaseEdge> {
00356 public:
00362 ConstNode(const LinkGraph *lg, NodeID node) :
00363 NodeWrapper<const BaseNode, const BaseEdge>(lg->nodes[node], lg->edges[node], node)
00364 {}
00365
00372 ConstEdge operator[](NodeID to) const { return ConstEdge(this->edges[to]); }
00373
00378 ConstEdgeIterator Begin() const { return ConstEdgeIterator(this->edges, this->index); }
00379
00384 ConstEdgeIterator End() const { return ConstEdgeIterator(this->edges, INVALID_NODE); }
00385 };
00386
00390 class Node : public NodeWrapper<BaseNode, BaseEdge> {
00391 public:
00397 Node(LinkGraph *lg, NodeID node) :
00398 NodeWrapper<BaseNode, BaseEdge>(lg->nodes[node], lg->edges[node], node)
00399 {}
00400
00407 Edge operator[](NodeID to) { return Edge(this->edges[to]); }
00408
00413 EdgeIterator Begin() { return EdgeIterator(this->edges, this->index); }
00414
00419 EdgeIterator End() { return EdgeIterator(this->edges, INVALID_NODE); }
00420
00425 void UpdateSupply(uint supply)
00426 {
00427 this->node.supply += supply;
00428 this->node.last_update = _date;
00429 }
00430
00435 void SetDemand(uint demand)
00436 {
00437 this->node.demand = demand;
00438 }
00439
00440 void AddEdge(NodeID to, uint capacity, uint usage = 0);
00441 void UpdateEdge(NodeID to, uint capacity, uint usage = 0);
00442 void RemoveEdge(NodeID to);
00443 };
00444
00445 typedef SmallVector<BaseNode, 16> NodeVector;
00446 typedef SmallMatrix<BaseEdge> EdgeMatrix;
00447
00449 static const uint MIN_TIMEOUT_DISTANCE = 32;
00450
00452 static const uint COMPRESSION_INTERVAL = 256;
00453
00462 inline static uint Scale(uint val, uint target_age, uint orig_age)
00463 {
00464 return val > 0 ? max(1U, val * target_age / orig_age) : 0;
00465 }
00466
00468 LinkGraph() : cargo(INVALID_CARGO), last_compression(0) {}
00473 LinkGraph(CargoID cargo) : cargo(cargo), last_compression(_date) {}
00474
00475 void Init(uint size);
00476 void ShiftDates(int interval);
00477 void Compress();
00478 void Merge(LinkGraph *other);
00479
00480
00481
00482
00483
00484
00485
00486
00487
00493 inline Node operator[](NodeID num) { return Node(this, num); }
00494
00500 inline ConstNode operator[](NodeID num) const { return ConstNode(this, num); }
00501
00506 inline uint Size() const { return this->nodes.Length(); }
00507
00512 inline Date LastCompression() const { return this->last_compression; }
00513
00518 inline CargoID Cargo() const { return this->cargo; }
00519
00525 inline uint Monthly(uint base) const
00526 {
00527 return base * 30 / (_date - this->last_compression + 1);
00528 }
00529
00530 NodeID AddNode(const Station *st);
00531 void RemoveNode(NodeID id);
00532 void UpdateDistances(NodeID id, TileIndex xy);
00533
00534 protected:
00535 friend class LinkGraph::ConstNode;
00536 friend class LinkGraph::Node;
00537 friend const SaveLoad *GetLinkGraphDesc();
00538 friend const SaveLoad *GetLinkGraphJobDesc();
00539 friend void SaveLoad_LinkGraph(LinkGraph &lg);
00540
00541 CargoID cargo;
00542 Date last_compression;
00543 NodeVector nodes;
00544 EdgeMatrix edges;
00545 };
00546
00547 #define FOR_ALL_LINK_GRAPHS(var) FOR_ALL_ITEMS_FROM(LinkGraph, link_graph_index, var, 0)
00548
00549 #endif