diff options
author | fonsinchen <fonsinchen@openttd.org> | 2013-06-09 13:03:48 +0000 |
---|---|---|
committer | fonsinchen <fonsinchen@openttd.org> | 2013-06-09 13:03:48 +0000 |
commit | 04e3eb6fabc0e4aff04c189368356b8af15e9655 (patch) | |
tree | aa9d6a025fb3e343fc8cdc9358a913182445210b /src/cargopacket.h | |
parent | a2ff96d6828bd32f7beb461bfb902880bf46ef75 (diff) | |
download | openttd-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.h | 134 |
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 |