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 */

Generated on Mon May 11 15:48:09 2009 for OpenTTD by  doxygen 1.5.6