Use order state at reservation time for signal mode tracerestrict eval

This commit is contained in:
Jonathan G Rennison
2022-07-01 00:19:50 +01:00
parent 12566f05ca
commit bd28d5a239
8 changed files with 62 additions and 23 deletions

View File

@@ -356,7 +356,7 @@ void UpdateAllBlockSignals(Owner owner)
} }
if (_extra_aspects > 0 && IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_GREEN) { if (_extra_aspects > 0 && IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_GREEN) {
SetTunnelBridgeEntranceSignalAspect(tile, 0); SetTunnelBridgeEntranceSignalAspect(tile, 0);
UpdateAspectDeferred(tile, GetTunnelBridgeEntranceTrackdir(tile), false); UpdateAspectDeferred(tile, GetTunnelBridgeEntranceTrackdir(tile));
} }
} }
} while (++tile != MapSize()); } while (++tile != MapSize());

View File

@@ -127,7 +127,7 @@ private:
m_res_fail_td = td; m_res_fail_td = td;
} }
} else { } else {
if (!TryReserveRailTrackdir(tile, td)) { if (!TryReserveRailTrackdir(Yapf().GetVehicle(), tile, td)) {
/* Tile couldn't be reserved, undo. */ /* Tile couldn't be reserved, undo. */
m_res_fail_tile = tile; m_res_fail_tile = tile;
m_res_fail_td = td; m_res_fail_td = td;

View File

@@ -74,13 +74,14 @@ void SetRailStationPlatformReservation(TileIndex start, DiagDirection dir, bool
/** /**
* Try to reserve a specific track on a tile * Try to reserve a specific track on a tile
* This also sets PBS signals to green if reserving through the facing track direction * This also sets PBS signals to green if reserving through the facing track direction
* @param v the train performing the reservation
* @param tile the tile * @param tile the tile
* @param t the track * @param t the track
* @param trigger_stations whether to call station randomisation trigger * @param trigger_stations whether to call station randomisation trigger
* @return \c true if reservation was successful, i.e. the track was * @return \c true if reservation was successful, i.e. the track was
* free and didn't cross any other reserved tracks. * free and didn't cross any other reserved tracks.
*/ */
bool TryReserveRailTrackdir(TileIndex tile, Trackdir td, bool trigger_stations) bool TryReserveRailTrackdir(const Train *v, TileIndex tile, Trackdir td, bool trigger_stations)
{ {
bool success = TryReserveRailTrack(tile, TrackdirToTrack(td), trigger_stations); bool success = TryReserveRailTrack(tile, TrackdirToTrack(td), trigger_stations);
if (success && HasPbsSignalOnTrackdir(tile, td)) { if (success && HasPbsSignalOnTrackdir(tile, td)) {
@@ -88,7 +89,7 @@ bool TryReserveRailTrackdir(TileIndex tile, Trackdir td, bool trigger_stations)
MarkSingleSignalDirty(tile, td); MarkSingleSignalDirty(tile, td);
if (_extra_aspects > 0) { if (_extra_aspects > 0) {
SetSignalAspect(tile, TrackdirToTrack(td), 0); SetSignalAspect(tile, TrackdirToTrack(td), 0);
UpdateAspectDeferred(tile, td, true); UpdateAspectDeferredWithVehicle(v, tile, td, true);
} }
} }
return success; return success;

View File

@@ -20,7 +20,7 @@ TrackBits GetReservedTrackbits(TileIndex t);
void SetRailStationPlatformReservation(TileIndex start, DiagDirection dir, bool b); void SetRailStationPlatformReservation(TileIndex start, DiagDirection dir, bool b);
bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations = true); bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations = true);
bool TryReserveRailTrackdir(TileIndex tile, Trackdir td, bool trigger_stations = true); bool TryReserveRailTrackdir(const Train *v, TileIndex tile, Trackdir td, bool trigger_stations = true);
void UnreserveRailTrack(TileIndex tile, Track t); void UnreserveRailTrack(TileIndex tile, Track t);
void UnreserveRailTrackdir(TileIndex tile, Trackdir td); void UnreserveRailTrackdir(TileIndex tile, Trackdir td);

View File

@@ -1434,7 +1434,7 @@ static void SetupBridgeTunnelSignalSimulation(TileIndex entrance, TileIndex exit
SetTunnelBridgeSignalSimulationExit(exit); SetTunnelBridgeSignalSimulationExit(exit);
if (_extra_aspects > 0) { if (_extra_aspects > 0) {
SetTunnelBridgeEntranceSignalAspect(entrance, 0); SetTunnelBridgeEntranceSignalAspect(entrance, 0);
UpdateAspectDeferred(entrance, GetTunnelBridgeEntranceTrackdir(entrance), false); UpdateAspectDeferred(entrance, GetTunnelBridgeEntranceTrackdir(entrance));
} }
} }
@@ -1584,7 +1584,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
SetTunnelBridgeSignalSimulationExit(t); SetTunnelBridgeSignalSimulationExit(t);
if (_extra_aspects > 0) { if (_extra_aspects > 0) {
SetTunnelBridgeEntranceSignalAspect(t, 0); SetTunnelBridgeEntranceSignalAspect(t, 0);
UpdateAspectDeferred(t, GetTunnelBridgeEntranceTrackdir(t), false); UpdateAspectDeferred(t, GetTunnelBridgeEntranceTrackdir(t));
} }
}; };

View File

@@ -1448,7 +1448,15 @@ void PropagateAspectChange(TileIndex tile, Trackdir trackdir, uint8 aspect)
} }
static std::vector<std::pair<TileIndex, Trackdir>> _deferred_aspect_updates; static std::vector<std::pair<TileIndex, Trackdir>> _deferred_aspect_updates;
static std::vector<std::pair<TileIndex, Trackdir>> _deferred_determine_combined_normal_shunt_mode;
struct DeferredCombinedNormalShuntModeItem {
TileIndex tile;
Trackdir trackdir;
Order current_order;
VehicleOrderID cur_real_order_index;
StationID last_station_visited;
};
static std::vector<DeferredCombinedNormalShuntModeItem> _deferred_determine_combined_normal_shunt_mode;
struct DeferredLookaheadCombinedNormalShuntModeItem { struct DeferredLookaheadCombinedNormalShuntModeItem {
TileIndex tile; TileIndex tile;
@@ -1457,11 +1465,23 @@ struct DeferredLookaheadCombinedNormalShuntModeItem {
}; };
static std::vector<DeferredLookaheadCombinedNormalShuntModeItem> _deferred_lookahead_combined_normal_shunt_mode; static std::vector<DeferredLookaheadCombinedNormalShuntModeItem> _deferred_lookahead_combined_normal_shunt_mode;
void UpdateAspectDeferred(TileIndex tile, Trackdir trackdir, bool check_combined_normal_aspect) void UpdateAspectDeferred(TileIndex tile, Trackdir trackdir)
{
_deferred_aspect_updates.push_back({ tile, trackdir });
}
void UpdateAspectDeferredWithVehicle(const Train *v, TileIndex tile, Trackdir trackdir, bool check_combined_normal_aspect)
{ {
if (check_combined_normal_aspect && IsRailCombinedNormalShuntSignalStyle(tile, TrackdirToTrack(trackdir)) && if (check_combined_normal_aspect && IsRailCombinedNormalShuntSignalStyle(tile, TrackdirToTrack(trackdir)) &&
_settings_game.vehicle.train_braking_model == TBM_REALISTIC) { _settings_game.vehicle.train_braking_model == TBM_REALISTIC) {
_deferred_determine_combined_normal_shunt_mode.push_back({ tile, trackdir }); DeferredCombinedNormalShuntModeItem &item = _deferred_determine_combined_normal_shunt_mode.emplace_back();
item.tile = tile;
item.trackdir = trackdir;
if (IsRestrictedSignal(tile)) {
item.current_order = v->current_order;
item.cur_real_order_index = v->cur_real_order_index;
item.last_station_visited = v->last_station_visited;
}
} }
_deferred_aspect_updates.push_back({ tile, trackdir }); _deferred_aspect_updates.push_back({ tile, trackdir });
} }
@@ -1514,7 +1534,16 @@ void DetermineCombineNormalShuntModeWithLookahead(Train *v, TileIndex tile, Trac
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
TrainReservationLookAheadItem &item = v->lookahead->items[i]; TrainReservationLookAheadItem &item = v->lookahead->items[i];
if (item.start == lookahead_position && item.type == TRLIT_SIGNAL && HasBit(item.data_aux, TRSLAI_COMBINED)) { if (item.start == lookahead_position && item.type == TRLIT_SIGNAL && HasBit(item.data_aux, TRSLAI_COMBINED)) {
container_unordered_remove(_deferred_determine_combined_normal_shunt_mode, std::pair<TileIndex, Trackdir>({ tile, trackdir })); DeferredCombinedNormalShuntModeItem res_item;
bool have_orders = false;
container_unordered_remove_if(_deferred_determine_combined_normal_shunt_mode, [&](DeferredCombinedNormalShuntModeItem &iter) -> bool {
bool found = (iter.tile == tile && iter.trackdir == trackdir);
if (found) {
res_item = std::move(iter);
have_orders = true;
}
return found;
});
if (IsRestrictedSignal(tile)) { if (IsRestrictedSignal(tile)) {
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(tile, TrackdirToTrack(trackdir)); const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(tile, TrackdirToTrack(trackdir));
@@ -1527,7 +1556,17 @@ void DetermineCombineNormalShuntModeWithLookahead(Train *v, TileIndex tile, Trac
return INVALID_TILE; return INVALID_TILE;
} }
}, nullptr); }, nullptr);
if (have_orders && (prog->actions_used_flags & TRPAUF_ORDER_CONDITIONALS)) {
std::swap(res_item.current_order, v->current_order);
std::swap(res_item.cur_real_order_index, v->cur_real_order_index);
std::swap(res_item.last_station_visited, v->last_station_visited);
prog->Execute(v, input, out); prog->Execute(v, input, out);
v->current_order = std::move(res_item.current_order);
v->cur_real_order_index = res_item.cur_real_order_index;
v->last_station_visited = res_item.last_station_visited;
} else {
prog->Execute(v, input, out);
}
if (out.flags & TRPRF_SIGNAL_MODE_NORMAL) { if (out.flags & TRPRF_SIGNAL_MODE_NORMAL) {
return; return;
} }
@@ -1613,10 +1652,8 @@ void FlushDeferredDetermineCombineNormalShuntMode(Train *v)
_deferred_lookahead_combined_normal_shunt_mode.clear(); _deferred_lookahead_combined_normal_shunt_mode.clear();
for (const auto &iter : _deferred_determine_combined_normal_shunt_mode) { for (const auto &iter : _deferred_determine_combined_normal_shunt_mode) {
TileIndex tile = iter.first;
Trackdir trackdir = iter.second;
/* Reservation with no associated lookahead, default to a shunt route */ /* Reservation with no associated lookahead, default to a shunt route */
SetSignalAspect(tile, TrackdirToTrack(trackdir), 1); SetSignalAspect(iter.tile, TrackdirToTrack(iter.trackdir), 1);
} }
_deferred_determine_combined_normal_shunt_mode.clear(); _deferred_determine_combined_normal_shunt_mode.clear();
} }

View File

@@ -189,7 +189,8 @@ void UpdateSignalsInBufferIfOwnerNotAddable(Owner owner);
uint8 GetForwardAspectFollowingTrack(TileIndex tile, Trackdir trackdir); uint8 GetForwardAspectFollowingTrack(TileIndex tile, Trackdir trackdir);
uint8 GetSignalAspectGeneric(TileIndex tile, Trackdir trackdir, bool check_non_inc_style); uint8 GetSignalAspectGeneric(TileIndex tile, Trackdir trackdir, bool check_non_inc_style);
void PropagateAspectChange(TileIndex tile, Trackdir trackdir, uint8 aspect); void PropagateAspectChange(TileIndex tile, Trackdir trackdir, uint8 aspect);
void UpdateAspectDeferred(TileIndex tile, Trackdir trackdir, bool check_combined_normal_aspect); void UpdateAspectDeferred(TileIndex tile, Trackdir trackdir);
void UpdateAspectDeferredWithVehicle(const Train *v, TileIndex tile, Trackdir trackdir, bool check_combined_normal_aspect);
void UpdateLookaheadCombinedNormalShuntSignalDeferred(TileIndex tile, Trackdir trackdir, int lookahead_position); void UpdateLookaheadCombinedNormalShuntSignalDeferred(TileIndex tile, Trackdir trackdir, int lookahead_position);
void FlushDeferredAspectUpdates(); void FlushDeferredAspectUpdates();
void FlushDeferredDetermineCombineNormalShuntMode(Train *v); void FlushDeferredDetermineCombineNormalShuntMode(Train *v);

View File

@@ -3454,7 +3454,7 @@ static void SetTunnelBridgeEntranceSignalGreen(TileIndex tile)
MarkTunnelBridgeSignalDirty(tile, false); MarkTunnelBridgeSignalDirty(tile, false);
if (_extra_aspects > 0) { if (_extra_aspects > 0) {
SetTunnelBridgeEntranceSignalAspect(tile, 0); SetTunnelBridgeEntranceSignalAspect(tile, 0);
UpdateAspectDeferred(tile, GetTunnelBridgeEntranceTrackdir(tile), false); UpdateAspectDeferred(tile, GetTunnelBridgeEntranceTrackdir(tile));
} }
} else if (_extra_aspects > 0) { } else if (_extra_aspects > 0) {
UpdateTunnelBridgeEntranceSignalAspect(tile); UpdateTunnelBridgeEntranceSignalAspect(tile);
@@ -3768,7 +3768,7 @@ static PBSTileInfo ExtendTrainReservation(const Train *v, const PBSTileInfo &ori
if (IsSafeWaitingPosition(v, tile, cur_td, true, _settings_game.pf.forbid_90_deg)) { if (IsSafeWaitingPosition(v, tile, cur_td, true, _settings_game.pf.forbid_90_deg)) {
PBSWaitingPositionRestrictedSignalInfo restricted_signal_info; PBSWaitingPositionRestrictedSignalInfo restricted_signal_info;
bool wp_free = IsWaitingPositionFree(v, tile, cur_td, _settings_game.pf.forbid_90_deg, &restricted_signal_info); bool wp_free = IsWaitingPositionFree(v, tile, cur_td, _settings_game.pf.forbid_90_deg, &restricted_signal_info);
if (!(wp_free && TryReserveRailTrackdir(tile, cur_td))) break; if (!(wp_free && TryReserveRailTrackdir(v, tile, cur_td))) break;
/* Safe position is all good, path valid and okay. */ /* Safe position is all good, path valid and okay. */
if (restricted_signal_info.tile != INVALID_TILE) { if (restricted_signal_info.tile != INVALID_TILE) {
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(restricted_signal_info.tile, TrackdirToTrack(restricted_signal_info.trackdir)); const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(restricted_signal_info.tile, TrackdirToTrack(restricted_signal_info.trackdir));
@@ -3782,7 +3782,7 @@ static PBSTileInfo ExtendTrainReservation(const Train *v, const PBSTileInfo &ori
return PBSTileInfo(tile, cur_td, true); return PBSTileInfo(tile, cur_td, true);
} }
if (!TryReserveRailTrackdir(tile, cur_td)) break; if (!TryReserveRailTrackdir(v, tile, cur_td)) break;
} }
if (ft.m_err == CFollowTrackRail::EC_OWNER || ft.m_err == CFollowTrackRail::EC_NO_WAY) { if (ft.m_err == CFollowTrackRail::EC_OWNER || ft.m_err == CFollowTrackRail::EC_NO_WAY) {
@@ -4157,7 +4157,7 @@ static void TryLongReserveChooseTrainTrack(Train *v, TileIndex tile, Trackdir td
} else { } else {
if (_extra_aspects > 0) { if (_extra_aspects > 0) {
SetTunnelBridgeExitSignalAspect(exit_tile, 0); SetTunnelBridgeExitSignalAspect(exit_tile, 0);
UpdateAspectDeferred(exit_tile, GetTunnelBridgeExitTrackdir(exit_tile), false); UpdateAspectDeferred(exit_tile, GetTunnelBridgeExitTrackdir(exit_tile));
} }
MarkTileDirtyByTile(exit_tile, VMDF_NOT_MAP_MODE); MarkTileDirtyByTile(exit_tile, VMDF_NOT_MAP_MODE);
} }
@@ -4251,7 +4251,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
SetSignalStateByTrackdir(tile, changed_signal, SIGNAL_STATE_GREEN); SetSignalStateByTrackdir(tile, changed_signal, SIGNAL_STATE_GREEN);
if (_extra_aspects > 0) { if (_extra_aspects > 0) {
SetSignalAspect(tile, track, 0); SetSignalAspect(tile, track, 0);
UpdateAspectDeferred(tile, changed_signal, true); UpdateAspectDeferredWithVehicle(v, tile, changed_signal, true);
} }
} else if (!do_track_reservation) { } else if (!do_track_reservation) {
return track; return track;
@@ -5142,7 +5142,7 @@ static bool CheckTrainStayInWormHolePathReserve(Train *t, TileIndex tile)
if (ok) { if (ok) {
if (_extra_aspects > 0) { if (_extra_aspects > 0) {
SetTunnelBridgeExitSignalAspect(tile, 0); SetTunnelBridgeExitSignalAspect(tile, 0);
UpdateAspectDeferred(tile, GetTunnelBridgeExitTrackdir(tile), false); UpdateAspectDeferred(tile, GetTunnelBridgeExitTrackdir(tile));
} }
mark_dirty = true; mark_dirty = true;
if (t->lookahead->reservation_end_tile == veh_orig_tile && t->lookahead->reservation_end_position - t->lookahead->current_position <= (int)TILE_SIZE) { if (t->lookahead->reservation_end_tile == veh_orig_tile && t->lookahead->reservation_end_position - t->lookahead->current_position <= (int)TILE_SIZE) {
@@ -5187,7 +5187,7 @@ static bool CheckTrainStayInWormHolePathReserve(Train *t, TileIndex tile)
SetTunnelBridgeExitSignalState(tile, SIGNAL_STATE_GREEN); SetTunnelBridgeExitSignalState(tile, SIGNAL_STATE_GREEN);
if (_extra_aspects > 0) { if (_extra_aspects > 0) {
SetTunnelBridgeExitSignalAspect(tile, 0); SetTunnelBridgeExitSignalAspect(tile, 0);
UpdateAspectDeferred(tile, GetTunnelBridgeExitTrackdir(tile), false); UpdateAspectDeferred(tile, GetTunnelBridgeExitTrackdir(tile));
} }
mark_dirty = true; mark_dirty = true;
} }