summaryrefslogtreecommitdiff
path: root/src/cargopacket.h
diff options
context:
space:
mode:
authorfonsinchen <fonsinchen@openttd.org>2013-06-09 13:03:48 +0000
committerfonsinchen <fonsinchen@openttd.org>2013-06-09 13:03:48 +0000
commit04e3eb6fabc0e4aff04c189368356b8af15e9655 (patch)
treeaa9d6a025fb3e343fc8cdc9358a913182445210b /src/cargopacket.h
parenta2ff96d6828bd32f7beb461bfb902880bf46ef75 (diff)
downloadopenttd-04e3eb6fabc0e4aff04c189368356b8af15e9655.tar.xz
(svn r25361) -Feature: distribute cargo according to plan given by linkgraph
Diffstat (limited to 'src/cargopacket.h')
-rw-r--r--src/cargopacket.h134
1 files changed, 93 insertions, 41 deletions
diff --git a/src/cargopacket.h b/src/cargopacket.h
index 15b233fd0..c31e4db58 100644
--- a/src/cargopacket.h
+++ b/src/cargopacket.h
@@ -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,21 +252,12 @@ 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);
@@ -313,6 +321,15 @@ public:
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