forked from mirror/OpenTTD
(svn r25345) -Add: implementation of SharesMap and FlowStatMap
This commit is contained in:
@@ -12,18 +12,101 @@
|
||||
#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;
|
||||
|
||||
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.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user