# yapf_common.hpp

Go to the documentation of this file.

    00001 /* $Id: yapf_common.hpp 12971 2008-05-06 15:11:33Z 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() {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 /* YAPF_COMMON_HPP */