# yapf_common.hpp

Go to the documentation of this file.

    00001 /* $Id: yapf_common.hpp 17596 2009-09-20 23:11:01Z smatz $ */
    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
    00151   inline bool PfCalcEstimate(Node& n)
    00152   {
    00153     static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
    00154     static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
    00155     if (PfDetectDestination(n)) {
    00156       n.m_estimate = n.m_cost;
    00157       return true;
    00158     }
    00159
    00160     TileIndex tile = n.GetTile();
    00161     DiagDirection exitdir = TrackdirToExitdir(n.GetTrackdir());
    00162     int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
    00163     int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
    00164     int x2 = 2 * TileX(m_destTile);
    00165     int y2 = 2 * TileY(m_destTile);
    00166     int dx = abs(x1 - x2);
    00167     int dy = abs(y1 - y2);
    00168     int dmin = min(dx, dy);
    00169     int dxy = abs(dx - dy);
    00170     int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
    00171     n.m_estimate = n.m_cost + d;
    00172     assert(n.m_estimate >= n.m_parent->m_estimate);
    00173     return true;
    00174   }
    00175 };
    00176
    00181 template <class Ttypes>
    00182 class CYapfT
    00183   : public Ttypes::PfBase
    00184   , public Ttypes::PfCost
    00185   , public Ttypes::PfCache
    00186   , public Ttypes::PfOrigin
    00187   , public Ttypes::PfDestination
    00188   , public Ttypes::PfFollow
    00189 {
    00190 };
    00191
    00192
    00193
    00194 #endif /* YAPF_COMMON_HPP */