From bd28d5a239a3562cfd28a578aedfe6894162caf7 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 1 Jul 2022 00:19:50 +0100 Subject: [PATCH] Use order state at reservation time for signal mode tracerestrict eval --- src/infrastructure.cpp | 2 +- src/pathfinder/yapf/yapf_rail.cpp | 2 +- src/pbs.cpp | 5 +-- src/pbs.h | 2 +- src/rail_cmd.cpp | 4 +-- src/signal.cpp | 53 ++++++++++++++++++++++++++----- src/signal_func.h | 3 +- src/train_cmd.cpp | 14 ++++---- 8 files changed, 62 insertions(+), 23 deletions(-) diff --git a/src/infrastructure.cpp b/src/infrastructure.cpp index e5c410cdf3..f29c74880a 100644 --- a/src/infrastructure.cpp +++ b/src/infrastructure.cpp @@ -356,7 +356,7 @@ void UpdateAllBlockSignals(Owner owner) } if (_extra_aspects > 0 && IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_GREEN) { SetTunnelBridgeEntranceSignalAspect(tile, 0); - UpdateAspectDeferred(tile, GetTunnelBridgeEntranceTrackdir(tile), false); + UpdateAspectDeferred(tile, GetTunnelBridgeEntranceTrackdir(tile)); } } } while (++tile != MapSize()); diff --git a/src/pathfinder/yapf/yapf_rail.cpp b/src/pathfinder/yapf/yapf_rail.cpp index e4a469e6c5..644d33a8bc 100644 --- a/src/pathfinder/yapf/yapf_rail.cpp +++ b/src/pathfinder/yapf/yapf_rail.cpp @@ -127,7 +127,7 @@ private: m_res_fail_td = td; } } else { - if (!TryReserveRailTrackdir(tile, td)) { + if (!TryReserveRailTrackdir(Yapf().GetVehicle(), tile, td)) { /* Tile couldn't be reserved, undo. */ m_res_fail_tile = tile; m_res_fail_td = td; diff --git a/src/pbs.cpp b/src/pbs.cpp index 93a6c41e03..6c950335c5 100644 --- a/src/pbs.cpp +++ b/src/pbs.cpp @@ -74,13 +74,14 @@ void SetRailStationPlatformReservation(TileIndex start, DiagDirection dir, bool /** * Try to reserve a specific track on a tile * 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 t the track * @param trigger_stations whether to call station randomisation trigger * @return \c true if reservation was successful, i.e. the track was * 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); if (success && HasPbsSignalOnTrackdir(tile, td)) { @@ -88,7 +89,7 @@ bool TryReserveRailTrackdir(TileIndex tile, Trackdir td, bool trigger_stations) MarkSingleSignalDirty(tile, td); if (_extra_aspects > 0) { SetSignalAspect(tile, TrackdirToTrack(td), 0); - UpdateAspectDeferred(tile, td, true); + UpdateAspectDeferredWithVehicle(v, tile, td, true); } } return success; diff --git a/src/pbs.h b/src/pbs.h index c7af642a69..20ac6eaa82 100644 --- a/src/pbs.h +++ b/src/pbs.h @@ -20,7 +20,7 @@ TrackBits GetReservedTrackbits(TileIndex t); void SetRailStationPlatformReservation(TileIndex start, DiagDirection dir, bool b); 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 UnreserveRailTrackdir(TileIndex tile, Trackdir td); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 0a163eabd0..568820325b 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1434,7 +1434,7 @@ static void SetupBridgeTunnelSignalSimulation(TileIndex entrance, TileIndex exit SetTunnelBridgeSignalSimulationExit(exit); if (_extra_aspects > 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); if (_extra_aspects > 0) { SetTunnelBridgeEntranceSignalAspect(t, 0); - UpdateAspectDeferred(t, GetTunnelBridgeEntranceTrackdir(t), false); + UpdateAspectDeferred(t, GetTunnelBridgeEntranceTrackdir(t)); } }; diff --git a/src/signal.cpp b/src/signal.cpp index 242f732849..7bb9116835 100644 --- a/src/signal.cpp +++ b/src/signal.cpp @@ -1448,7 +1448,15 @@ void PropagateAspectChange(TileIndex tile, Trackdir trackdir, uint8 aspect) } static std::vector> _deferred_aspect_updates; -static std::vector> _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 _deferred_determine_combined_normal_shunt_mode; struct DeferredLookaheadCombinedNormalShuntModeItem { TileIndex tile; @@ -1457,11 +1465,23 @@ struct DeferredLookaheadCombinedNormalShuntModeItem { }; static std::vector _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)) && _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 }); } @@ -1514,7 +1534,16 @@ void DetermineCombineNormalShuntModeWithLookahead(Train *v, TileIndex tile, Trac for (size_t i = 0; i < count; i++) { TrainReservationLookAheadItem &item = v->lookahead->items[i]; 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({ 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)) { const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(tile, TrackdirToTrack(trackdir)); @@ -1527,7 +1556,17 @@ void DetermineCombineNormalShuntModeWithLookahead(Train *v, TileIndex tile, Trac return INVALID_TILE; } }, nullptr); - prog->Execute(v, input, out); + 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); + 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) { return; } @@ -1613,10 +1652,8 @@ void FlushDeferredDetermineCombineNormalShuntMode(Train *v) _deferred_lookahead_combined_normal_shunt_mode.clear(); 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 */ - SetSignalAspect(tile, TrackdirToTrack(trackdir), 1); + SetSignalAspect(iter.tile, TrackdirToTrack(iter.trackdir), 1); } _deferred_determine_combined_normal_shunt_mode.clear(); } diff --git a/src/signal_func.h b/src/signal_func.h index 7197d459e5..9b02638937 100644 --- a/src/signal_func.h +++ b/src/signal_func.h @@ -189,7 +189,8 @@ void UpdateSignalsInBufferIfOwnerNotAddable(Owner owner); uint8 GetForwardAspectFollowingTrack(TileIndex tile, Trackdir trackdir); uint8 GetSignalAspectGeneric(TileIndex tile, Trackdir trackdir, bool check_non_inc_style); 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 FlushDeferredAspectUpdates(); void FlushDeferredDetermineCombineNormalShuntMode(Train *v); diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index aeb1c5febe..fb07f853f8 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -3454,7 +3454,7 @@ static void SetTunnelBridgeEntranceSignalGreen(TileIndex tile) MarkTunnelBridgeSignalDirty(tile, false); if (_extra_aspects > 0) { SetTunnelBridgeEntranceSignalAspect(tile, 0); - UpdateAspectDeferred(tile, GetTunnelBridgeEntranceTrackdir(tile), false); + UpdateAspectDeferred(tile, GetTunnelBridgeEntranceTrackdir(tile)); } } else if (_extra_aspects > 0) { 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)) { PBSWaitingPositionRestrictedSignalInfo 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. */ if (restricted_signal_info.tile != INVALID_TILE) { 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); } - 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) { @@ -4157,7 +4157,7 @@ static void TryLongReserveChooseTrainTrack(Train *v, TileIndex tile, Trackdir td } else { if (_extra_aspects > 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); } @@ -4251,7 +4251,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, SetSignalStateByTrackdir(tile, changed_signal, SIGNAL_STATE_GREEN); if (_extra_aspects > 0) { SetSignalAspect(tile, track, 0); - UpdateAspectDeferred(tile, changed_signal, true); + UpdateAspectDeferredWithVehicle(v, tile, changed_signal, true); } } else if (!do_track_reservation) { return track; @@ -5142,7 +5142,7 @@ static bool CheckTrainStayInWormHolePathReserve(Train *t, TileIndex tile) if (ok) { if (_extra_aspects > 0) { SetTunnelBridgeExitSignalAspect(tile, 0); - UpdateAspectDeferred(tile, GetTunnelBridgeExitTrackdir(tile), false); + UpdateAspectDeferred(tile, GetTunnelBridgeExitTrackdir(tile)); } mark_dirty = true; 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); if (_extra_aspects > 0) { SetTunnelBridgeExitSignalAspect(tile, 0); - UpdateAspectDeferred(tile, GetTunnelBridgeExitTrackdir(tile), false); + UpdateAspectDeferred(tile, GetTunnelBridgeExitTrackdir(tile)); } mark_dirty = true; }