summaryrefslogtreecommitdiff
path: root/src/station_base.h
diff options
context:
space:
mode:
authorfonsinchen <fonsinchen@openttd.org>2013-06-09 12:48:42 +0000
committerfonsinchen <fonsinchen@openttd.org>2013-06-09 12:48:42 +0000
commitc8f068d979251fb6963a56e3c0f9dac5b9897c72 (patch)
tree69f8d84a0d0fd233f9da4aae72357cf4c6bdc613 /src/station_base.h
parenta2d84868e74ab6814b55db75df82dfb48d494d14 (diff)
downloadopenttd-c8f068d979251fb6963a56e3c0f9dac5b9897c72.tar.xz
(svn r25345) -Add: implementation of SharesMap and FlowStatMap
Diffstat (limited to 'src/station_base.h')
-rw-r--r--src/station_base.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/station_base.h b/src/station_base.h
index 974caa063..200d97a97 100644
--- a/src/station_base.h
+++ b/src/station_base.h
@@ -12,12 +12,14 @@
#ifndef STATION_BASE_H
#define STATION_BASE_H
+#include "core/random_func.hpp"
#include "base_station_base.h"
#include "newgrf_airport.h"
#include "cargopacket.h"
#include "industry_type.h"
#include "linkgraph/linkgraph_type.h"
#include "newgrf_storage.h"
+#include <map>
typedef Pool<BaseStation, StationID, 32, 64000> StationPool;
extern StationPool _station_pool;
@@ -25,6 +27,87 @@ extern StationPool _station_pool;
static const byte INITIAL_STATION_RATING = 175;
/**
+ * Flow statistics telling how much flow should be sent along a link. This is
+ * done by creating "flow shares" and using std::map's upper_bound() method to
+ * look them up with a random number. A flow share is the difference between a
+ * key in a map and the previous key. So one key in the map doesn't actually
+ * mean anything by itself.
+ */
+class FlowStat {
+public:
+ typedef std::map<uint32, StationID> SharesMap;
+
+ /**
+ * Invalid constructor. This can't be called as a FlowStat must not be
+ * empty. However, the constructor must be defined and reachable for
+ * FlwoStat to be used in a std::map.
+ */
+ inline FlowStat() {NOT_REACHED();}
+
+ /**
+ * Create a FlowStat with an initial entry.
+ * @param st Station the initial entry refers to.
+ * @param flow Amount of flow for the initial entry.
+ */
+ inline FlowStat(StationID st, uint flow)
+ {
+ assert(flow > 0);
+ this->shares[flow] = st;
+ }
+
+ /**
+ * Add some flow to the end of the shares map. Only do that if you know
+ * that the station isn't in the map yet. Anything else may lead to
+ * inconsistencies.
+ * @param st Remote station.
+ * @param flow Amount of flow to be added.
+ */
+ inline void AppendShare(StationID st, uint flow)
+ {
+ assert(flow > 0);
+ this->shares[(--this->shares.end())->first + flow] = st;
+ }
+
+ uint GetShare(StationID st) const;
+
+ void ChangeShare(StationID st, int flow);
+
+ /**
+ * Get the actual shares as a const pointer so that they can be iterated
+ * over.
+ * @return Actual shares.
+ */
+ inline const SharesMap *GetShares() const { return &this->shares; }
+
+ /**
+ * Get a station a package can be routed to. This done by drawing a
+ * random number between 0 and sum_shares and then looking that up in
+ * the map with lower_bound. So each share gets selected with a
+ * probability dependent on its flow.
+ * @return A station ID from the shares map.
+ */
+ inline StationID GetVia() const
+ {
+ assert(!this->shares.empty());
+ return this->shares.upper_bound(RandomRange((--this->shares.end())->first - 1))->second;
+ }
+
+ StationID GetVia(StationID excluded, StationID excluded2 = INVALID_STATION) const;
+
+private:
+ SharesMap shares; ///< Shares of flow to be sent via specified station (or consumed locally).
+};
+
+/** Flow descriptions by origin stations. */
+class FlowStatMap : public std::map<StationID, FlowStat> {
+public:
+ void AddFlow(StationID origin, StationID via, uint amount);
+ void PassOnFlow(StationID origin, StationID via, uint amount);
+ void DeleteFlows(StationID via);
+ void FinalizeLocalConsumption(StationID self);
+};
+
+/**
* Stores station stats for a single cargo.
*/
struct GoodsEntry {