Files
@ r8616:656db5986c9e
Branch filter:
Location: cpp/openttd-patchpack/source/src/yapf/yapf_common.hpp
r8616:656db5986c9e
6.4 KiB
text/x-c++hdr
(svn r12199) -Codechange: Remove magic around the results of GetTileTrackStatus().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | /* $Id$ */
/** @file yapf_common.hpp */
#ifndef YAPF_COMMON_HPP
#define YAPF_COMMON_HPP
/** YAPF origin provider base class - used when origin is one tile / multiple trackdirs */
template <class Types>
class CYapfOriginTileT
{
public:
typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
typedef typename Types::NodeList::Titem Node; ///< this will be our node type
typedef typename Node::Key Key; ///< key to hash tables
protected:
TileIndex m_orgTile; ///< origin tile
TrackdirBits m_orgTrackdirs; ///< origin trackdir mask
/// to access inherited path finder
FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
public:
/// Set origin tile / trackdir mask
void SetOrigin(TileIndex tile, TrackdirBits trackdirs)
{
m_orgTile = tile;
m_orgTrackdirs = trackdirs;
}
/// Called when YAPF needs to place origin nodes into open list
void PfSetStartupNodes()
{
bool is_choice = (KillFirstBit(m_orgTrackdirs) != TRACKDIR_BIT_NONE);
for (TrackdirBits tdb = m_orgTrackdirs; tdb != TRACKDIR_BIT_NONE; tdb = KillFirstBit(tdb)) {
Trackdir td = (Trackdir)FindFirstBit2x64(tdb);
Node& n1 = Yapf().CreateNewNode();
n1.Set(NULL, m_orgTile, td, is_choice);
Yapf().AddStartupNode(n1);
}
}
};
/** YAPF origin provider base class - used when there are two tile/trackdir origins */
template <class Types>
class CYapfOriginTileTwoWayT
{
public:
typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
typedef typename Types::NodeList::Titem Node; ///< this will be our node type
typedef typename Node::Key Key; ///< key to hash tables
protected:
TileIndex m_orgTile; ///< first origin tile
Trackdir m_orgTd; ///< first origin trackdir
TileIndex m_revTile; ///< second (reversed) origin tile
Trackdir m_revTd; ///< second (reversed) origin trackdir
int m_reverse_penalty; ///< penalty to be added for using the reversed origin
bool m_treat_first_red_two_way_signal_as_eol; ///< in some cases (leaving station) we need to handle first two-way signal differently
/// to access inherited path finder
FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
public:
/// set origin (tiles, trackdirs, etc.)
void SetOrigin(TileIndex tile, Trackdir td, TileIndex tiler = INVALID_TILE, Trackdir tdr = INVALID_TRACKDIR, int reverse_penalty = 0, bool treat_first_red_two_way_signal_as_eol = true)
{
m_orgTile = tile;
m_orgTd = td;
m_revTile = tiler;
m_revTd = tdr;
m_reverse_penalty = reverse_penalty;
m_treat_first_red_two_way_signal_as_eol = treat_first_red_two_way_signal_as_eol;
}
/// Called when YAPF needs to place origin nodes into open list
void PfSetStartupNodes()
{
if (m_orgTile != INVALID_TILE && m_orgTd != INVALID_TRACKDIR) {
Node& n1 = Yapf().CreateNewNode();
n1.Set(NULL, m_orgTile, m_orgTd, false);
Yapf().AddStartupNode(n1);
}
if (m_revTile != INVALID_TILE && m_revTd != INVALID_TRACKDIR) {
Node& n2 = Yapf().CreateNewNode();
n2.Set(NULL, m_revTile, m_revTd, false);
n2.m_cost = m_reverse_penalty;
Yapf().AddStartupNode(n2);
}
}
/// return true if first two-way signal should be treated as dead end
FORCEINLINE bool TreatFirstRedTwoWaySignalAsEOL()
{
return Yapf().PfGetSettings().rail_firstred_twoway_eol && m_treat_first_red_two_way_signal_as_eol;
}
};
/** YAPF destination provider base class - used when destination is single tile / multiple trackdirs */
template <class Types>
class CYapfDestinationTileT
{
public:
typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
typedef typename Types::NodeList::Titem Node; ///< this will be our node type
typedef typename Node::Key Key; ///< key to hash tables
protected:
TileIndex m_destTile; ///< destination tile
TrackdirBits m_destTrackdirs; ///< destination trackdir mask
public:
/// set the destination tile / more trackdirs
void SetDestination(TileIndex tile, TrackdirBits trackdirs)
{
m_destTile = tile;
m_destTrackdirs = trackdirs;
}
protected:
/// to access inherited path finder
Tpf& Yapf() {return *static_cast<Tpf*>(this);}
public:
/// Called by YAPF to detect if node ends in the desired destination
FORCEINLINE bool PfDetectDestination(Node& n)
{
bool bDest = (n.m_key.m_tile == m_destTile) && ((m_destTrackdirs & TrackdirToTrackdirBits(n.GetTrackdir())) != TRACKDIR_BIT_NONE);
return bDest;
}
/** Called by YAPF to calculate cost estimate. Calculates distance to the destination
* adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
inline bool PfCalcEstimate(Node& n)
{
static int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
static int dg_dir_to_y_offs[] = {0, 1, 0, -1};
if (PfDetectDestination(n)) {
n.m_estimate = n.m_cost;
return true;
}
TileIndex tile = n.GetTile();
DiagDirection exitdir = TrackdirToExitdir(n.GetTrackdir());
int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
int x2 = 2 * TileX(m_destTile);
int y2 = 2 * TileY(m_destTile);
int dx = abs(x1 - x2);
int dy = abs(y1 - y2);
int dmin = min(dx, dy);
int dxy = abs(dx - dy);
int d = dmin * 7 + (dxy - 1) * (10 / 2);
n.m_estimate = n.m_cost + d;
assert(n.m_estimate >= n.m_parent->m_estimate);
return true;
}
};
/** YAPF template that uses Ttypes template argument to determine all YAPF
* components (base classes) from which the actual YAPF is composed.
* For example classes consult: CYapfRail_TypesT template and its instantiations:
* CYapfRail1, CYapfRail2, CYapfRail3, CYapfAnyDepotRail1, CYapfAnyDepotRail2, CYapfAnyDepotRail3 */
template <class Ttypes>
class CYapfT
: public Ttypes::PfBase ///< Instance of CYapfBaseT - main YAPF loop and support base class
, public Ttypes::PfCost ///< Cost calculation provider base class
, public Ttypes::PfCache ///< Segment cost cache provider
, public Ttypes::PfOrigin ///< Origin (tile or two-tile origin)
, public Ttypes::PfDestination ///< Destination detector and distance (estimate) calculation provider
, public Ttypes::PfFollow ///< Node follower (stepping provider)
{
};
#endif /* YAPF_COMMON_HPP */
|