(svn r25361) -Feature: distribute cargo according to plan given by linkgraph

This commit is contained in:
fonsinchen
2013-06-09 13:03:48 +00:00
parent a2ff96d682
commit 04e3eb6fab
16 changed files with 586 additions and 206 deletions

View File

@@ -15,8 +15,10 @@
#include "core/pool_type.hpp"
#include "economy_type.h"
#include "station_type.h"
#include "order_type.h"
#include "cargo_type.h"
#include "vehicle_type.h"
#include "core/multimap.hpp"
#include <list>
/** Unique identifier for a single cargo packet. */
@@ -28,10 +30,14 @@ typedef Pool<CargoPacket, CargoPacketID, 1024, 0xFFF000, PT_NORMAL, true, false>
/** The actual pool with cargo packets. */
extern CargoPacketPool _cargopacket_pool;
template <class Tinst> class CargoList;
struct GoodsEntry; // forward-declare for Stage() and RerouteStalePackets()
template <class Tinst, class Tcont> class CargoList;
class StationCargoList; // forward-declare, so we can use it in VehicleCargoList.
extern const struct SaveLoad *GetCargoPacketDesc();
typedef uint32 TileOrStationID;
/**
* Container for cargo from the same location and time.
*/
@@ -44,10 +50,13 @@ private:
SourceID source_id; ///< Index of source, INVALID_SOURCE if unknown/invalid.
StationID source; ///< The station where the cargo came from first.
TileIndex source_xy; ///< The origin of the cargo (first station in feeder chain).
TileIndex loaded_at_xy; ///< Location where this cargo has been loaded into the vehicle.
union {
TileOrStationID loaded_at_xy; ///< Location where this cargo has been loaded into the vehicle.
TileOrStationID next_station; ///< Station where the cargo wants to go next.
};
/** The CargoList caches, thus needs to know about it. */
template <class Tinst> friend class CargoList;
template <class Tinst, class Tcont> friend class CargoList;
friend class VehicleCargoList;
friend class StationCargoList;
/** We want this to be saved, right? */
@@ -165,6 +174,14 @@ public:
return this->loaded_at_xy;
}
/**
* Gets the ID of station the cargo wants to go next.
* @return Next station for this packets.
*/
inline StationID NextStation() const
{
return this->next_station;
}
static void InvalidateAllFrom(SourceType src_type, SourceID src);
static void InvalidateAllFrom(StationID sid);
@@ -188,19 +205,17 @@ public:
* Simple collection class for a list of cargo packets.
* @tparam Tinst Actual instantiation of this cargo list.
*/
template <class Tinst>
template <class Tinst, class Tcont>
class CargoList {
public:
/** Container with cargo packets. */
typedef std::list<CargoPacket *> List;
/** The iterator for our container. */
typedef List::iterator Iterator;
typedef typename Tcont::iterator Iterator;
/** The reverse iterator for our container. */
typedef List::reverse_iterator ReverseIterator;
typedef typename Tcont::reverse_iterator ReverseIterator;
/** The const iterator for our container. */
typedef List::const_iterator ConstIterator;
typedef typename Tcont::const_iterator ConstIterator;
/** The const reverse iterator for our container. */
typedef List::const_reverse_iterator ConstReverseIterator;
typedef typename Tcont::const_reverse_iterator ConstReverseIterator;
/** Kind of actions that could be done with packets on move. */
enum MoveToAction {
@@ -217,18 +232,12 @@ protected:
uint count; ///< Cache for the number of cargo entities.
uint cargo_days_in_transit; ///< Cache for the sum of number of days in transit of each entity; comparable to man-hours.
List packets; ///< The cargo packets in this list.
Tcont packets; ///< The cargo packets in this list.
void AddToCache(const CargoPacket *cp);
void RemoveFromCache(const CargoPacket *cp, uint count);
template<class Taction>
void ShiftCargo(Taction action);
template<class Taction>
void PopCargo(Taction action);
static bool TryMerge(CargoPacket *cp, CargoPacket *icp);
public:
@@ -243,20 +252,11 @@ public:
* Returns a pointer to the cargo packet list (so you can iterate over it etc).
* @return Pointer to the packet list.
*/
inline const List *Packets() const
inline const Tcont *Packets() const
{
return &this->packets;
}
/**
* Returns source of the first cargo packet in this list.
* @return The before mentioned source.
*/
inline StationID Source() const
{
return this->count == 0 ? INVALID_STATION : this->packets.front()->source;
}
/**
* Returns average number of days in transit for a cargo entity.
* @return The before mentioned number.
@@ -266,22 +266,28 @@ public:
return this->count == 0 ? 0 : this->cargo_days_in_transit / this->count;
}
uint Truncate(uint max_move = UINT_MAX);
void InvalidateCache();
};
typedef std::list<CargoPacket *> CargoPacketList;
/**
* CargoList that is used for vehicles.
*/
class VehicleCargoList : public CargoList<VehicleCargoList> {
class VehicleCargoList : public CargoList<VehicleCargoList, CargoPacketList> {
protected:
/** The (direct) parent of this class. */
typedef CargoList<VehicleCargoList> Parent;
typedef CargoList<VehicleCargoList, CargoPacketList> Parent;
Money feeder_share; ///< Cache for the feeder share.
uint action_counts[NUM_MOVE_TO_ACTION]; ///< Counts of cargo to be transfered, delivered, kept and loaded.
template<class Taction>
void ShiftCargo(Taction action);
template<class Taction>
void PopCargo(Taction action);
/**
* Assert that the designation counts add up.
*/
@@ -300,8 +306,10 @@ protected:
void RemoveFromMeta(const CargoPacket *cp, MoveToAction action, uint count);
public:
/** The station cargo list needs to control the unloading. */
friend class StationCargoList;
/** The super class ought to know what it's doing. */
friend class CargoList<VehicleCargoList>;
friend class CargoList<VehicleCargoList, CargoPacketList>;
/** The vehicles have a cargo list (and we want that saved). */
friend const struct SaveLoad *GetVehicleDescription(VehicleType vt);
@@ -312,6 +320,15 @@ public:
friend class CargoRemoval;
friend class CargoReturn;
/**
* Returns source of the first cargo packet in this list.
* @return The before mentioned source.
*/
inline StationID Source() const
{
return this->count == 0 ? INVALID_STATION : this->packets.front()->source;
}
/**
* Returns total sum of the feeder share for all packets.
* @return The before mentioned number.
@@ -383,7 +400,9 @@ public:
void InvalidateCache();
bool Stage(bool accepted, StationID current_station, uint8 order_flags);
void SetTransferLoadPlace(TileIndex xy);
bool Stage(bool accepted, StationID current_station, StationID next_station, uint8 order_flags, const GoodsEntry *ge, CargoPayment *payment);
/**
* Marks all cargo in the vehicle as to be kept. This is mostly useful for
@@ -401,9 +420,10 @@ public:
* applicable), return value is amount of cargo actually moved. */
uint Reassign(uint max_move, MoveToAction from, MoveToAction to);
uint Return(uint max_move, StationCargoList *dest);
uint Return(uint max_move, StationCargoList *dest, StationID next_station);
uint Unload(uint max_move, StationCargoList *dest, CargoPayment *payment);
uint Shift(uint max_move, VehicleCargoList *dest);
uint Truncate(uint max_move = UINT_MAX);
/**
* Are two the two CargoPackets mergeable in the context of
@@ -422,19 +442,21 @@ public:
}
};
typedef MultiMap<StationID, CargoPacket *> StationCargoPacketMap;
/**
* CargoList that is used for stations.
*/
class StationCargoList : public CargoList<StationCargoList> {
class StationCargoList : public CargoList<StationCargoList, StationCargoPacketMap> {
protected:
/** The (direct) parent of this class. */
typedef CargoList<StationCargoList> Parent;
typedef CargoList<StationCargoList, StationCargoPacketMap> Parent;
uint reserved_count; ///< Amount of cargo being reserved for loading.
public:
/** The super class ought to know what it's doing. */
friend class CargoList<StationCargoList>;
friend class CargoList<StationCargoList, StationCargoPacketMap>;
/** The stations, via GoodsEntry, have a CargoList. */
friend const struct SaveLoad *GetGoodsDesc();
@@ -444,6 +466,36 @@ public:
friend class CargoRemoval;
friend class CargoReservation;
friend class CargoReturn;
friend class CargoReroute;
static void InvalidateAllFrom(SourceType src_type, SourceID src);
template<class Taction>
bool ShiftCargo(Taction &action, StationID next);
template<class Taction>
uint ShiftCargo(Taction action, StationID next, bool include_invalid);
void Append(CargoPacket *cp, StationID next);
/**
* Check for cargo headed for a specific station.
* @param next Station the cargo is headed for.
* @return If there is any cargo for that station.
*/
inline bool HasCargoFor(StationID next) const
{
return this->packets.find(next) != this->packets.end();
}
/**
* Returns source of the first cargo packet in this list.
* @return The before mentioned source.
*/
inline StationID Source() const
{
return this->count == 0 ? INVALID_STATION : this->packets.begin()->second.front()->source;
}
/**
* Returns sum of cargo still available for loading at the sation.
@@ -474,14 +526,14 @@ public:
return this->count + this->reserved_count;
}
void Append(CargoPacket *cp);
/* Methods for moving cargo around. First parameter is always maximum
* amount of cargo to be moved. Second parameter is destination (if
* applicable), return value is amount of cargo actually moved. */
uint Reserve(uint max_move, VehicleCargoList *dest, TileIndex load_place);
uint Load(uint max_move, VehicleCargoList *dest, TileIndex load_place);
uint Reserve(uint max_move, VehicleCargoList *dest, TileIndex load_place, StationID next);
uint Load(uint max_move, VehicleCargoList *dest, TileIndex load_place, StationID next);
uint Truncate(uint max_move = UINT_MAX);
uint Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge);
/**
* Are two the two CargoPackets mergeable in the context of