OpenTTD Source  1.11.2
yapf_node_rail.hpp
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 <http://www.gnu.org/licenses/>.
6  */
7 
10 #ifndef YAPF_NODE_RAIL_HPP
11 #define YAPF_NODE_RAIL_HPP
12 
15 {
16  uint32 m_value;
17 
18  inline CYapfRailSegmentKey(const CYapfRailSegmentKey &src) : m_value(src.m_value) {}
19 
20  inline CYapfRailSegmentKey(const CYapfNodeKeyTrackDir &node_key)
21  {
22  Set(node_key);
23  }
24 
25  inline void Set(const CYapfRailSegmentKey &src)
26  {
27  m_value = src.m_value;
28  }
29 
30  inline void Set(const CYapfNodeKeyTrackDir &node_key)
31  {
32  m_value = (((int)node_key.m_tile) << 4) | node_key.m_td;
33  }
34 
35  inline int32 CalcHash() const
36  {
37  return m_value;
38  }
39 
40  inline TileIndex GetTile() const
41  {
42  return (TileIndex)(m_value >> 4);
43  }
44 
45  inline Trackdir GetTrackdir() const
46  {
47  return (Trackdir)(m_value & 0x0F);
48  }
49 
50  inline bool operator==(const CYapfRailSegmentKey &other) const
51  {
52  return m_value == other.m_value;
53  }
54 
55  void Dump(DumpTarget &dmp) const
56  {
57  dmp.WriteTile("tile", GetTile());
58  dmp.WriteEnumT("td", GetTrackdir());
59  }
60 };
61 
64 {
65  typedef CYapfRailSegmentKey Key;
66 
67  CYapfRailSegmentKey m_key;
68  TileIndex m_last_tile;
69  Trackdir m_last_td;
70  int m_cost;
71  TileIndex m_last_signal_tile;
72  Trackdir m_last_signal_td;
73  EndSegmentReasonBits m_end_segment_reason;
74  CYapfRailSegment *m_hash_next;
75 
76  inline CYapfRailSegment(const CYapfRailSegmentKey &key)
77  : m_key(key)
78  , m_last_tile(INVALID_TILE)
79  , m_last_td(INVALID_TRACKDIR)
80  , m_cost(-1)
81  , m_last_signal_tile(INVALID_TILE)
82  , m_last_signal_td(INVALID_TRACKDIR)
83  , m_end_segment_reason(ESRB_NONE)
84  , m_hash_next(nullptr)
85  {}
86 
87  inline const Key& GetKey() const
88  {
89  return m_key;
90  }
91 
92  inline TileIndex GetTile() const
93  {
94  return m_key.GetTile();
95  }
96 
97  inline CYapfRailSegment *GetHashNext()
98  {
99  return m_hash_next;
100  }
101 
102  inline void SetHashNext(CYapfRailSegment *next)
103  {
104  m_hash_next = next;
105  }
106 
107  void Dump(DumpTarget &dmp) const
108  {
109  dmp.WriteStructT("m_key", &m_key);
110  dmp.WriteTile("m_last_tile", m_last_tile);
111  dmp.WriteEnumT("m_last_td", m_last_td);
112  dmp.WriteLine("m_cost = %d", m_cost);
113  dmp.WriteTile("m_last_signal_tile", m_last_signal_tile);
114  dmp.WriteEnumT("m_last_signal_td", m_last_signal_td);
115  dmp.WriteEnumT("m_end_segment_reason", m_end_segment_reason);
116  }
117 };
118 
120 template <class Tkey_>
122  : CYapfNodeT<Tkey_, CYapfRailNodeT<Tkey_> >
123 {
126 
127  CYapfRailSegment *m_segment;
128  uint16 m_num_signals_passed;
129  union {
130  uint32 m_inherited_flags;
131  struct {
132  bool m_targed_seen : 1;
133  bool m_choice_seen : 1;
134  bool m_last_signal_was_red : 1;
135  } flags_s;
136  } flags_u;
137  SignalType m_last_red_signal_type;
138  SignalType m_last_signal_type;
139 
140  inline void Set(CYapfRailNodeT *parent, TileIndex tile, Trackdir td, bool is_choice)
141  {
142  base::Set(parent, tile, td, is_choice);
143  m_segment = nullptr;
144  if (parent == nullptr) {
145  m_num_signals_passed = 0;
146  flags_u.m_inherited_flags = 0;
147  m_last_red_signal_type = SIGTYPE_NORMAL;
148  /* We use PBS as initial signal type because if we are in
149  * a PBS section and need to route, i.e. we're at a safe
150  * waiting point of a station, we need to account for the
151  * reservation costs. If we are in a normal block then we
152  * should be alone in there and as such the reservation
153  * costs should be 0 anyway. If there would be another
154  * train in the block, i.e. passing signals at danger
155  * then avoiding that train with help of the reservation
156  * costs is not a bad thing, actually it would probably
157  * be a good thing to do. */
158  m_last_signal_type = SIGTYPE_PBS;
159  } else {
160  m_num_signals_passed = parent->m_num_signals_passed;
161  flags_u.m_inherited_flags = parent->flags_u.m_inherited_flags;
162  m_last_red_signal_type = parent->m_last_red_signal_type;
163  m_last_signal_type = parent->m_last_signal_type;
164  }
165  flags_u.flags_s.m_choice_seen |= is_choice;
166  }
167 
168  inline TileIndex GetLastTile() const
169  {
170  assert(m_segment != nullptr);
171  return m_segment->m_last_tile;
172  }
173 
174  inline Trackdir GetLastTrackdir() const
175  {
176  assert(m_segment != nullptr);
177  return m_segment->m_last_td;
178  }
179 
180  inline void SetLastTileTrackdir(TileIndex tile, Trackdir td)
181  {
182  assert(m_segment != nullptr);
183  m_segment->m_last_tile = tile;
184  m_segment->m_last_td = td;
185  }
186 
187  template <class Tbase, class Tfunc, class Tpf>
188  bool IterateTiles(const Train *v, Tpf &yapf, Tbase &obj, bool (Tfunc::*func)(TileIndex, Trackdir)) const
189  {
190  typename Tbase::TrackFollower ft(v, yapf.GetCompatibleRailTypes());
191  TileIndex cur = base::GetTile();
192  Trackdir cur_td = base::GetTrackdir();
193 
194  while (cur != GetLastTile() || cur_td != GetLastTrackdir()) {
195  if (!((obj.*func)(cur, cur_td))) return false;
196 
197  if (!ft.Follow(cur, cur_td)) break;
198  cur = ft.m_new_tile;
199  assert(KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE);
200  cur_td = FindFirstTrackdir(ft.m_new_td_bits);
201  }
202 
203  return (obj.*func)(cur, cur_td);
204  }
205 
206  void Dump(DumpTarget &dmp) const
207  {
208  base::Dump(dmp);
209  dmp.WriteStructT("m_segment", m_segment);
210  dmp.WriteLine("m_num_signals_passed = %d", m_num_signals_passed);
211  dmp.WriteLine("m_targed_seen = %s", flags_u.flags_s.m_targed_seen ? "Yes" : "No");
212  dmp.WriteLine("m_choice_seen = %s", flags_u.flags_s.m_choice_seen ? "Yes" : "No");
213  dmp.WriteLine("m_last_signal_was_red = %s", flags_u.flags_s.m_last_signal_was_red ? "Yes" : "No");
214  dmp.WriteEnumT("m_last_red_signal_type", m_last_red_signal_type);
215  }
216 };
217 
218 /* now define two major node types (that differ by key type) */
221 
222 /* Default NodeList types */
225 
226 #endif /* YAPF_NODE_RAIL_HPP */
FindFirstTrackdir
static Trackdir FindFirstTrackdir(TrackdirBits trackdirs)
Returns first Trackdir from TrackdirBits or INVALID_TRACKDIR.
Definition: track_func.h:219
TileIndex
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:83
CYapfRailNodeT
Yapf Node for rail YAPF.
Definition: yapf_node_rail.hpp:121
DumpTarget::WriteEnumT
void WriteEnumT(const char *name, E e)
Dump given enum value (as a number and as named value)
Definition: dbg_helpers.h:143
KillFirstBit
static T KillFirstBit(T value)
Clear the first bit in an integer.
Definition: bitmath_func.hpp:239
DumpTarget::WriteLine
void CDECL WriteLine(const char *format,...) WARN_FORMAT(2
Write a line with indent at the beginning and <LF> at the end.
Definition: dbg_helpers.cpp:119
DumpTarget::WriteTile
void WriteTile(const char *name, TileIndex t)
Write name & TileIndex to the output.
Definition: dbg_helpers.cpp:137
SignalType
SignalType
Type of signal, i.e.
Definition: signal_type.h:23
SIGTYPE_PBS
@ SIGTYPE_PBS
normal pbs signal
Definition: signal_type.h:28
SIGTYPE_NORMAL
@ SIGTYPE_NORMAL
normal signal
Definition: signal_type.h:24
DumpTarget
Class that represents the dump-into-string target.
Definition: dbg_helpers.h:94
Train
'Train' is either a loco or a wagon.
Definition: train.h:85
CNodeList_HashTableT
Hash table based node list multi-container class.
Definition: nodelist.hpp:23
CYapfNodeT
Yapf Node base.
Definition: yapf_node.hpp:59
INVALID_TRACKDIR
@ INVALID_TRACKDIR
Flag for an invalid trackdir.
Definition: track_type.h:89
DumpTarget::WriteStructT
void WriteStructT(const char *name, const S *s)
Dump nested object (or only its name if this instance is already known).
Definition: dbg_helpers.h:152
TRACKDIR_BIT_NONE
@ TRACKDIR_BIT_NONE
No track build.
Definition: track_type.h:102
CYapfNodeKeyTrackDir
Definition: yapf_node.hpp:44
CYapfRailSegment
cached segment cost for rail YAPF
Definition: yapf_node_rail.hpp:63
INVALID_TILE
static const TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:88
Trackdir
Trackdir
Enumeration for tracks and directions.
Definition: track_type.h:70
CYapfRailSegmentKey
key for cached segment cost for rail YAPF
Definition: yapf_node_rail.hpp:14