yapf_common.hpp
Go to the documentation of this file.00001
00002
00005 #ifndef YAPF_COMMON_HPP
00006 #define YAPF_COMMON_HPP
00007
00009 template <class Types>
00010 class CYapfOriginTileT
00011 {
00012 public:
00013 typedef typename Types::Tpf Tpf;
00014 typedef typename Types::NodeList::Titem Node;
00015 typedef typename Node::Key Key;
00016
00017 protected:
00018 TileIndex m_orgTile;
00019 TrackdirBits m_orgTrackdirs;
00020
00022 FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
00023
00024 public:
00026 void SetOrigin(TileIndex tile, TrackdirBits trackdirs)
00027 {
00028 m_orgTile = tile;
00029 m_orgTrackdirs = trackdirs;
00030 }
00031
00033 void PfSetStartupNodes()
00034 {
00035 bool is_choice = (KillFirstBit(m_orgTrackdirs) != TRACKDIR_BIT_NONE);
00036 for (TrackdirBits tdb = m_orgTrackdirs; tdb != TRACKDIR_BIT_NONE; tdb = KillFirstBit(tdb)) {
00037 Trackdir td = (Trackdir)FindFirstBit2x64(tdb);
00038 Node& n1 = Yapf().CreateNewNode();
00039 n1.Set(NULL, m_orgTile, td, is_choice);
00040 Yapf().AddStartupNode(n1);
00041 }
00042 }
00043 };
00044
00046 template <class Types>
00047 class CYapfOriginTileTwoWayT
00048 {
00049 public:
00050 typedef typename Types::Tpf Tpf;
00051 typedef typename Types::NodeList::Titem Node;
00052 typedef typename Node::Key Key;
00053
00054 protected:
00055 TileIndex m_orgTile;
00056 Trackdir m_orgTd;
00057 TileIndex m_revTile;
00058 Trackdir m_revTd;
00059 int m_reverse_penalty;
00060 bool m_treat_first_red_two_way_signal_as_eol;
00061
00063 FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
00064
00065 public:
00067 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)
00068 {
00069 m_orgTile = tile;
00070 m_orgTd = td;
00071 m_revTile = tiler;
00072 m_revTd = tdr;
00073 m_reverse_penalty = reverse_penalty;
00074 m_treat_first_red_two_way_signal_as_eol = treat_first_red_two_way_signal_as_eol;
00075 }
00076
00078 void PfSetStartupNodes()
00079 {
00080 if (m_orgTile != INVALID_TILE && m_orgTd != INVALID_TRACKDIR) {
00081 Node& n1 = Yapf().CreateNewNode();
00082 n1.Set(NULL, m_orgTile, m_orgTd, false);
00083 Yapf().AddStartupNode(n1);
00084 }
00085 if (m_revTile != INVALID_TILE && m_revTd != INVALID_TRACKDIR) {
00086 Node& n2 = Yapf().CreateNewNode();
00087 n2.Set(NULL, m_revTile, m_revTd, false);
00088 n2.m_cost = m_reverse_penalty;
00089 Yapf().AddStartupNode(n2);
00090 }
00091 }
00092
00094 FORCEINLINE bool TreatFirstRedTwoWaySignalAsEOL()
00095 {
00096 return Yapf().PfGetSettings().rail_firstred_twoway_eol && m_treat_first_red_two_way_signal_as_eol;
00097 }
00098 };
00099
00101 template <class Types>
00102 class CYapfDestinationTileT
00103 {
00104 public:
00105 typedef typename Types::Tpf Tpf;
00106 typedef typename Types::NodeList::Titem Node;
00107 typedef typename Node::Key Key;
00108
00109 protected:
00110 TileIndex m_destTile;
00111 TrackdirBits m_destTrackdirs;
00112
00113 public:
00115 void SetDestination(TileIndex tile, TrackdirBits trackdirs)
00116 {
00117 m_destTile = tile;
00118 m_destTrackdirs = trackdirs;
00119 }
00120
00121 protected:
00123 Tpf& Yapf() {return *static_cast<Tpf*>(this);}
00124
00125 public:
00127 FORCEINLINE bool PfDetectDestination(Node& n)
00128 {
00129 bool bDest = (n.m_key.m_tile == m_destTile) && ((m_destTrackdirs & TrackdirToTrackdirBits(n.GetTrackdir())) != TRACKDIR_BIT_NONE);
00130 return bDest;
00131 }
00132
00135 inline bool PfCalcEstimate(Node& n)
00136 {
00137 static int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
00138 static int dg_dir_to_y_offs[] = {0, 1, 0, -1};
00139 if (PfDetectDestination(n)) {
00140 n.m_estimate = n.m_cost;
00141 return true;
00142 }
00143
00144 TileIndex tile = n.GetTile();
00145 DiagDirection exitdir = TrackdirToExitdir(n.GetTrackdir());
00146 int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
00147 int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
00148 int x2 = 2 * TileX(m_destTile);
00149 int y2 = 2 * TileY(m_destTile);
00150 int dx = abs(x1 - x2);
00151 int dy = abs(y1 - y2);
00152 int dmin = min(dx, dy);
00153 int dxy = abs(dx - dy);
00154 int d = dmin * 7 + (dxy - 1) * (10 / 2);
00155 n.m_estimate = n.m_cost + d;
00156 assert(n.m_estimate >= n.m_parent->m_estimate);
00157 return true;
00158 }
00159 };
00160
00165 template <class Ttypes>
00166 class CYapfT
00167 : public Ttypes::PfBase
00168 , public Ttypes::PfCost
00169 , public Ttypes::PfCache
00170 , public Ttypes::PfOrigin
00171 , public Ttypes::PfDestination
00172 , public Ttypes::PfFollow
00173 {
00174 };
00175
00176
00177
00178 #endif