74 feeder_share(feeder_share),
76 days_in_transit(days_in_transit),
80 loaded_at_xy(loaded_at_xy)
98 this->
count -= new_size;
119 assert(count < this->count);
121 this->count -=
count;
158 template <
class Tinst,
class Tcont>
161 for (
Iterator it(this->packets.begin()); it != this->packets.end(); ++it) {
170 template <
class Tinst,
class Tcont>
173 this->packets.clear();
182 template <
class Tinst,
class Tcont>
185 assert(count <= cp->count);
186 this->count -=
count;
195 template <
class Tinst,
class Tcont>
203 template <
class Tinst,
class Tcont>
207 this->cargo_days_in_transit = 0;
209 for (
ConstIterator it(this->packets.begin()); it != this->packets.end(); it++) {
210 static_cast<Tinst *
>(
this)->AddToCache(*it);
221 template <
class Tinst,
class Tcont>
224 if (Tinst::AreMergable(icp, cp) &&
257 assert(action == MTA_LOAD ||
258 (action == MTA_KEEP && this->action_counts[MTA_LOAD] == 0));
259 this->AddToMeta(cp, action);
262 this->packets.push_back(cp);
266 uint sum = cp->
count;
267 for (
ReverseIterator it(this->packets.rbegin()); it != this->packets.rend(); it++) {
271 if (sum >= this->action_counts[action]) {
272 this->packets.push_back(cp);
288 template<
class Taction>
292 while (it != this->packets.end() && action.MaxMove() > 0) {
295 it = this->packets.erase(it);
310 template<
class Taction>
313 if (this->packets.empty())
return;
314 Iterator it(--(this->packets.end()));
315 Iterator begin(this->packets.begin());
316 while (action.MaxMove() > 0) {
320 this->packets.erase(it--);
322 this->packets.erase(it);
340 this->Parent::RemoveFromCache(cp, count);
351 this->Parent::AddToCache(cp);
362 assert(count <= this->action_counts[action]);
363 this->AssertCountConsistency();
364 this->RemoveFromCache(cp, count);
365 this->action_counts[action] -=
count;
366 this->AssertCountConsistency();
376 this->AssertCountConsistency();
377 this->AddToCache(cp);
378 this->action_counts[action] += cp->
count;
379 this->AssertCountConsistency();
387 for (
ConstIterator it(this->packets.begin()); it != this->packets.end(); it++) {
393 this->cargo_days_in_transit += cp->
count;
407 for (
Iterator it = this->packets.begin(); sum < this->action_counts[MTA_TRANSFER]; ++it) {
426 if (cargo_next == INVALID_STATION) {
427 return (accepted && cp->
source != current_station) ? MTA_DELIVER : MTA_KEEP;
428 }
else if (cargo_next == current_station) {
430 }
else if (next_station.
Contains(cargo_next)) {
452 this->AssertCountConsistency();
453 assert(this->action_counts[MTA_LOAD] == 0);
454 this->action_counts[MTA_TRANSFER] = this->action_counts[MTA_DELIVER] = this->action_counts[MTA_KEEP] = 0;
455 Iterator deliver = this->packets.end();
456 Iterator it = this->packets.begin();
460 bool force_unload = (order_flags &
OUFB_UNLOAD) != 0;
462 assert(this->
count > 0 || it == this->packets.end());
463 while (sum < this->
count) {
466 this->packets.erase(it++);
467 StationID cargo_next = INVALID_STATION;
468 MoveToAction action = MTA_LOAD;
471 }
else if (force_unload && accepted && cp->
source != current_station) {
472 action = MTA_DELIVER;
473 }
else if (force_transfer) {
474 action = MTA_TRANSFER;
477 FlowStatMap::const_iterator flow_it(ge->
flows.find(cp->
source));
478 if (flow_it == ge->
flows.end()) {
479 cargo_next = INVALID_STATION;
481 FlowStat new_shares = flow_it->second;
488 cargo_next = INVALID_STATION;
490 cargo_next = new_shares.
GetVia();
496 if (cp->
source == INVALID_STATION && !ge->
flows.empty()) {
499 bool restricted =
false;
500 FlowStatMap::const_iterator flow_it(ge->
flows.find(cp->
source));
501 if (flow_it == ge->
flows.end()) {
502 cargo_next = INVALID_STATION;
504 cargo_next = flow_it->second.GetViaWithRestricted(restricted);
507 if (restricted && action == MTA_TRANSFER) {
510 cargo_next = flow_it->second.GetVia();
517 this->packets.push_back(cp);
518 if (deliver == this->packets.end()) --deliver;
521 this->packets.insert(deliver, cp);
524 this->packets.push_front(cp);
534 this->action_counts[action] += cp->
count;
537 this->AssertCountConsistency();
538 return this->action_counts[MTA_DELIVER] > 0 || this->action_counts[MTA_TRANSFER] > 0;
545 this->Parent::InvalidateCache();
560 template<VehicleCargoList::MoveToAction Tfrom, VehicleCargoList::MoveToAction Tto>
563 assert_tcompile(Tfrom != MTA_TRANSFER && Tto != MTA_TRANSFER);
564 assert_tcompile(Tfrom - Tto == 1 || Tto - Tfrom == 1);
565 max_move =
min(this->action_counts[Tfrom], max_move);
566 this->action_counts[Tfrom] -= max_move;
567 this->action_counts[Tto] += max_move;
579 uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_TRANSFER>(uint max_move, TileOrStationID
next_station)
581 max_move =
min(this->action_counts[MTA_DELIVER], max_move);
584 for (Iterator it(this->packets.begin()); sum < this->action_counts[MTA_TRANSFER] + max_move;) {
587 if (sum <= this->action_counts[MTA_TRANSFER])
continue;
588 if (sum > this->action_counts[MTA_TRANSFER] + max_move) {
589 CargoPacket *cp_split = cp->
Split(sum - this->action_counts[MTA_TRANSFER] + max_move);
590 sum -= cp_split->
Count();
591 this->packets.insert(it, cp_split);
596 this->action_counts[MTA_DELIVER] -= max_move;
597 this->action_counts[MTA_TRANSFER] += max_move;
610 max_move =
min(this->action_counts[MTA_LOAD], max_move);
611 this->PopCargo(
CargoReturn(
this, dest, max_move, next));
623 max_move =
min(this->
count, max_move);
624 this->PopCargo(
CargoShift(
this, dest, max_move));
639 if (this->action_counts[MTA_TRANSFER] > 0) {
640 uint move =
min(this->action_counts[MTA_TRANSFER], max_move);
644 if (this->action_counts[MTA_TRANSFER] == 0 && this->action_counts[MTA_DELIVER] > 0 && moved < max_move) {
645 uint move =
min(this->action_counts[MTA_DELIVER], max_move - moved);
660 max_move =
min(this->
count, max_move);
675 max_move =
min(this->action_counts[MTA_TRANSFER], max_move);
697 this->AddToCache(cp);
699 StationCargoPacketMap::List &list = this->packets[next];
700 for (StationCargoPacketMap::List::reverse_iterator it(list.rbegin());
701 it != list.rend(); it++) {
721 template <
class Taction>
724 std::pair<Iterator, Iterator> range(this->packets.equal_range(next));
725 for (
Iterator it(range.first); it != range.second && it.GetKey() == next;) {
726 if (action.MaxMove() == 0)
return false;
729 it = this->packets.erase(it);
751 template <
class Taction>
754 uint max_move = action.MaxMove();
756 this->ShiftCargo(action, next.
Pop());
757 if (action.MaxMove() == 0)
break;
759 if (include_invalid && action.MaxMove() > 0) {
760 this->ShiftCargo(action, INVALID_STATION);
762 return max_move - action.MaxMove();
775 max_move =
min(max_move, this->
count);
776 uint prev_count = this->
count;
779 bool do_count = cargo_per_source != NULL;
780 while (max_move > moved) {
781 for (
Iterator it(this->packets.begin()); it != this->packets.end();) {
783 if (prev_count > max_move &&
RandomRange(prev_count) < prev_count - max_move) {
784 if (do_count && loop == 0) {
790 uint diff = max_move - moved;
791 if (cp->
count > diff) {
793 this->RemoveFromCache(cp, diff);
798 if (do_count) (*cargo_per_source)[cp->
source] -= diff;
801 if (do_count) (*cargo_per_source)[cp->
source] += cp->
count;
805 it = this->packets.erase(it);
806 if (do_count && loop > 0) {
810 this->RemoveFromCache(cp, cp->
count);
829 return this->ShiftCargo(
CargoReservation(
this, dest, max_move, load_place), next_station,
true);
848 this->reserved_count -= move;
852 return this->ShiftCargo(
CargoLoad(
this, dest, max_move, load_place), next_station,
true);
866 return this->ShiftCargo(
StationCargoReroute(
this, dest, max_move, avoid, avoid2, ge), avoid,
false);
874 template uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_KEEP>(uint, TileOrStationID);
Action of rerouting cargo in a station.
void AddFeederShare(Money new_share)
Adds some feeder share to the packet.
CargoPacketList ::reverse_iterator ReverseIterator
The reverse iterator for our container.
Minimal stack that uses a pool to avoid pointers.
void Append(CargoPacket *cp, MoveToAction action=MTA_KEEP)
Appends the given cargo packet.
SourceTypeByte source_type
Type of source_id.
CargoPacketPool _cargopacket_pool("CargoPacket")
The actual pool with cargo packets.
CargoList that is used for stations.
void AddToCache(const CargoPacket *cp)
Update the cache to reflect adding of this packet.
void PopCargo(Taction action)
Pops cargo from the back of the packet list and applies some action to it.
void AddToMeta(const CargoPacket *cp, MoveToAction action)
Adds a packet to the metadata.
uint Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
Routes packets with station "avoid" as next hop to a different place.
CargoPacket()
Create a new packet for savegame loading.
void SetTransferLoadPlace(TileIndex xy)
Sets loaded_at_xy to the current station for all cargo to be transfered.
uint Truncate(uint max_move=UINT_MAX)
Truncates the cargo in this list to the given amount.
Money FeederShare() const
Gets the amount of money already paid to earlier vehicles in the feeder chain.
Action of shifting cargo from one vehicle to another.
Stores station stats for a single cargo.
Action of rerouting cargo staged for transfer in a vehicle.
static void InvalidateAllFrom(SourceType src_type, SourceID src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
uint Return(uint max_move, StationCargoList *dest, StationID next_station)
Returns reserved cargo to the station and removes it from the cache.
uint Load(uint max_move, VehicleCargoList *dest, TileIndex load_place, StationIDStack next)
Loads cargo onto a vehicle.
static uint32 RandomRange(uint32 limit)
Pick a random number between 0 and limit - 1, inclusive.
static const SourceID INVALID_SOURCE
Invalid/unknown index of source.
uint16 count
The amount of cargo in this packet.
void RemoveFromCache(const CargoPacket *cp, uint count)
Update the cached values to reflect the removal of this packet or part of it.
void OnCleanPool()
Empty the cargo list, but don't free the cargo packets; the cargo packets are cleaned by CargoPacket'...
Pseudo random number generator.
~CargoList()
Destroy the cargolist ("frees" all cargo packets).
bool IsEmpty() const
Check if the stack is empty.
Some methods of Pool are placed here in order to reduce compilation time and binary size...
void ShiftCargo(Taction action)
Shifts cargo from the front of the packet list and applies some action to it.
SourceID source_id
Index of source, INVALID_SOURCE if unknown/invalid.
Actions to be applied to cargo packets.
StationID GetVia() const
Get a station a package can be routed to.
uint Reassign(uint max_move, TileOrStationID update=INVALID_TILE)
Moves some cargo from one designation to another.
Money PayTransfer(const CargoPacket *cp, uint count)
Handle payment for transfer of the given cargo packet.
Container for cargo from the same location and time.
Definition of base types and functions in a cross-platform compatible way.
uint Reroute(uint max_move, VehicleCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
Routes packets with station "avoid" as next hop to a different place.
A number of safeguards to prevent using unsafe methods.
TileOrStationID next_station
Station where the cargo wants to go next.
Titem Pop()
Pop an item from the stack.
bool Contains(const Titem &item) const
Check if the given item is contained in the stack.
uint ActionCount(MoveToAction action) const
Returns the amount of cargo designated for a given purpose.
void InvalidateCache()
Invalidates the cached data and rebuild it.
CargoPacket * Split(uint new_size)
Split this packet in two and return the split off part.
uint Reserve(uint max_move, VehicleCargoList *dest, TileIndex load_place, StationIDStack next)
Reserves cargo for loading onto the vehicle.
static T min(const T a, const T b)
Returns the minimum of two values.
Helper class to perform the cargo payment.
Action of transferring cargo from a vehicle to a station.
#define FOR_ALL_CARGOPACKETS(var)
Iterate over all valid cargo packets from the begin of the pool.
MoveToAction
Kind of actions that could be done with packets on move.
Transfer all cargo onto the platform.
Action of reserving cargo from a station to be loaded onto a vehicle.
uint Truncate(uint max_move=UINT_MAX, StationCargoAmountMap *cargo_per_source=NULL)
Truncates where each destination loses roughly the same percentage of its cargo.
Base class for all pools.
FlowStatMap flows
Planned flows through this station.
SourceType
Types of cargo source and destination.
void ChangeShare(StationID st, int flow)
Change share for specified station.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
Keep the cargo in the vehicle.
bool ShiftCargo(Taction &action, StationID next)
Shifts cargo from the front of the packet list for a specific station and applies some action to it...
CargoList that is used for vehicles.
StationCargoPacketMap ::const_iterator ConstIterator
The const iterator for our container.
uint32 TileIndex
The index/ID of a Tile.
Action of returning previously reserved cargo from the vehicle to the station.
static MoveToAction ChooseAction(const CargoPacket *cp, StationID cargo_next, StationID current_station, bool accepted, StationIDStack next_station)
Choose action to be performed with the given cargo packet.
Source/destination is an industry.
uint16 SourceID
Contains either industry ID, town ID or company ID (or INVALID_SOURCE)
const SharesMap * GetShares() const
Get the actual shares as a const pointer so that they can be iterated over.
TileIndex xy
Base tile of the station.
void AgeCargo()
Ages the all cargo in this list.
StationID source
The station where the cargo came from first.
uint Shift(uint max_move, VehicleCargoList *dest)
Shifts cargo between two vehicles.
Totally no unloading will be done.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() ...
Flow statistics telling how much flow should be sent along a link.
uint Unload(uint max_move, StationCargoList *dest, CargoPayment *payment)
Unloads cargo at the given station.
void Reduce(uint count)
Reduce the packet by the given amount and remove the feeder share.
Base classes related to the economy.
void RemoveFromMeta(const CargoPacket *cp, MoveToAction action, uint count)
Removes a packet or part of it from the metadata.
Load the cargo from the station.
bool Stage(bool accepted, StationID current_station, StationIDStack next_station, uint8 order_flags, const GoodsEntry *ge, CargoPayment *payment)
Stages cargo for unloading.
void Merge(CargoPacket *cp)
Merge another packet into this one.
uint16 Count() const
Gets the number of 'items' in this packet.
static const uint16 MAX_COUNT
Maximum number of items in a single cargo packet.
Money feeder_share
Value of feeder pickup to be paid for on delivery of cargo.
Action of final delivery of cargo.
void InvalidateCache()
Invalidates the cached data and rebuilds it.
TileOrStationID loaded_at_xy
Location where this cargo has been loaded into the vehicle.
TileIndex source_xy
The origin of the cargo (first station in feeder chain).
void RemoveFromCache(const CargoPacket *cp, uint count)
Update the cached values to reflect the removal of this packet or part of it.
Force unloading all cargo onto the platform, possibly not getting paid.
Action of loading cargo from a station onto a vehicle.
StationCargoPacketMap ::iterator Iterator
The iterator for our container.
Base classes/functions for stations.
void AddToCache(const CargoPacket *cp)
Update the cache to reflect adding of this packet.
byte days_in_transit
Amount of days this packet has been in transit.
void Append(CargoPacket *cp, StationID next)
Appends the given cargo packet to the range of packets with the same next station.
static bool TryMerge(CargoPacket *cp, CargoPacket *icp)
Tries to merge the second packet into the first and return if that was successful.