Changeset - r20419:493e8735e0cc
[Not reviewed]
master
0 5 0
fonsinchen - 11 years ago 2013-06-23 08:28:53
fonsinchen@openttd.org
(svn r25434) -Fix: reroute cargo staged for unloading if a link breaks
5 files changed with 82 insertions and 7 deletions:
0 comments (0 inline, 0 general)
src/cargoaction.cpp
Show inline comments
 
@@ -189,13 +189,13 @@ bool CargoShift::operator()(CargoPacket 
 

	
 
/**
 
 * Reroutes some cargo from one Station sublist to another.
 
 * @param cp Packet to be rerouted.
 
 * @return True if the packet was completely rerouted, false if part of it was.
 
 */
 
bool CargoReroute::operator()(CargoPacket *cp)
 
bool StationCargoReroute::operator()(CargoPacket *cp)
 
{
 
	CargoPacket *cp_new = this->Preprocess(cp);
 
	if (cp_new == NULL) cp_new = cp;
 
	StationID next = this->ge->GetVia(cp_new->SourceStation(), this->avoid, this->avoid2);
 
	assert(next != this->avoid && next != this->avoid2);
 
	if (this->source != this->destination) {
 
@@ -207,10 +207,33 @@ bool CargoReroute::operator()(CargoPacke
 
	 * this might insert the packet between range.first and range.second (which might be end())
 
	 * This is why we check for GetKey above to avoid infinite loops. */
 
	this->destination->packets.Insert(next, cp_new);
 
	return cp_new == cp;
 
}
 

	
 
/**
 
 * Reroutes some cargo in a VehicleCargoList.
 
 * @param cp Packet to be rerouted.
 
 * @return True if the packet was completely rerouted, false if part of it was.
 
 */
 
bool VehicleCargoReroute::operator()(CargoPacket *cp)
 
{
 
	CargoPacket *cp_new = this->Preprocess(cp);
 
	if (cp_new == NULL) cp_new = cp;
 
	if (cp_new->NextStation() == this->avoid || cp_new->NextStation() == this->avoid2) {
 
		cp->SetNextStation(this->ge->GetVia(cp_new->SourceStation(), this->avoid, this->avoid2));
 
	}
 
	if (this->source != this->destination) {
 
		this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count());
 
		this->source->AddToMeta(cp_new, VehicleCargoList::MTA_TRANSFER);
 
		this->destination->action_counts[VehicleCargoList::MTA_TRANSFER] += cp_new->Count();
 
	}
 

	
 
	/* Legal, as front pushing doesn't invalidate iterators in std::list. */
 
	this->destination->packets.push_front(cp_new);
 
	return cp_new == cp;
 
}
 

	
 
template uint CargoRemoval<VehicleCargoList>::Preprocess(CargoPacket *cp);
 
template uint CargoRemoval<StationCargoList>::Preprocess(CargoPacket *cp);
 
template bool CargoRemoval<VehicleCargoList>::Postprocess(CargoPacket *cp, uint remove);
 
template bool CargoRemoval<StationCargoList>::Postprocess(CargoPacket *cp, uint remove);
src/cargoaction.h
Show inline comments
 
@@ -109,19 +109,38 @@ class CargoShift : public CargoMovement<
 
public:
 
	CargoShift(VehicleCargoList *source, VehicleCargoList *destination, uint max_move) :
 
			CargoMovement<VehicleCargoList, VehicleCargoList>(source, destination, max_move) {}
 
	bool operator()(CargoPacket *cp);
 
};
 

	
 
/** Action of rerouting cargo between different station cargo lists and/or next hops. */
 
class CargoReroute : public CargoMovement<StationCargoList, StationCargoList> {
 
/** Action of rerouting cargo between different cargo lists and/or next hops. */
 
template<class Tlist>
 
class CargoReroute : public CargoMovement<Tlist, Tlist> {
 
protected:
 
	StationID avoid;
 
	StationID avoid2;
 
	const GoodsEntry *ge;
 
public:
 
	CargoReroute(StationCargoList *source, StationCargoList *dest, uint max_move, StationID avoid, StationID avoid2, const GoodsEntry *ge) :
 
			CargoMovement<StationCargoList, StationCargoList>(source, dest, max_move), avoid(avoid), avoid2(avoid2), ge(ge) {}
 
	CargoReroute(Tlist *source, Tlist *dest, uint max_move, StationID avoid, StationID avoid2, const GoodsEntry *ge) :
 
			CargoMovement<Tlist, Tlist>(source, dest, max_move), avoid(avoid), avoid2(avoid2), ge(ge) {}
 
};
 

	
 
/** Action of rerouting cargo in a station. */
 
class StationCargoReroute : public CargoReroute<StationCargoList> {
 
public:
 
	StationCargoReroute(StationCargoList *source, StationCargoList *dest, uint max_move, StationID avoid, StationID avoid2, const GoodsEntry *ge) :
 
				CargoReroute<StationCargoList>(source, dest, max_move, avoid, avoid2, ge) {}
 
	bool operator()(CargoPacket *cp);
 
};
 

	
 
/** Action of rerouting cargo staged for transfer in a vehicle. */
 
class VehicleCargoReroute : public CargoReroute<VehicleCargoList> {
 
public:
 
	VehicleCargoReroute(VehicleCargoList *source, VehicleCargoList *dest, uint max_move, StationID avoid, StationID avoid2, const GoodsEntry *ge) :
 
			CargoReroute<VehicleCargoList>(source, dest, max_move, avoid, avoid2, ge)
 
	{
 
		assert(this->max_move <= source->ActionCount(VehicleCargoList::MTA_TRANSFER));
 
	}
 
	bool operator()(CargoPacket *cp);
 
};
 

	
 
#endif /* CARGOACTION_H */
src/cargopacket.cpp
Show inline comments
 
@@ -577,12 +577,27 @@ uint VehicleCargoList::Truncate(uint max
 
{
 
	max_move = min(this->count, max_move);
 
	this->PopCargo(CargoRemoval<VehicleCargoList>(this, max_move));
 
	return max_move;
 
}
 

	
 
/**
 
 * Routes packets with station "avoid" as next hop to a different place.
 
 * @param max_move Maximum amount of cargo to move.
 
 * @param dest List to prepend the cargo to.
 
 * @param avoid Station to exclude from routing and current next hop of packets to reroute.
 
 * @param avoid2 Additional station to exclude from routing.
 
 * @oaram ge GoodsEntry to get the routing info from.
 
 */
 
uint VehicleCargoList::Reroute(uint max_move, VehicleCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
 
{
 
	max_move = min(this->action_counts[MTA_TRANSFER], max_move);
 
	this->ShiftCargo(VehicleCargoReroute(this, dest, max_move, avoid, avoid2, ge));
 
	return max_move;
 
}
 

	
 
/*
 
 *
 
 * Station cargo list implementation.
 
 *
 
 */
 

	
 
@@ -756,13 +771,13 @@ uint StationCargoList::Load(uint max_mov
 
 * @param avoid Station to exclude from routing and current next hop of packets to reroute.
 
 * @param avoid2 Additional station to exclude from routing.
 
 * @oaram ge GoodsEntry to get the routing info from.
 
 */
 
uint StationCargoList::Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
 
{
 
	return this->ShiftCargo(CargoReroute(this, dest, max_move, avoid, avoid2, ge), avoid, false);
 
	return this->ShiftCargo(StationCargoReroute(this, dest, max_move, avoid, avoid2, ge), avoid, false);
 
}
 

	
 
/*
 
 * We have to instantiate everything we want to be usable.
 
 */
 
template class CargoList<VehicleCargoList, CargoPacketList>;
src/cargopacket.h
Show inline comments
 
@@ -80,12 +80,18 @@ public:
 
	 * Sets the tile where the packet was loaded last.
 
	 * @param load_place Tile where the packet was loaded last.
 
	 */
 
	void SetLoadPlace(TileIndex load_place) { this->loaded_at_xy = load_place; }
 

	
 
	/**
 
	 * Sets the station where the packet is supposed to go next.
 
	 * @param next_station Next station the packet should go to.
 
	 */
 
	void SetNextStation(StationID next_station) { this->next_station = next_station; }
 

	
 
	/**
 
	 * Adds some feeder share to the packet.
 
	 * @param new_share Feeder share to be added.
 
	 */
 
	void AddFeederShare(Money new_share) { this->feeder_share += new_share; }
 

	
 
	/**
 
@@ -316,12 +322,13 @@ public:
 
	friend class CargoShift;
 
	friend class CargoTransfer;
 
	friend class CargoDelivery;
 
	template<class Tsource>
 
	friend class CargoRemoval;
 
	friend class CargoReturn;
 
	friend class VehicleCargoReroute;
 

	
 
	/**
 
	 * Returns source of the first cargo packet in this list.
 
	 * @return The before mentioned source.
 
	 */
 
	inline StationID Source() const
 
@@ -421,12 +428,13 @@ public:
 

	
 
	uint Reassign(uint max_move, MoveToAction from, MoveToAction to);
 
	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);
 
	uint Reroute(uint max_move, VehicleCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge);
 

	
 
	/**
 
	 * Are two the two CargoPackets mergeable in the context of
 
	 * a list of CargoPackets for a Vehicle?
 
	 * @param cp1 First CargoPacket.
 
	 * @param cp2 Second CargoPacket.
 
@@ -464,13 +472,13 @@ public:
 
	friend class CargoLoad;
 
	friend class CargoTransfer;
 
	template<class Tsource>
 
	friend class CargoRemoval;
 
	friend class CargoReservation;
 
	friend class CargoReturn;
 
	friend class CargoReroute;
 
	friend class StationCargoReroute;
 

	
 
	static void InvalidateAllFrom(SourceType src_type, SourceID src);
 

	
 
	template<class Taction>
 
	bool ShiftCargo(Taction &action, StationID next);
 

	
src/station_cmd.cpp
Show inline comments
 
@@ -3399,13 +3399,23 @@ void DeleteStaleLinks(Station *from)
 
			++it; // Do that before removing the node. Anything else may crash.
 
			assert(_date >= edge.LastUpdate());
 
			if ((uint)(_date - edge.LastUpdate()) > LinkGraph::MIN_TIMEOUT_DISTANCE +
 
					(DistanceManhattan(from->xy, to->xy) >> 2)) {
 
				node.RemoveEdge(to->goods[c].node);
 
				ge.flows.DeleteFlows(to->index);
 

	
 
				/* Reroute cargo in station. */
 
				ge.cargo.Reroute(UINT_MAX, &ge.cargo, to->index, from->index, &ge);
 

	
 
				/* Reroute cargo staged to be transfered. */
 
				for (std::list<Vehicle *>::iterator it(from->loading_vehicles.begin()); it != from->loading_vehicles.end(); ++it) {
 
					for (Vehicle *v = *it; v != NULL; v = v->Next()) {
 
						if (v->cargo_type != c) continue;
 
						v->cargo.Reroute(UINT_MAX, &v->cargo, to->index, from->index, &ge);
 
					}
 
				}
 
			}
 
		}
 
		assert(_date >= lg->LastCompression());
 
		if ((uint)(_date - lg->LastCompression()) > LinkGraph::COMPRESSION_INTERVAL) {
 
			lg->Compress();
 
		}
0 comments (0 inline, 0 general)