yapf_common.hpp

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #ifndef YAPF_COMMON_HPP
00013 #define YAPF_COMMON_HPP
00014 
00016 template <class Types>
00017 class CYapfOriginTileT
00018 {
00019 public:
00020   typedef typename Types::Tpf Tpf;              
00021   typedef typename Types::NodeList::Titem Node; 
00022   typedef typename Node::Key Key;               
00023 
00024 protected:
00025   TileIndex    m_orgTile;                       
00026   TrackdirBits m_orgTrackdirs;                  
00027 
00029   FORCEINLINE Tpf& Yapf()
00030   {
00031     return *static_cast<Tpf*>(this);
00032   }
00033 
00034 public:
00036   void SetOrigin(TileIndex tile, TrackdirBits trackdirs)
00037   {
00038     m_orgTile = tile;
00039     m_orgTrackdirs = trackdirs;
00040   }
00041 
00043   void PfSetStartupNodes()
00044   {
00045     bool is_choice = (KillFirstBit(m_orgTrackdirs) != TRACKDIR_BIT_NONE);
00046     for (TrackdirBits tdb = m_orgTrackdirs; tdb != TRACKDIR_BIT_NONE; tdb = KillFirstBit(tdb)) {
00047       Trackdir td = (Trackdir)FindFirstBit2x64(tdb);
00048       Node& n1 = Yapf().CreateNewNode();
00049       n1.Set(NULL, m_orgTile, td, is_choice);
00050       Yapf().AddStartupNode(n1);
00051     }
00052   }
00053 };
00054 
00056 template <class Types>
00057 class CYapfOriginTileTwoWayT
00058 {
00059 public:
00060   typedef typename Types::Tpf Tpf;              
00061   typedef typename Types::NodeList::Titem Node; 
00062   typedef typename Node::Key Key;               
00063 
00064 protected:
00065   TileIndex   m_orgTile;                        
00066   Trackdir    m_orgTd;                          
00067   TileIndex   m_revTile;                        
00068   Trackdir    m_revTd;                          
00069   int         m_reverse_penalty;                
00070   bool        m_treat_first_red_two_way_signal_as_eol; 
00071 
00073   FORCEINLINE Tpf& Yapf()
00074   {
00075     return *static_cast<Tpf*>(this);
00076   }
00077 
00078 public:
00080   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)
00081   {
00082     m_orgTile = tile;
00083     m_orgTd = td;
00084     m_revTile = tiler;
00085     m_revTd = tdr;
00086     m_reverse_penalty = reverse_penalty;
00087     m_treat_first_red_two_way_signal_as_eol = treat_first_red_two_way_signal_as_eol;
00088   }
00089 
00091   void PfSetStartupNodes()
00092   {
00093     if (m_orgTile != INVALID_TILE && m_orgTd != INVALID_TRACKDIR) {
00094       Node& n1 = Yapf().CreateNewNode();
00095       n1.Set(NULL, m_orgTile, m_orgTd, false);
00096       Yapf().AddStartupNode(n1);
00097     }
00098     if (m_revTile != INVALID_TILE && m_revTd != INVALID_TRACKDIR) {
00099       Node& n2 = Yapf().CreateNewNode();
00100       n2.Set(NULL, m_revTile, m_revTd, false);
00101       n2.m_cost = m_reverse_penalty;
00102       Yapf().AddStartupNode(n2);
00103     }
00104   }
00105 
00107   FORCEINLINE bool TreatFirstRedTwoWaySignalAsEOL()
00108   {
00109     return Yapf().PfGetSettings().rail_firstred_twoway_eol && m_treat_first_red_two_way_signal_as_eol;
00110   }
00111 };
00112 
00114 template <class Types>
00115 class CYapfDestinationTileT
00116 {
00117 public:
00118   typedef typename Types::Tpf Tpf;              
00119   typedef typename Types::NodeList::Titem Node; 
00120   typedef typename Node::Key Key;               
00121 
00122 protected:
00123   TileIndex    m_destTile;                      
00124   TrackdirBits m_destTrackdirs;                 
00125 
00126 public:
00128   void SetDestination(TileIndex tile, TrackdirBits trackdirs)
00129   {
00130     m_destTile = tile;
00131     m_destTrackdirs = trackdirs;
00132   }
00133 
00134 protected:
00136   Tpf& Yapf()
00137   {
00138     return *static_cast<Tpf*>(this);
00139   }
00140 
00141 public:
00143   FORCEINLINE bool PfDetectDestination(Node& n)
00144   {
00145     bool bDest = (n.m_key.m_tile == m_destTile) && ((m_destTrackdirs & TrackdirToTrackdirBits(n.GetTrackdir())) != TRACKDIR_BIT_NONE);
00146     return bDest;
00147   }
00148 
00153   inline bool PfCalcEstimate(Node& n)
00154   {
00155     static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
00156     static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
00157     if (PfDetectDestination(n)) {
00158       n.m_estimate = n.m_cost;
00159       return true;
00160     }
00161 
00162     TileIndex tile = n.GetTile();
00163     DiagDirection exitdir = TrackdirToExitdir(n.GetTrackdir());
00164     int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
00165     int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
00166     int x2 = 2 * TileX(m_destTile);
00167     int y2 = 2 * TileY(m_destTile);
00168     int dx = abs(x1 - x2);
00169     int dy = abs(y1 - y2);
00170     int dmin = min(dx, dy);
00171     int dxy = abs(dx - dy);
00172     int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
00173     n.m_estimate = n.m_cost + d;
00174     assert(n.m_estimate >= n.m_parent->m_estimate);
00175     return true;
00176   }
00177 };
00178 
00185 template <class Ttypes>
00186 class CYapfT
00187   : public Ttypes::PfBase         
00188   , public Ttypes::PfCost         
00189   , public Ttypes::PfCache        
00190   , public Ttypes::PfOrigin       
00191   , public Ttypes::PfDestination  
00192   , public Ttypes::PfFollow       
00193 {
00194 };
00195 
00196 
00197 
00198 #endif /* YAPF_COMMON_HPP */

Generated on Sun Jan 23 01:49:06 2011 for OpenTTD by  doxygen 1.6.1