MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / UpdateSignalsAroundSegment

Function UpdateSignalsAroundSegment

src/signal.cpp:410–460  ·  view source on GitHub ↗

* Update signals around segment in _tbuset * * @param flags info about segment */

Source from the content-addressed store, hash-verified

408 * @param flags info about segment
409 */
410static 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 */

Callers 1

UpdateSignalsInBufferFunction · 0.85

Calls 15

HasSignalOnTrackdirFunction · 0.85
TrackdirToTrackFunction · 0.85
GetSignalTypeFunction · 0.85
IsPbsSignalFunction · 0.85
TrackToTrackBitsFunction · 0.85
ReverseTrackdirFunction · 0.85
GetSignalStateByTrackdirFunction · 0.85
IsPresignalEntryFunction · 0.85
IsPresignalExitFunction · 0.85
TrackdirToExitdirFunction · 0.85
SetSignalStateByTrackdirFunction · 0.85

Tested by

no test coverage detected