00001
00002
00003
00004
00005
00006
00007
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 "cargo_type.h"
00019 #include "vehicle_type.h"
00020 #include "order_type.h"
00021 #include "cargotype.h"
00022 #include <list>
00023 #include <map>
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 CargoList;
00035 extern const struct SaveLoad *GetCargoPacketDesc();
00036
00040 struct CargoPacket : CargoPacketPool::PoolItem<&_cargopacket_pool> {
00041 private:
00042 Money feeder_share;
00043 uint16 count;
00044 byte days_in_transit;
00045 SourceTypeByte source_type;
00046 SourceID source_id;
00047 StationID source;
00048 TileIndex source_xy;
00049 TileIndex loaded_at_xy;
00050 TileIndex dest_xy;
00051 SourceID dest_id;
00052 SourceTypeByte dest_type;
00053 byte flags;
00054 OrderID next_order;
00055 StationID next_station;
00056
00058 template <class Tinst> friend class CargoList;
00059 friend class VehicleCargoList;
00060 friend class StationCargoList;
00062 friend const struct SaveLoad *GetCargoPacketDesc();
00063 friend bool CargodestModeChanged(int32 p1);
00064 public:
00066 static const uint16 MAX_COUNT = UINT16_MAX;
00067
00068 CargoPacket();
00069 CargoPacket(StationID source, TileIndex source_xy, uint16 count, SourceType source_type, SourceID source_id, TileIndex dest_xy = INVALID_TILE, SourceType dest_type = ST_INDUSTRY, SourceID dest_id = INVALID_SOURCE, OrderID next_order = INVALID_ORDER, StationID next_station = INVALID_STATION, byte flags = 0);
00070 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, TileIndex dest_xy = INVALID_TILE, SourceType dest_type = ST_INDUSTRY, SourceID dest_id = INVALID_SOURCE, OrderID next_order = INVALID_ORDER, StationID next_station = INVALID_STATION, byte flags = 0);
00071
00073 ~CargoPacket() { }
00074
00075 CargoPacket *Split(uint new_size);
00076 void Merge(CargoPacket *cp);
00077
00082 FORCEINLINE uint16 Count() const
00083 {
00084 return this->count;
00085 }
00086
00092 FORCEINLINE Money FeederShare() const
00093 {
00094 return this->feeder_share;
00095 }
00096
00103 FORCEINLINE byte DaysInTransit() const
00104 {
00105 return this->days_in_transit;
00106 }
00107
00112 FORCEINLINE SourceType SourceSubsidyType() const
00113 {
00114 return this->source_type;
00115 }
00116
00121 FORCEINLINE SourceID SourceSubsidyID() const
00122 {
00123 return this->source_id;
00124 }
00125
00130 FORCEINLINE SourceID SourceStation() const
00131 {
00132 return this->source;
00133 }
00134
00139 FORCEINLINE TileIndex SourceStationXY() const
00140 {
00141 return this->source_xy;
00142 }
00143
00148 FORCEINLINE TileIndex LoadedAtXY() const
00149 {
00150 return this->loaded_at_xy;
00151 }
00152
00157 FORCEINLINE TileIndex DestinationXY() const
00158 {
00159 return this->dest_xy;
00160 }
00161
00166 FORCEINLINE SourceID DestinationID() const
00167 {
00168 return this->dest_id;
00169 }
00170
00175 FORCEINLINE SourceType DestinationType() const
00176 {
00177 return this->dest_type;
00178 }
00179
00184 FORCEINLINE byte Flags() const
00185 {
00186 return this->flags;
00187 }
00188
00193 FORCEINLINE OrderID NextHop() const
00194 {
00195 return this->next_order;
00196 }
00197
00202 FORCEINLINE StationID NextStation() const
00203 {
00204 return this->next_station;
00205 }
00206
00207 static void InvalidateAllFrom(SourceType src_type, SourceID src);
00208 static void InvalidateAllFrom(StationID sid);
00209 static void AfterLoad();
00210 };
00211
00217 #define FOR_ALL_CARGOPACKETS_FROM(var, start) FOR_ALL_ITEMS_FROM(CargoPacket, cargopacket_index, var, start)
00218
00223 #define FOR_ALL_CARGOPACKETS(var) FOR_ALL_CARGOPACKETS_FROM(var, 0)
00224
00229 template <class Tinst>
00230 class CargoList {
00231 public:
00233 typedef std::list<CargoPacket *> List;
00235 typedef List::iterator Iterator;
00237 typedef List::const_iterator ConstIterator;
00238
00240 enum MoveToAction {
00241 MTA_FINAL_DELIVERY,
00242 MTA_CARGO_LOAD,
00243 MTA_TRANSFER,
00244 MTA_UNLOAD,
00245 MTA_NO_ACTION,
00246 };
00247
00248 friend bool CargodestModeChanged(int32 p1);
00249
00250 protected:
00251 uint count;
00252 uint cargo_days_in_transit;
00253
00254 List packets;
00255
00256 void AddToCache(const CargoPacket *cp);
00257
00258 void RemoveFromCache(const CargoPacket *cp);
00259
00260 void RemoveFromCacheLocal(const CargoPacket *cp, uint amount) {}
00261
00262 virtual bool UpdateCargoNextHop(CargoPacket *cp, Station *st, CargoID cid)
00263 {
00264 return true;
00265 }
00266
00267 public:
00269 CargoList() {}
00270
00271 virtual ~CargoList();
00272
00273 void OnCleanPool();
00274
00279 FORCEINLINE const List *Packets() const
00280 {
00281 return &this->packets;
00282 }
00283
00288 FORCEINLINE bool Empty() const
00289 {
00290 return this->count == 0;
00291 }
00292
00297 FORCEINLINE uint Count() const
00298 {
00299 return this->count;
00300 }
00301
00306 FORCEINLINE StationID Source() const
00307 {
00308 return this->Empty() ? INVALID_STATION : this->packets.front()->source;
00309 }
00310
00315 FORCEINLINE uint DaysInTransit() const
00316 {
00317 return this->count == 0 ? 0 : this->cargo_days_in_transit / this->count;
00318 }
00319
00320
00321 void Append(CargoPacket *cp);
00322 void Truncate(uint max_remaining);
00323
00324 template <class Tother_inst>
00325 bool MoveTo(Tother_inst *dest, uint count, MoveToAction mta, CargoPayment *payment, StationID st = INVALID_STATION, OrderID cur_order = INVALID_ORDER, CargoID cid = INVALID_CARGO, bool *did_transfer = NULL);
00326
00327 void InvalidateCache();
00328 };
00329
00333 class VehicleCargoList : public CargoList<VehicleCargoList> {
00334 protected:
00336 typedef CargoList<VehicleCargoList> Parent;
00337
00338 Money feeder_share;
00339
00340 void AddToCache(const CargoPacket *cp);
00341 void RemoveFromCache(const CargoPacket *cp);
00342
00343 public:
00345 friend class CargoList<VehicleCargoList>;
00347 friend const struct SaveLoad *GetVehicleDescription(VehicleType vt);
00348
00353 FORCEINLINE Money FeederShare() const
00354 {
00355 return this->feeder_share;
00356 }
00357
00358 void AgeCargo();
00359
00360 void InvalidateCache();
00361
00362 void InvalidateNextStation();
00363
00371 static bool AreMergable(const CargoPacket *cp1, const CargoPacket *cp2)
00372 {
00373 return cp1->source_xy == cp2->source_xy &&
00374 cp1->days_in_transit == cp2->days_in_transit &&
00375 cp1->source_type == cp2->source_type &&
00376 cp1->source_id == cp2->source_id &&
00377 cp1->loaded_at_xy == cp2->loaded_at_xy &&
00378 cp1->dest_xy == cp2->dest_xy &&
00379 cp1->dest_type == cp2->dest_type &&
00380 cp1->dest_id == cp2->dest_id &&
00381 cp1->next_order == cp2->next_order &&
00382 cp1->next_station == cp2->next_station &&
00383 cp1->flags == cp2->flags;
00384 }
00385 };
00386
00390 class StationCargoList : public CargoList<StationCargoList> {
00391 public:
00392 typedef std::map<OrderID, int> OrderMap;
00393
00394 protected:
00396 typedef CargoList<StationCargoList> Parent;
00397
00398 OrderMap order_cache;
00399 int32 next_start;
00400
00401 void AddToCache(const CargoPacket *cp);
00402 void RemoveFromCache(const CargoPacket *cp);
00403 void RemoveFromCacheLocal(const CargoPacket *cp, uint amount);
00404
00405 bool UpdateCargoNextHop(CargoPacket *cp, Station *st, CargoID cid);
00406
00407 public:
00409 friend class CargoList<StationCargoList>;
00411 friend const struct SaveLoad *GetGoodsDesc();
00412
00413 void InvalidateCache();
00414
00415 void UpdateCargoNextHop(Station *st, CargoID cid);
00416
00421 const OrderMap& CountForNextHop() const
00422 {
00423 return this->order_cache;
00424 }
00425
00431 int CountForNextHop(OrderID order) const
00432 {
00433 OrderMap::const_iterator i = this->order_cache.find(order);
00434 return i != this->order_cache.end() ? i->second : 0;
00435 }
00436
00444 static bool AreMergable(const CargoPacket *cp1, const CargoPacket *cp2)
00445 {
00446 return cp1->source_xy == cp2->source_xy &&
00447 cp1->days_in_transit == cp2->days_in_transit &&
00448 cp1->source_type == cp2->source_type &&
00449 cp1->source_id == cp2->source_id &&
00450 cp1->dest_xy == cp2->dest_xy &&
00451 cp1->dest_type == cp2->dest_type &&
00452 cp1->dest_id == cp2->dest_id &&
00453 cp1->next_order == cp2->next_order &&
00454 cp1->next_station == cp2->next_station &&
00455 cp1->flags == cp2->flags;
00456 }
00457
00458 static void InvalidateAllTo(OrderID order, StationID st_unload);
00459 static void InvalidateAllTo(SourceType type, SourceID dest);
00460 };
00461
00462 #endif