(svn r14286) -Fix [FS#2265]: If a change of conventional/electric rail coincided with the start of a station platform, stale reservations could be left behind.

This commit is contained in:
michi_cc 2008-09-09 19:21:22 +00:00
parent 5a28d3a54f
commit 0ac103e506
2 changed files with 43 additions and 21 deletions

View File

@ -193,18 +193,6 @@ struct CYapfRailNodeT
cur = ft.m_new_tile; cur = ft.m_new_tile;
assert(KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE); assert(KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE);
cur_td = FindFirstTrackdir(ft.m_new_td_bits); cur_td = FindFirstTrackdir(ft.m_new_td_bits);
/* Did we skip tiles because of a station? */
if (ft.m_is_station && ft.m_tiles_skipped > 0) {
TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(cur_td));
TileIndex tile = TILE_ADD(cur, -diff * ft.m_tiles_skipped);
/* Call func for all tiles in between. */
for (int i = 0; i < ft.m_tiles_skipped; ++i) {
if (!(obj.*func)(tile, cur_td)) return false;
tile = TILE_ADD(tile, diff);
}
}
} }
return (obj.*func)(cur, cur_td); return (obj.*func)(cur, cur_td);

View File

@ -10,6 +10,7 @@
#include "yapf_destrail.hpp" #include "yapf_destrail.hpp"
#include "../vehicle_func.h" #include "../vehicle_func.h"
#include "../pbs.h" #include "../pbs.h"
#include "../functions.h"
#define DEBUG_YAPF_CACHE 0 #define DEBUG_YAPF_CACHE 0
@ -46,23 +47,56 @@ private:
return true; return true;
} }
/** Reserve a railway platform. Tile contains the failed tile on abort. */
bool ReserveRailwayStationPlatform(TileIndex &tile, DiagDirection dir)
{
TileIndex start = tile;
TileIndexDiff diff = TileOffsByDiagDir(dir);
do {
if (GetRailwayStationReservation(tile)) return false;
SetRailwayStationReservation(tile, true);
MarkTileDirtyByTile(tile);
tile = TILE_ADD(tile, diff);
} while (IsCompatibleTrainStationTile(tile, start));
return true;
}
/** Try to reserve a single track/platform. */
bool ReserveSingleTrack(TileIndex tile, Trackdir td) bool ReserveSingleTrack(TileIndex tile, Trackdir td)
{ {
if (!TryReserveRailTrack(tile, TrackdirToTrack(td))) { if (IsRailwayStationTile(tile)) {
/* Tile couldn't be reserved, undo. */ if (!ReserveRailwayStationPlatform(tile, TrackdirToExitdir(ReverseTrackdir(td)))) {
m_res_fail_tile = tile; /* Platform could not be reserved, undo. */
m_res_fail_td = td; m_res_fail_tile = tile;
return false; m_res_fail_td = td;
}
} else {
if (!TryReserveRailTrack(tile, TrackdirToTrack(td))) {
/* Tile couldn't be reserved, undo. */
m_res_fail_tile = tile;
m_res_fail_td = td;
return false;
}
} }
/* YAPF can sometimes skip parts of a station, so make sure we
* always reserve the whole platform. */
if (IsRailwayStationTile(tile)) SetRailwayStationPlatformReservation(tile, TrackdirToExitdir(ReverseTrackdir(td)), true);
return tile != m_res_dest; return tile != m_res_dest;
} }
/** Unreserve a single track/platform. Stops when the previous failer is reached. */
bool UnreserveSingleTrack(TileIndex tile, Trackdir td) bool UnreserveSingleTrack(TileIndex tile, Trackdir td)
{ {
if (tile != m_res_fail_tile || td != m_res_fail_td) UnreserveRailTrack(tile, TrackdirToTrack(td)); if (IsRailwayStationTile(tile)) {
TileIndex start = tile;
TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(td)));
while ((tile != m_res_fail_tile || td != m_res_fail_td) && IsCompatibleTrainStationTile(tile, start)) {
SetRailwayStationReservation(tile, false);
tile = TILE_ADD(tile, diff);
}
} else if (tile != m_res_fail_tile || td != m_res_fail_td) {
UnreserveRailTrack(tile, TrackdirToTrack(td));
}
return tile != m_res_dest && (tile != m_res_fail_tile || td != m_res_fail_td); return tile != m_res_dest && (tile != m_res_fail_tile || td != m_res_fail_td);
} }