# yapf_common.hpp

Go to the documentation of this file.

    00001 /* $Id: yapf_common.hpp 15903 2009-03-30 23:15:05Z rubidium $ */
    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()
    00023   {
    00024     return *static_cast<Tpf*>(this);
    00025   }
    00026
    00027 public:
    00029   void SetOrigin(TileIndex tile, TrackdirBits trackdirs)
    00030   {
    00031     m_orgTile = tile;
    00032     m_orgTrackdirs = trackdirs;
    00033   }
    00034
    00036   void PfSetStartupNodes()
    00037   {
    00038     bool is_choice = (KillFirstBit(m_orgTrackdirs) != TRACKDIR_BIT_NONE);
    00039     for (TrackdirBits tdb = m_orgTrackdirs; tdb != TRACKDIR_BIT_NONE; tdb = KillFirstBit(tdb)) {
    00040       Trackdir td = (Trackdir)FindFirstBit2x64(tdb);
    00041       Node& n1 = Yapf().CreateNewNode();
    00042       n1.Set(NULL, m_orgTile, td, is_choice);
    00043       Yapf().AddStartupNode(n1);
    00044     }
    00045   }
    00046 };
    00047
    00049 template <class Types>
    00050 class CYapfOriginTileTwoWayT
    00051 {
    00052 public:
    00053   typedef typename Types::Tpf Tpf;
    00054   typedef typename Types::NodeList::Titem Node;
    00055   typedef typename Node::Key Key;
    00056
    00057 protected:
    00058   TileIndex   m_orgTile;
    00059   Trackdir    m_orgTd;
    00060   TileIndex   m_revTile;
    00061   Trackdir    m_revTd;
    00062   int         m_reverse_penalty;
    00063   bool        m_treat_first_red_two_way_signal_as_eol;
    00064
    00066   FORCEINLINE Tpf& Yapf()
    00067   {
    00068     return *static_cast<Tpf*>(this);
    00069   }
    00070
    00071 public:
    00073   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)
    00074   {
    00075     m_orgTile = tile;
    00076     m_orgTd = td;
    00077     m_revTile = tiler;
    00078     m_revTd = tdr;
    00079     m_reverse_penalty = reverse_penalty;
    00080     m_treat_first_red_two_way_signal_as_eol = treat_first_red_two_way_signal_as_eol;
    00081   }
    00082
    00084   void PfSetStartupNodes()
    00085   {
    00086     if (m_orgTile != INVALID_TILE && m_orgTd != INVALID_TRACKDIR) {
    00087       Node& n1 = Yapf().CreateNewNode();
    00088       n1.Set(NULL, m_orgTile, m_orgTd, false);
    00089       Yapf().AddStartupNode(n1);
    00090     }
    00091     if (m_revTile != INVALID_TILE && m_revTd != INVALID_TRACKDIR) {
    00092       Node& n2 = Yapf().CreateNewNode();
    00093       n2.Set(NULL, m_revTile, m_revTd, false);
    00094       n2.m_cost = m_reverse_penalty;
    00095       Yapf().AddStartupNode(n2);
    00096     }
    00097   }
    00098
    00100   FORCEINLINE bool TreatFirstRedTwoWaySignalAsEOL()
    00101   {
    00102     return Yapf().PfGetSettings().rail_firstred_twoway_eol && m_treat_first_red_two_way_signal_as_eol;
    00103   }
    00104 };
    00105
    00107 template <class Types>
    00108 class CYapfDestinationTileT
    00109 {
    00110 public:
    00111   typedef typename Types::Tpf Tpf;
    00112   typedef typename Types::NodeList::Titem Node;
    00113   typedef typename Node::Key Key;
    00114
    00115 protected:
    00116   TileIndex    m_destTile;
    00117   TrackdirBits m_destTrackdirs;
    00118
    00119 public:
    00121   void SetDestination(TileIndex tile, TrackdirBits trackdirs)
    00122   {
    00123     m_destTile = tile;
    00124     m_destTrackdirs = trackdirs;
    00125   }
    00126
    00127 protected:
    00129   Tpf& Yapf()
    00130   {
    00131     return *static_cast<Tpf*>(this);
    00132   }
    00133
    00134 public:
    00136   FORCEINLINE bool PfDetectDestination(Node& n)
    00137   {
    00138     bool bDest = (n.m_key.m_tile == m_destTile) && ((m_destTrackdirs & TrackdirToTrackdirBits(n.GetTrackdir())) != TRACKDIR_BIT_NONE);
    00139     return bDest;
    00140   }
    00141
    00144   inline bool PfCalcEstimate(Node& n)
    00145   {
    00146     static int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
    00147     static int dg_dir_to_y_offs[] = {0, 1, 0, -1};
    00148     if (PfDetectDestination(n)) {
    00149       n.m_estimate = n.m_cost;
    00150       return true;
    00151     }
    00152
    00153     TileIndex tile = n.GetTile();
    00154     DiagDirection exitdir = TrackdirToExitdir(n.GetTrackdir());
    00155     int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
    00156     int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
    00157     int x2 = 2 * TileX(m_destTile);
    00158     int y2 = 2 * TileY(m_destTile);
    00159     int dx = abs(x1 - x2);
    00160     int dy = abs(y1 - y2);
    00161     int dmin = min(dx, dy);
    00162     int dxy = abs(dx - dy);
    00163     int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
    00164     n.m_estimate = n.m_cost + d;
    00165     assert(n.m_estimate >= n.m_parent->m_estimate);
    00166     return true;
    00167   }
    00168 };
    00169
    00174 template <class Ttypes>
    00175 class CYapfT
    00176   : public Ttypes::PfBase
    00177   , public Ttypes::PfCost
    00178   , public Ttypes::PfCache
    00179   , public Ttypes::PfOrigin
    00180   , public Ttypes::PfDestination
    00181   , public Ttypes::PfFollow
    00182 {
    00183 };
    00184
    00185
    00186
    00187 #endif /* YAPF_COMMON_HPP */