cargopacket.h

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #ifndef CARGOPACKET_H
00013 #define CARGOPACKET_H
00014 
00015 #include "core/pool_type.hpp"
00016 #include "economy_type.h"
00017 #include "station_type.h"
00018 #include "order_type.h"
00019 #include "cargo_type.h"
00020 #include "cargotype.h"
00021 #include "vehicle_type.h"
00022 #include "core/multimap.hpp"
00023 #include <list>
00024 
00026 typedef uint32 CargoPacketID;
00027 struct CargoPacket;
00028 
00030 typedef Pool<CargoPacket, CargoPacketID, 1024, 0xFFF000, PT_NORMAL, true, false> CargoPacketPool;
00032 extern CargoPacketPool _cargopacket_pool;
00033 
00034 template <class Tinst, class Tcont> class CargoList;
00035 class StationCargoList; // forward-declare, so we can use it in VehicleCargoList::Unreserve
00036 class VehicleCargoList; // forward-declare, so we can use it in CargoList::MovePacket
00037 extern const struct SaveLoad *GetCargoPacketDesc();
00038 
00042 struct CargoPacket : CargoPacketPool::PoolItem<&_cargopacket_pool> {
00043 private:
00044   Money feeder_share;         
00045   uint16 count;               
00046   byte days_in_transit;       
00047   SourceTypeByte source_type; 
00048   SourceID source_id;         
00049   StationID source;           
00050   TileIndex source_xy;        
00051   TileIndex loaded_at_xy;     
00052 
00054   template <class Tinst, class Tcont> friend class CargoList;
00055   friend class VehicleCargoList;
00056   friend class StationCargoList;
00058   friend const struct SaveLoad *GetCargoPacketDesc();
00059 public:
00061   static const uint16 MAX_COUNT = UINT16_MAX;
00062 
00063   CargoPacket();
00064   CargoPacket(StationID source, TileIndex source_xy, uint16 count, SourceType source_type, SourceID source_id);
00065   CargoPacket(uint16 count, byte days_in_transit, StationID source, TileIndex source_xy, TileIndex loaded_at_xy, Money feeder_share = 0, SourceType source_type = ST_INDUSTRY, SourceID source_id = INVALID_SOURCE);
00066 
00068   ~CargoPacket() { }
00069 
00070   CargoPacket *Split(uint new_size);
00071   void Merge(CargoPacket *cp);
00072 
00077   FORCEINLINE uint16 Count() const
00078   {
00079     return this->count;
00080   }
00081 
00087   FORCEINLINE Money FeederShare() const
00088   {
00089     return this->feeder_share;
00090   }
00091 
00098   FORCEINLINE byte DaysInTransit() const
00099   {
00100     return this->days_in_transit;
00101   }
00102 
00107   FORCEINLINE SourceType SourceSubsidyType() const
00108   {
00109     return this->source_type;
00110   }
00111 
00116   FORCEINLINE SourceID SourceSubsidyID() const
00117   {
00118     return this->source_id;
00119   }
00120 
00125   FORCEINLINE SourceID SourceStation() const
00126   {
00127     return this->source;
00128   }
00129 
00134   FORCEINLINE TileIndex SourceStationXY() const
00135   {
00136     return this->source_xy;
00137   }
00138 
00143   FORCEINLINE TileIndex LoadedAtXY() const
00144   {
00145     return this->loaded_at_xy;
00146   }
00147 
00148   static void InvalidateAllFrom(SourceType src_type, SourceID src);
00149   static void InvalidateAllFrom(StationID sid);
00150   static void AfterLoad();
00151 };
00152 
00158 #define FOR_ALL_CARGOPACKETS_FROM(var, start) FOR_ALL_ITEMS_FROM(CargoPacket, cargopacket_index, var, start)
00159 
00164 #define FOR_ALL_CARGOPACKETS(var) FOR_ALL_CARGOPACKETS_FROM(var, 0)
00165 
00167 enum UnloadType {
00168   UL_KEEP     = 0,      
00169   UL_DELIVER  = 1 << 0, 
00170   UL_TRANSFER = 1 << 1, 
00171   UL_ACCEPTED = 1 << 2, 
00172 };
00173 
00178 template <class Tinst, class Tcont>
00179 class CargoList {
00180 public:
00182   typedef typename Tcont::iterator Iterator;
00184   typedef typename Tcont::const_iterator ConstIterator;
00186   typedef typename Tcont::reverse_iterator ReverseIterator;
00188   typedef typename Tcont::const_reverse_iterator ConstReverseIterator;
00189 
00190 protected:
00191   uint count;                 
00192   uint cargo_days_in_transit; 
00193 
00194   Tcont packets;              
00195 
00196   void AddToCache(const CargoPacket *cp);
00197 
00198   void RemoveFromCache(const CargoPacket *cp);
00199 
00200   CargoPacket *RemovePacket(Iterator &it, uint cap, TileIndex load_place = INVALID_TILE);
00201 
00202   uint MovePacket(StationCargoList *dest, StationID next, Iterator &it, uint cap);
00203 
00204   uint MovePacket(VehicleCargoList *dest, Iterator &it, uint cap, TileIndex load_place = INVALID_TILE, bool reserved = false);
00205 
00206 public:
00208   CargoList() {}
00209 
00210   ~CargoList();
00211 
00212   void OnCleanPool();
00213 
00218   FORCEINLINE const Tcont *Packets() const
00219   {
00220     return &this->packets;
00221   }
00222 
00227   FORCEINLINE bool Empty() const
00228   {
00229     return this->count == 0;
00230   }
00231 
00236   FORCEINLINE uint Count() const
00237   {
00238     return this->count;
00239   }
00240 
00245   FORCEINLINE uint DaysInTransit() const
00246   {
00247     return this->count == 0 ? 0 : this->cargo_days_in_transit / this->count;
00248   }
00249 
00250   void Truncate(uint max_remaining);
00251 
00252   void InvalidateCache();
00253 };
00254 
00255 typedef std::list<CargoPacket *> CargoPacketList;
00256 
00260 class VehicleCargoList : public CargoList<VehicleCargoList, CargoPacketList> {
00261 protected:
00262   uint TransferPacket(Iterator &c, uint remaining_unload, StationCargoList *dest, CargoPayment *payment, StationID next);
00263   uint DeliverPacket(Iterator &c, uint remaining_unload, CargoPayment *payment);
00264   uint KeepPacket(Iterator &c);
00265 
00267   typedef CargoList<VehicleCargoList, CargoPacketList> Parent;
00268 
00269   CargoPacketList reserved; 
00270   Money feeder_share;       
00271   uint reserved_count;      
00272 
00273   void AddToCache(const CargoPacket *cp);
00274   void RemoveFromCache(const CargoPacket *cp);
00275 
00276 public:
00278   friend class StationCargoList;
00280   friend class CargoList<VehicleCargoList, CargoPacketList>;
00282   friend const struct SaveLoad *GetVehicleDescription(VehicleType vt);
00283 
00284   ~VehicleCargoList();
00285 
00286   void OnCleanPool();
00287 
00292   FORCEINLINE Money FeederShare() const
00293   {
00294     return this->feeder_share;
00295   }
00296 
00297   void Append(CargoPacket *cp, bool update_cache = true);
00298 
00304   FORCEINLINE uint OnboardCount() const
00305   {
00306     return this->count - this->reserved_count;
00307   }
00308 
00313   FORCEINLINE uint ReservedCount() const
00314   {
00315     return this->reserved_count;
00316   }
00317 
00322   FORCEINLINE const CargoPacketList *Reserved() const
00323   {
00324     return &this->reserved;
00325   }
00326 
00334   FORCEINLINE StationID Source() const
00335   {
00336     if (this->Empty()) {
00337       return INVALID_STATION;
00338     } else if (this->packets.empty()) {
00339       return this->reserved.front()->source;
00340     } else {
00341       return this->packets.front()->source;
00342     }
00343   }
00344 
00345   void Reserve(CargoPacket *cp);
00346 
00347   void Unreserve(StationID next, StationCargoList *dest);
00348 
00349   uint LoadReserved(uint count);
00350 
00351   void SwapReserved();
00352 
00353   void AgeCargo();
00354 
00355   void InvalidateCache();
00356 
00357   uint MoveTo(VehicleCargoList *dest, uint cap);
00358 
00366   static bool AreMergable(const CargoPacket *cp1, const CargoPacket *cp2)
00367   {
00368     return cp1->source_xy    == cp2->source_xy &&
00369         cp1->days_in_transit == cp2->days_in_transit &&
00370         cp1->source_type     == cp2->source_type &&
00371         cp1->source_id       == cp2->source_id &&
00372         cp1->loaded_at_xy    == cp2->loaded_at_xy;
00373   }
00374 };
00375 
00376 typedef MultiMap<StationID, CargoPacket *> StationCargoPacketMap;
00377 typedef std::map<StationID, uint> StationCargoAmountMap;
00378 
00382 class StationCargoList : public CargoList<StationCargoList, StationCargoPacketMap> {
00383 public:
00385   friend class CargoList<StationCargoList, StationCargoPacketMap>;
00387   friend const struct SaveLoad *GetGoodsDesc();
00388 
00389   StationCargoList() : station(NULL), cargo(INVALID_CARGO) {}
00390 
00398   static bool AreMergable(const CargoPacket *cp1, const CargoPacket *cp2)
00399   {
00400     return cp1->source_xy    == cp2->source_xy &&
00401         cp1->days_in_transit == cp2->days_in_transit &&
00402         cp1->source_type     == cp2->source_type &&
00403         cp1->source_id       == cp2->source_id;
00404   }
00405 
00406   uint TakeFrom(VehicleCargoList *source, uint max_unload, OrderUnloadFlags flags, StationID next_station, bool has_stopped, CargoPayment *payment);
00407 
00408   uint MoveTo(VehicleCargoList *dest, uint cap, StationID next_station, bool reserve = false);
00409 
00410   void Append(StationID next, CargoPacket *cp);
00411 
00412   void RerouteStalePackets(StationID to);
00413 
00414   void CountAndTruncate(uint max_remaining, StationCargoAmountMap &cargo_per_source);
00415 
00420   FORCEINLINE StationID Source() const
00421   {
00422     return this->Empty() ? INVALID_STATION : this->packets.begin()->second.front()->source;
00423   }
00424 
00425   void AssignTo(Station *station, CargoID cargo);
00426 
00427   static void InvalidateAllFrom(SourceType src_type, SourceID src);
00428 
00429 protected:
00430   Station *station; 
00431   CargoID cargo;    
00432 
00433   byte GetUnloadFlags(OrderUnloadFlags order_flags);
00434 
00435   UnloadType WillUnloadOld(byte flags, StationID source);
00436   UnloadType WillUnloadCargoDist(byte flags, StationID next_station, StationID via, StationID source);
00437 
00438   uint MovePackets(VehicleCargoList *dest, uint cap, Iterator begin, Iterator end, bool reserve);
00439 };
00440 
00441 #endif /* CARGOPACKET_H */

Generated on Fri May 27 04:19:40 2011 for OpenTTD by  doxygen 1.6.1