OpenTTD Source 20260621-master-g720d10536d
signal.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#include "stdafx.h"
11#include "debug.h"
12#include "station_map.h"
13#include "tunnelbridge_map.h"
14#include "vehicle_func.h"
15#include "viewport_func.h"
16#include "train.h"
17#include "company_base.h"
18#include "pbs.h"
19
20#include "table/signal_data.h"
21
22#include "safeguards.h"
23
24
26static const uint SIG_TBU_SIZE = 64;
27static const uint SIG_TBD_SIZE = 256;
28static const uint SIG_GLOB_SIZE = 128;
29static const uint SIG_GLOB_UPDATE = 64;
30
31static_assert(SIG_GLOB_UPDATE <= SIG_GLOB_SIZE);
32
40
48
54template <typename Tdir, uint items>
55struct SmallSet {
56private:
57 uint n = 0;
58 bool overflowed = false;
59 const std::string_view name;
60
62 struct SSdata {
63 TileIndex tile;
64 Tdir dir;
65 } data[items];
66
67public:
72 SmallSet(std::string_view name) : name(name) { }
73
75 void Reset()
76 {
77 this->n = 0;
78 this->overflowed = false;
79 }
80
86 {
87 return this->overflowed;
88 }
89
94 bool IsEmpty()
95 {
96 return this->n == 0;
97 }
98
103 bool IsFull()
104 {
105 return this->n == lengthof(data);
106 }
107
112 uint Items()
113 {
114 return this->n;
115 }
116
117
124 bool Remove(TileIndex tile, Tdir dir)
125 {
126 for (uint i = 0; i < this->n; i++) {
127 if (this->data[i].tile == tile && this->data[i].dir == dir) {
128 this->data[i] = this->data[--this->n];
129 return true;
130 }
131 }
132
133 return false;
134 }
135
142 bool IsIn(TileIndex tile, Tdir dir)
143 {
144 for (uint i = 0; i < this->n; i++) {
145 if (this->data[i].tile == tile && this->data[i].dir == dir) return true;
146 }
147
148 return false;
149 }
150
158 bool Add(TileIndex tile, Tdir dir)
159 {
160 if (this->IsFull()) {
161 overflowed = true;
162 Debug(misc, 0, "SignalSegment too complex. Set {} is full (maximum {})", name, items);
163 return false; // set is full
164 }
165
166 this->data[this->n].tile = tile;
167 this->data[this->n].dir = dir;
168 this->n++;
169
170 return true;
171 }
172
179 bool Get(TileIndex *tile, Tdir *dir)
180 {
181 if (this->n == 0) return false;
182
183 this->n--;
184 *tile = this->data[this->n].tile;
185 *dir = this->data[this->n].dir;
186
187 return true;
188 }
189};
190
194
195
201static bool IsTrainAndNotInDepot(const Vehicle *v)
202{
204}
205
206
221{
222 _globset.Remove(t1, d1); // it can be in Global but not in Todo
223 _globset.Remove(t2, d2); // remove in all cases
224
225 assert(!_tbdset.IsIn(t1, d1)); // it really shouldn't be there already
226
227 return !_tbdset.Remove(t2, d2);
228}
229
230
245{
246 if (!CheckAddToTodoSet(t1, d1, t2, d2)) return true;
247
248 return _tbdset.Add(t1, d1);
249}
250
251
265
268
275static SigFlags ExploreSegment(Owner owner)
276{
277 SigFlags flags{};
278
279 TileIndex tile = INVALID_TILE; // Stop GCC from complaining about a possibly uninitialized variable (issue #8280).
281
282 while (_tbdset.Get(&tile, &enterdir)) { // tile and enterdir are initialized here, unless I'm mistaken.
283 TileIndex oldtile = tile; // tile we are leaving
284 DiagDirection exitdir = enterdir == DiagDirection::Invalid ? DiagDirection::Invalid : ReverseDiagDir(enterdir); // expected new exit direction (for straight line)
285
286 switch (GetTileType(tile)) {
287 case TileType::Railway: {
288 if (GetTileOwner(tile) != owner) continue; // do not propagate signals on others' tiles (remove for tracksharing)
289
290 if (IsRailDepot(tile)) {
291 if (enterdir == DiagDirection::Invalid) { // from 'inside' - train just entered or left the depot
293 exitdir = GetRailDepotDirection(tile);
294 tile += TileOffsByDiagDir(exitdir);
295 enterdir = ReverseDiagDir(exitdir);
296 break;
297 } else if (enterdir == GetRailDepotDirection(tile)) { // entered a depot
299 continue;
300 } else {
301 continue;
302 }
303 }
304
305 assert(IsValidDiagDirection(enterdir));
306 TrackBits tracks = GetTrackBits(tile); // trackbits of tile
307 TrackBits tracks_masked = tracks & _enterdir_to_trackbits[enterdir]; // only accessible trackbits
308
309 if (tracks == TRACK_BIT_HORZ || tracks == TRACK_BIT_VERT) { // there is exactly one accessible track, no need to check
310 tracks = tracks_masked;
311 /* If no train detected yet, and there is not no train -> there is a train -> set the flag */
312 if (!flags.Test(SigFlag::Train) && EnsureNoTrainOnTrackBits(tile, tracks).Failed()) flags. Set(SigFlag::Train);
313 } else {
314 if (tracks_masked.None()) continue; // no accessible track
316 }
317
318 /* Is this a track merge or split? */
319 if (tracks.Count() > 1) flags.Set(SigFlag::Split);
320
321 if (HasSignals(tile)) { // there is exactly one track - not zero, because there is exit from this tile
322 Track track = TrackBitsToTrack(tracks_masked); // mask TRACK_BIT_X and Y too
323 if (HasSignalOnTrack(tile, track)) { // now check whole track, not trackdir
324 SignalType sig = GetSignalType(tile, track);
325 Trackdir trackdir = (TrackBitsToTrackdirBits(tracks) & _enterdir_to_trackdirbits[enterdir]).GetNthSetBit(0).value();
326 Trackdir reversedir = ReverseTrackdir(trackdir);
327 /* add (tile, reversetrackdir) to 'to-be-updated' set when there is
328 * ANY conventional signal in REVERSE direction
329 * (if it is a presignal EXIT and it changes, it will be added to 'to-be-done' set later) */
330 if (HasSignalOnTrackdir(tile, reversedir)) {
331 if (IsPbsSignal(sig)) flags.Set(SigFlag::Pbs);
332 if (flags.Test(SigFlag::Enter)) flags.Set(SigFlag::MultiEnter);
333 flags.Set(SigFlag::Enter);
334
335 if (!_tbuset.Add(tile, reversedir)) return flags | SigFlag::Full;
336 }
337 if (HasSignalOnTrackdir(tile, trackdir) && !IsOnewaySignal(tile, track)) flags.Set(SigFlag::Pbs);
338
339 /* if it is a presignal EXIT in OUR direction and we haven't found 2 green exits yes, do special check */
340 if (!flags.Test(SigFlag::MultiGreen) && IsPresignalExit(tile, track) && HasSignalOnTrackdir(tile, trackdir)) { // found presignal exit
341 if (flags.Test(SigFlag::Exit)) flags.Set(SigFlag::MultiExit); // found two (or more) exits
342 flags.Set(SigFlag::Exit); // found at least one exit - allow for compiler optimizations
343 if (GetSignalStateByTrackdir(tile, trackdir) == SignalState::Green) { // found green presignal exit
344 if (flags.Test(SigFlag::Green)) flags.Set(SigFlag::MultiGreen);
345 flags.Set(SigFlag::Green);
346 }
347 }
348
349 continue;
350 }
351 }
352
353 for (DiagDirection dir : EnumRange(DiagDirection::End)) { // test all possible exit directions
354 if (dir != enterdir && tracks.Any(_enterdir_to_trackbits[dir])) { // any accessible track?
355 TileIndex newtile = tile + TileOffsByDiagDir(dir); // new tile to check
356 DiagDirection newdir = ReverseDiagDir(dir); // direction we are entering from
357 if (!MaybeAddToTodoSet(newtile, newdir, tile, dir)) return flags | SigFlag::Full;
358 }
359 }
360
361 continue; // continue the while() loop
362 }
363
365 if (!HasStationRail(tile)) continue;
366 if (GetTileOwner(tile) != owner) continue;
367 if (DiagDirToAxis(enterdir) != GetRailStationAxis(tile)) continue; // different axis
368 if (IsStationTileBlocked(tile)) continue; // 'eye-candy' station tile
369
371 tile += TileOffsByDiagDir(exitdir);
372 break;
373
374 case TileType::Road:
375 if (!IsLevelCrossing(tile)) continue;
376 if (GetTileOwner(tile) != owner) continue;
377 if (DiagDirToAxis(enterdir) == GetCrossingRoadAxis(tile)) continue; // different axis
378
380 tile += TileOffsByDiagDir(exitdir);
381 break;
382
384 if (GetTileOwner(tile) != owner) continue;
385 if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) continue;
387
388 if (enterdir == DiagDirection::Invalid) { // incoming from the wormhole
390 enterdir = dir;
391 exitdir = ReverseDiagDir(dir);
392 tile += TileOffsByDiagDir(exitdir); // just skip to next tile
393 } else { // NOT incoming from the wormhole!
394 if (ReverseDiagDir(enterdir) != dir) continue;
396 tile = GetOtherTunnelBridgeEnd(tile); // just skip to exit tile
397 enterdir = DiagDirection::Invalid;
398 exitdir = DiagDirection::Invalid;
399 }
400 }
401 break;
402
403 default:
404 continue; // continue the while() loop
405 }
406
407 if (!MaybeAddToTodoSet(tile, enterdir, oldtile, exitdir)) return flags | SigFlag::Full;
408 }
409
410 return flags;
411}
412
413
420{
421 TileIndex tile = INVALID_TILE; // Stop GCC from complaining about a possibly uninitialized variable (issue #8280).
422 Trackdir trackdir = Trackdir::Invalid;
423
424 while (_tbuset.Get(&tile, &trackdir)) {
425 assert(HasSignalOnTrackdir(tile, trackdir));
426
427 Track track = TrackdirToTrack(trackdir);
428 SignalType sig = GetSignalType(tile, track);
430
431 /* Signal state of reserved path signals is handled by the reserve/unreserve process. */
432 if (IsPbsSignal(sig) && GetRailReservationTrackBits(tile).Test(track)) continue;
433
434 /* determine whether the new state is red */
435 if (flags.Test(SigFlag::Train)) {
436 /* train in the segment */
437 newstate = SignalState::Red;
438 } else if (IsPbsSignal(sig) && flags.Any({SigFlag::Split, SigFlag::MultiEnter})) {
439 /* Turn path signals red if the segment has a junction or more than one way in. */
440 newstate = SignalState::Red;
441 } else {
442 /* is it a bidir combo? - then do not count its other signal direction as exit */
443 if (sig == SignalType::Combo && HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) {
444 /* at least one more exit */
445 if (flags.Test(SigFlag::MultiExit) &&
446 /* no green exit */
447 (!flags.Test(SigFlag::Green) ||
448 /* only one green exit, and it is this one - so all other exits are red */
450 newstate = SignalState::Red;
451 }
452 } else { // entry, at least one exit, no green exit
453 if (IsPresignalEntry(tile, TrackdirToTrack(trackdir)) && flags.Test(SigFlag::Exit) && !flags.Test(SigFlag::Green)) newstate = SignalState::Red;
454 }
455 }
456
457 /* only when the state changes */
458 if (newstate != GetSignalStateByTrackdir(tile, trackdir)) {
459 if (IsPresignalExit(tile, TrackdirToTrack(trackdir))) {
460 /* for pre-signal exits, add block to the global set */
462 _globset.Add(tile, exitdir); // do not check for full global set, first update all signals
463 }
464 SetSignalStateByTrackdir(tile, trackdir, newstate);
466 }
467 }
468
469}
470
471
473static inline void ResetSets()
474{
475 _tbuset.Reset();
476 _tbdset.Reset();
477 _globset.Reset();
478}
479
480
489{
490 assert(Company::IsValidID(owner));
491
492 bool first = true; // first block?
493 SigSegState state = SigSegState::Free; // value to return
494
495 TileIndex tile = INVALID_TILE; // Stop GCC from complaining about a possibly uninitialized variable (issue #8280).
497
498 while (_globset.Get(&tile, &dir)) {
499 assert(_tbuset.IsEmpty());
500 assert(_tbdset.IsEmpty());
501
502 /* After updating signal, data stored are always TileType::Railway with signals.
503 * Other situations happen when data are from outside functions -
504 * modification of railbits (including both rail building and removal),
505 * train entering/leaving block, train leaving depot...
506 */
507 switch (GetTileType(tile)) {
509 /* 'optimization assert' - do not try to update signals when it is not needed */
511 assert(dir == DiagDirection::Invalid || dir == ReverseDiagDir(GetTunnelBridgeDirection(tile)));
512 _tbdset.Add(tile, DiagDirection::Invalid); // we can safely start from wormhole centre
514 break;
515
517 if (IsRailDepot(tile)) {
518 /* 'optimization assert' do not try to update signals in other cases */
519 assert(dir == DiagDirection::Invalid || dir == GetRailDepotDirection(tile));
520 _tbdset.Add(tile, DiagDirection::Invalid); // start from depot inside
521 break;
522 }
523 [[fallthrough]];
524
526 case TileType::Road:
528 /* only add to set when there is some 'interesting' track */
529 _tbdset.Add(tile, dir);
530 _tbdset.Add(tile + TileOffsByDiagDir(dir), ReverseDiagDir(dir));
531 break;
532 }
533 [[fallthrough]];
534
535 default:
536 /* jump to next tile */
537 tile = tile + TileOffsByDiagDir(dir);
538 dir = ReverseDiagDir(dir);
540 _tbdset.Add(tile, dir);
541 break;
542 }
543 /* happens when removing a rail that wasn't connected at one or both sides */
544 continue; // continue the while() loop
545 }
546
547 assert(!_tbdset.Overflowed()); // it really shouldn't overflow by these one or two items
548 assert(!_tbdset.IsEmpty()); // it wouldn't hurt anyone, but shouldn't happen too
549
550 SigFlags flags = ExploreSegment(owner);
551
552 if (first) {
553 first = false;
554 /* SigSegState::Free is set by default */
555 if (flags.Test(SigFlag::Pbs)) {
556 state = SigSegState::Path;
557 } else if (flags.Test(SigFlag::Train) || (flags.Test(SigFlag::Exit) && !flags.Test(SigFlag::Green)) || flags.Test(SigFlag::Full)) {
558 state = SigSegState::Full;
559 }
560 }
561
562 /* do not do anything when some buffer was full */
563 if (flags.Test(SigFlag::Full)) {
564 ResetSets(); // free all sets
565 break;
566 }
567
569 }
570
571 return state;
572}
573
574
576
577
583{
584 if (!_globset.IsEmpty()) {
586 _last_owner = INVALID_OWNER; // invalidate
587 }
588}
589
590
598void AddTrackToSignalBuffer(TileIndex tile, Track track, Owner owner)
599{
600 static const DiagDirection _search_dir_1[] = {
602 };
603 static const DiagDirection _search_dir_2[] = {
605 };
606
607 /* do not allow signal updates for two companies in one run */
608 assert(_globset.IsEmpty() || owner == _last_owner);
609
610 _last_owner = owner;
611
612 _globset.Add(tile, _search_dir_1[to_underlying(track)]);
613 _globset.Add(tile, _search_dir_2[to_underlying(track)]);
614
615 if (_globset.Items() >= SIG_GLOB_UPDATE) {
616 /* too many items, force update */
619 }
620}
621
622
630void AddSideToSignalBuffer(TileIndex tile, DiagDirection side, Owner owner)
631{
632 /* do not allow signal updates for two companies in one run */
633 assert(_globset.IsEmpty() || owner == _last_owner);
634
635 _last_owner = owner;
636
637 _globset.Add(tile, side);
638
639 if (_globset.Items() >= SIG_GLOB_UPDATE) {
640 /* too many items, force update */
643 }
644}
645
657{
658 assert(_globset.IsEmpty());
659 _globset.Add(tile, side);
660
661 return UpdateSignalsInBuffer(owner);
662}
663
664
674void SetSignalsOnBothDir(TileIndex tile, Track track, Owner owner)
675{
676 assert(_globset.IsEmpty());
677
678 AddTrackToSignalBuffer(tile, track, owner);
680}
uint Count() const
Count the number of set bits.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr bool None() const
Test if none of the values are set.
constexpr Timpl & Set()
Set all bits.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Enum-as-bit-set wrapper.
Iterate a range of enum values.
Definition of stuff that is very close to a company, like the company struct itself.
static constexpr Owner INVALID_OWNER
An invalid owner.
Functions related to debugging.
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
bool IsValidDiagDirection(DiagDirection d)
Checks if an integer value is a valid DiagDirection.
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
EnumIndexArray< T, DiagDirection, DiagDirection::End > DiagDirectionIndexArray
Array with DiagDirection as index.
DiagDirection
Enumeration for diagonal directions.
@ Invalid
Flag for an invalid DiagDirection.
@ SW
Southwest.
@ NW
Northwest.
@ End
Used for iterations.
@ NE
Northeast, upper right on your monitor.
@ SE
Southeast.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp:21
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, RoadTramType sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:574
@ Any
Use first found.
PBS support routines.
bool HasSignalOnTrackdir(Tile tile, Trackdir trackdir)
Checks for the presence of signals along the given trackdir on the given rail tile.
Definition rail_map.h:490
static bool IsRailDepot(Tile t)
Is this rail tile a rail depot?
Definition rail_map.h:95
TrackBits GetTrackBits(Tile tile)
Gets the track bits of the given tile.
Definition rail_map.h:136
bool IsPbsSignal(SignalType s)
Checks whether the given signal is a path based signal.
Definition rail_map.h:291
DiagDirection GetRailDepotDirection(Tile t)
Returns the direction the depot is facing to.
Definition rail_map.h:171
void SetSignalStateByTrackdir(Tile tile, Trackdir trackdir, SignalState state)
Sets the state of the signal along the given trackdir.
Definition rail_map.h:519
bool HasSignalOnTrack(Tile tile, Track track)
Checks for the presence of signals (either way) on the given track on the given rail tile.
Definition rail_map.h:474
bool IsOnewaySignal(Tile t, Track track)
Is the signal at the given track on a tile a one way signal?
Definition rail_map.h:357
bool IsPresignalExit(Tile t, Track track)
Is the signal at the given track on a tile a presignal exit signal?
Definition rail_map.h:344
SignalType GetSignalType(Tile t, Track track)
Get the signal type for a track on a tile.
Definition rail_map.h:303
TrackBits GetRailReservationTrackBits(Tile t)
Returns the reserved track bits of the tile.
Definition rail_map.h:194
bool HasSignals(Tile t)
Checks if a rail tile has signals.
Definition rail_map.h:72
SignalState GetSignalStateByTrackdir(Tile tile, Trackdir trackdir)
Gets the state of the signal along the given trackdir.
Definition rail_map.h:505
bool IsPresignalEntry(Tile t, Track track)
Is the signal at the given track on a tile a presignal entry signal?
Definition rail_map.h:332
Axis GetCrossingRoadAxis(Tile t)
Get the road axis of a level crossing.
Definition road_map.h:335
bool IsLevelCrossing(Tile t)
Return whether a tile is a level crossing.
Definition road_map.h:69
@ Invalid
Invalid marker.
Definition road_type.h:41
A number of safeguards to prevent using unsafe methods.
static bool IsTrainAndNotInDepot(const Vehicle *v)
Check whether there is a train on rail, not in a depot.
Definition signal.cpp:201
static Owner _last_owner
last owner whose track was put into _globset
Definition signal.cpp:575
static bool MaybeAddToTodoSet(TileIndex t1, DiagDirection d1, TileIndex t2, DiagDirection d2)
Perform some operations before adding data into Todo set The new and reverse direction is removed fro...
Definition signal.cpp:244
static constexpr DiagDirectionIndexArray< TrackdirBits > _enterdir_to_trackdirbits
Accessible TrackdirBits from a given enter direction.
Definition signal.cpp:42
static SmallSet< Trackdir, SIG_TBU_SIZE > _tbuset("_tbuset")
set of signals that will be updated
static SmallSet< DiagDirection, SIG_GLOB_SIZE > _globset("_globset")
set of places to be updated in following runs
void AddTrackToSignalBuffer(TileIndex tile, Track track, Owner owner)
Add track to signal update buffer.
Definition signal.cpp:598
SigSegState UpdateSignalsOnSegment(TileIndex tile, DiagDirection side, Owner owner)
Update signals, starting at one side of a tile Will check tile next to this at opposite side too.
Definition signal.cpp:656
void UpdateSignalsInBuffer()
Update signals in buffer Called from 'outside'.
Definition signal.cpp:582
static const uint SIG_TBD_SIZE
number of intersections - open nodes in current block
Definition signal.cpp:27
void AddSideToSignalBuffer(TileIndex tile, DiagDirection side, Owner owner)
Add side of tile to signal update buffer.
Definition signal.cpp:630
static const uint SIG_GLOB_SIZE
number of open blocks (block can be opened more times until detected)
Definition signal.cpp:28
EnumBitSet< SigFlag, uint16_t > SigFlags
Bitset of SigFlag elements.
Definition signal.cpp:267
static void ResetSets()
Reset all sets after one set overflowed.
Definition signal.cpp:473
SigFlag
Current signal block state flags.
Definition signal.cpp:253
@ MultiGreen
two or more green exits found
Definition signal.cpp:258
@ MultiExit
two or more exits found
Definition signal.cpp:256
@ Pbs
pbs signal found
Definition signal.cpp:260
@ MultiEnter
two or more signals entering the block found
Definition signal.cpp:263
@ Split
track merge/split found
Definition signal.cpp:261
@ Full
some of buffers was full, do not continue
Definition signal.cpp:259
@ Green
green exitsignal found
Definition signal.cpp:257
@ Train
train found in segment
Definition signal.cpp:254
@ Enter
signal entering the block found
Definition signal.cpp:262
@ Exit
exitsignal found
Definition signal.cpp:255
static SmallSet< DiagDirection, SIG_TBD_SIZE > _tbdset("_tbdset")
set of open nodes in current signal block
static const uint SIG_TBU_SIZE
these are the maximums used for updating signal blocks
Definition signal.cpp:26
static void UpdateSignalsAroundSegment(SigFlags flags)
Update signals around segment in _tbuset.
Definition signal.cpp:419
void SetSignalsOnBothDir(TileIndex tile, Track track, Owner owner)
Update signals at segments that are at both ends of given (existent or non-existent) track.
Definition signal.cpp:674
static constexpr DiagDirectionIndexArray< TrackBits > _enterdir_to_trackbits
Accessible TrackBits from a given enter direction.
Definition signal.cpp:34
static const uint SIG_GLOB_UPDATE
how many items need to be in _globset to force update
Definition signal.cpp:29
static bool CheckAddToTodoSet(TileIndex t1, DiagDirection d1, TileIndex t2, DiagDirection d2)
Perform some operations before adding data into Todo set The new and reverse direction is removed fro...
Definition signal.cpp:220
static SigFlags ExploreSegment(Owner owner)
Search signal block.
Definition signal.cpp:275
Data related to rail signals.
SigSegState
State of the signal segment.
Definition signal_func.h:55
@ Path
Segment is a path segment.
Definition signal_func.h:58
@ Free
Free and has no pre-signal exits or at least one green exit.
Definition signal_func.h:56
@ Full
Occupied by a train.
Definition signal_func.h:57
SignalType
Type of signal, i.e.
Definition signal_type.h:24
@ Combo
presignal inter-block.
Definition signal_type.h:28
SignalState
These are states in which a signal can be.
Definition signal_type.h:40
@ Green
The signal is green.
Definition signal_type.h:42
@ Red
The signal is red.
Definition signal_type.h:41
Maps accessors for stations.
Axis GetRailStationAxis(Tile t)
Get the rail direction of a rail station.
bool IsStationTileBlocked(Tile t)
Is tile t a blocked tile?
bool HasStationRail(Tile t)
Has this station tile a rail?
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:271
VehicleType type
Type of vehicle.
Element of set.
Definition signal.cpp:62
Set containing 'items' items of 'tile and Tdir' No tree structure is used because it would cause slow...
Definition signal.cpp:55
bool Add(TileIndex tile, Tdir dir)
Adds tile & dir into the set, checks for full set Sets the 'overflowed' flag if the set was full.
Definition signal.cpp:158
SmallSet(std::string_view name)
Constructor - just set default values and 'name'.
Definition signal.cpp:72
uint n
Actual number of units.
Definition signal.cpp:57
const std::string_view name
Name, used for debugging purposes...
Definition signal.cpp:59
bool Overflowed()
Returns value of 'overflowed'.
Definition signal.cpp:85
bool Remove(TileIndex tile, Tdir dir)
Tries to remove first instance of given tile and dir.
Definition signal.cpp:124
bool Get(TileIndex *tile, Tdir *dir)
Reads the last added element into the set.
Definition signal.cpp:179
void Reset()
Reset variables to default values.
Definition signal.cpp:75
uint Items()
Reads the number of items.
Definition signal.cpp:112
bool overflowed
Did we try to overflow the set?
Definition signal.cpp:58
bool IsIn(TileIndex tile, Tdir dir)
Tries to find given tile and dir in the set.
Definition signal.cpp:142
bool IsEmpty()
Checks for empty set.
Definition signal.cpp:94
bool IsFull()
Checks for full set.
Definition signal.cpp:103
static Train * From(Vehicle *v)
'Train' is either a loco or a wagon.
Definition train.h:97
TrackBits track
On which track the train currently is.
Definition train.h:110
Vehicle data structure.
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
Definition tile_map.h:178
static TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:100
@ TunnelBridge
Tunnel entry/exit and bridge heads.
Definition tile_type.h:58
@ Station
A tile of a station or airport.
Definition tile_type.h:54
@ Railway
A tile with railway.
Definition tile_type.h:50
@ Road
A tile with road and/or tram tracks.
Definition tile_type.h:51
Track TrackdirToTrack(Trackdir trackdir)
Returns the Track that a given Trackdir represents.
Definition track_func.h:235
TrackdirBits TrackBitsToTrackdirBits(TrackBits bits)
Converts TrackBits to TrackdirBits while allowing both directions.
Definition track_func.h:292
Track TrackBitsToTrack(TrackBits tracks)
Converts TrackBits to Track.
Definition track_func.h:166
Trackdir ReverseTrackdir(Trackdir trackdir)
Maps a trackdir to the reverse trackdir.
Definition track_func.h:220
DiagDirection TrackdirToExitdir(Trackdir trackdir)
Maps a trackdir to the (4-way) direction the tile is exited when following that trackdir.
Definition track_func.h:343
TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
Discards all directional information from a TrackdirBits value.
Definition track_func.h:281
static constexpr TrackBits TRACK_BIT_3WAY_NE
"Arrow" to the north-east
Definition track_type.h:48
static constexpr TrackBits TRACK_BIT_HORZ
Upper and lower track.
Definition track_type.h:46
EnumBitSet< Track, uint8_t > TrackBits
Bitset of Track elements.
Definition track_type.h:43
Trackdir
Enumeration for tracks and directions.
Definition track_type.h:63
@ Right_N
Right track and direction to north.
Definition track_type.h:77
@ X_NE
X-axis and direction to north-east.
Definition track_type.h:64
@ Right_S
Right track and direction to south.
Definition track_type.h:69
@ Left_S
Left track and direction to south.
Definition track_type.h:68
@ Lower_E
Lower track and direction to east.
Definition track_type.h:67
@ X_SW
X-axis and direction to south-west.
Definition track_type.h:72
@ Invalid
Flag for an invalid trackdir.
Definition track_type.h:82
@ Y_SE
Y-axis and direction to south-east.
Definition track_type.h:65
@ Y_NW
Y-axis and direction to north-west.
Definition track_type.h:73
@ Upper_W
Upper track and direction to west.
Definition track_type.h:74
@ Upper_E
Upper track and direction to east.
Definition track_type.h:66
@ Left_N
Left track and direction to north.
Definition track_type.h:76
@ Lower_W
Lower track and direction to west.
Definition track_type.h:75
static constexpr TrackBits TRACK_BIT_VERT
Left and right track.
Definition track_type.h:47
static constexpr TrackBits TRACK_BIT_3WAY_SW
"Arrow" to the south-west
Definition track_type.h:50
static constexpr TrackBits TRACK_BIT_3WAY_SE
"Arrow" to the south-east
Definition track_type.h:49
static constexpr TrackBits TRACK_BIT_3WAY_NW
"Arrow" to the north-west
Definition track_type.h:51
Track
These are used to specify a single track.
Definition track_type.h:19
@ Depot
Special flag indicating a vehicle is inside a depot.
Definition track_type.h:30
Base for the train class.
@ TRANSPORT_RAIL
Transport by train.
Functions that have tunnels and bridges in common.
DiagDirection GetTunnelBridgeDirection(Tile t)
Get the direction pointing to the other end.
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
TileIndex GetOtherTunnelBridgeEnd(Tile t)
Determines type of the wormhole and returns its other end.
CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits)
Tests if a vehicle interacts with the specified track bits.
Definition vehicle.cpp:605
Functions related to vehicles.
bool HasVehicleOnTile(TileIndex tile, UnaryPred &&predicate)
Loop over vehicles on a tile, and check whether a predicate is true for any of them.
@ Train
Train vehicle type.
Functions related to (drawing on) viewports.