* Update signals around segment in _tbuset * * @param flags info about segment */
| 408 | * @param flags info about segment |
| 409 | */ |
| 410 | static void UpdateSignalsAroundSegment(SigFlags flags) |
| 411 | { |
| 412 | TileIndex tile = INVALID_TILE; // Stop GCC from complaining about a possibly uninitialized variable (issue #8280). |
| 413 | Trackdir trackdir = INVALID_TRACKDIR; |
| 414 | |
| 415 | while (_tbuset.Get(&tile, &trackdir)) { |
| 416 | assert(HasSignalOnTrackdir(tile, trackdir)); |
| 417 | |
| 418 | Track track = TrackdirToTrack(trackdir); |
| 419 | SignalType sig = GetSignalType(tile, track); |
| 420 | SignalState newstate = SIGNAL_STATE_GREEN; |
| 421 | |
| 422 | /* Signal state of reserved path signals is handled by the reserve/unreserve process. */ |
| 423 | if (IsPbsSignal(sig) && (GetRailReservationTrackBits(tile) & TrackToTrackBits(track)) != TRACK_BIT_NONE) continue; |
| 424 | |
| 425 | /* determine whether the new state is red */ |
| 426 | if (flags.Test(SigFlag::Train)) { |
| 427 | /* train in the segment */ |
| 428 | newstate = SIGNAL_STATE_RED; |
| 429 | } else if (IsPbsSignal(sig) && flags.Any({SigFlag::Split, SigFlag::MultiEnter})) { |
| 430 | /* Turn path signals red if the segment has a junction or more than one way in. */ |
| 431 | newstate = SIGNAL_STATE_RED; |
| 432 | } else { |
| 433 | /* is it a bidir combo? - then do not count its other signal direction as exit */ |
| 434 | if (sig == SIGTYPE_COMBO && HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) { |
| 435 | /* at least one more exit */ |
| 436 | if (flags.Test(SigFlag::MultiExit) && |
| 437 | /* no green exit */ |
| 438 | (!flags.Test(SigFlag::Green) || |
| 439 | /* only one green exit, and it is this one - so all other exits are red */ |
| 440 | (!flags.Test(SigFlag::MultiGreen) && GetSignalStateByTrackdir(tile, ReverseTrackdir(trackdir)) == SIGNAL_STATE_GREEN))) { |
| 441 | newstate = SIGNAL_STATE_RED; |
| 442 | } |
| 443 | } else { // entry, at least one exit, no green exit |
| 444 | if (IsPresignalEntry(tile, TrackdirToTrack(trackdir)) && flags.Test(SigFlag::Exit) && !flags.Test(SigFlag::Green)) newstate = SIGNAL_STATE_RED; |
| 445 | } |
| 446 | } |
| 447 | |
| 448 | /* only when the state changes */ |
| 449 | if (newstate != GetSignalStateByTrackdir(tile, trackdir)) { |
| 450 | if (IsPresignalExit(tile, TrackdirToTrack(trackdir))) { |
| 451 | /* for pre-signal exits, add block to the global set */ |
| 452 | DiagDirection exitdir = TrackdirToExitdir(ReverseTrackdir(trackdir)); |
| 453 | _globset.Add(tile, exitdir); // do not check for full global set, first update all signals |
| 454 | } |
| 455 | SetSignalStateByTrackdir(tile, trackdir, newstate); |
| 456 | MarkTileDirtyByTile(tile); |
| 457 | } |
| 458 | } |
| 459 | |
| 460 | } |
| 461 | |
| 462 | |
| 463 | /** Reset all sets after one set overflowed */ |
no test coverage detected