12 #include "../../stdafx.h" 
   19 #include "../../viewport_func.h" 
   20 #include "../../newgrf_station.h" 
   22 #include "../../safeguards.h" 
   24 template <
typename Tpf> 
void DumpState(Tpf &pf1, Tpf &pf2)
 
   29   FILE *f1 = fopen(
"yapf1.txt", 
"wt");
 
   30   FILE *f2 = fopen(
"yapf2.txt", 
"wt");
 
   37 int _total_pf_time_us = 0;
 
   39 template <
class Types>
 
   43   typedef typename Types::Tpf 
Tpf;                     
 
   44   typedef typename Types::TrackFollower TrackFollower;
 
   45   typedef typename Types::NodeList::Titem 
Node;        
 
   51     return *
static_cast<Tpf *
>(
this);
 
  139     assert(node->m_parent != NULL);
 
  142     if (node->m_parent->m_num_signals_passed >= 2) 
return;
 
  155     if (target != NULL) {
 
  158       target->
okay = 
false;
 
  164     for (
Node *node = 
m_res_node; node->m_parent != NULL; node = node->m_parent) {
 
  174         } 
while (fail_node != node && (fail_node = fail_node->m_parent) != NULL);
 
  180     if (target != NULL) target->
okay = 
true;
 
  190 template <
class Types>
 
  194   typedef typename Types::Tpf 
Tpf;                     
 
  195   typedef typename Types::TrackFollower TrackFollower;
 
  196   typedef typename Types::NodeList::Titem 
Node;        
 
  197   typedef typename Node::Key 
Key;                      
 
  203     return *
static_cast<Tpf *
>(
this);
 
  214     TrackFollower F(
Yapf().GetVehicle());
 
  215     if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir())) {
 
  216       Yapf().AddMultipleNodes(&old_node, F);
 
  238     if (max_penalty != 0) pf1.DisableCache(
true);
 
  239     bool result1 = pf1.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_penalty, reverse_penalty, depot_tile, reversed);
 
  241     if (_debug_desync_level >= 2) {
 
  244       bool reversed2 = 
false;
 
  245       pf2.DisableCache(
true);
 
  246       bool result2 = pf2.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_penalty, reverse_penalty, &depot_tile2, &reversed2);
 
  247       if (result1 != result2 || (result1 && (*depot_tile != depot_tile2 || *reversed != reversed2))) {
 
  248         DEBUG(desync, 2, 
"CACHE ERROR: FindNearestDepotTwoWay() = [%s, %s]", result1 ? 
"T" : 
"F", result2 ? 
"T" : 
"F");
 
  259     Yapf().SetOrigin(t1, td1, t2, td2, reverse_penalty, 
true);
 
  260     Yapf().SetDestination(v);
 
  261     Yapf().SetMaxCost(max_penalty);
 
  264     bool bFound = 
Yapf().FindPath(v);
 
  265     if (!bFound) 
return false;
 
  270     *depot_tile = n->GetLastTile();
 
  274     while (pNode->m_parent != NULL) {
 
  275       pNode = pNode->m_parent;
 
  280     *reversed = (pNode->m_cost != 0);
 
  286 template <
class Types>
 
  290   typedef typename Types::Tpf 
Tpf;                     
 
  291   typedef typename Types::TrackFollower TrackFollower;
 
  292   typedef typename Types::NodeList::Titem 
Node;        
 
  293   typedef typename Node::Key 
Key;                      
 
  299     return *
static_cast<Tpf *
>(
this);
 
  310     TrackFollower F(
Yapf().GetVehicle(), 
Yapf().GetCompatibleRailTypes());
 
  311     if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir()) && F.MaskReservedTracks()) {
 
  312       Yapf().AddMultipleNodes(&old_node, F);
 
  327     if (_debug_desync_level < 2) {
 
  328       result1 = pf1.FindNearestSafeTile(v, t1, td, override_railtype, 
false);
 
  330       bool result2 = pf1.FindNearestSafeTile(v, t1, td, override_railtype, 
true);
 
  332       pf2.DisableCache(
true);
 
  333       result1 = pf2.FindNearestSafeTile(v, t1, td, override_railtype, 
false);
 
  334       if (result1 != result2) {
 
  335         DEBUG(desync, 2, 
"CACHE ERROR: FindSafeTile() = [%s, %s]", result2 ? 
"T" : 
"F", result1 ? 
"T" : 
"F");
 
  343   bool FindNearestSafeTile(
const Train *v, 
TileIndex t1, 
Trackdir td, 
bool override_railtype, 
bool dont_reserve)
 
  346     Yapf().SetOrigin(t1, td);
 
  347     Yapf().SetDestination(v, override_railtype);
 
  349     bool bFound = 
Yapf().FindPath(v);
 
  350     if (!bFound) 
return false;
 
  358     while (pNode->m_parent != NULL) {
 
  360       pNode = pNode->m_parent;
 
  365     return dont_reserve || this->
TryReservePath(NULL, pNode->GetLastTile());
 
  369 template <
class Types>
 
  373   typedef typename Types::Tpf 
Tpf;                     
 
  374   typedef typename Types::TrackFollower TrackFollower;
 
  375   typedef typename Types::NodeList::Titem 
Node;        
 
  376   typedef typename Node::Key 
Key;                      
 
  382     return *
static_cast<Tpf *
>(
this);
 
  393     TrackFollower F(
Yapf().GetVehicle());
 
  394     if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir())) {
 
  395       Yapf().AddMultipleNodes(&old_node, F);
 
  411     if (_debug_desync_level < 2) {
 
  412       result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target);
 
  414       result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, 
false, NULL);
 
  416       pf2.DisableCache(
true);
 
  417       Trackdir result2 = pf2.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target);
 
  418       if (result1 != result2) {
 
  419         DEBUG(desync, 2, 
"CACHE ERROR: ChooseRailTrack() = [%d, %d]", result1, result2);
 
  434     Yapf().SetDestination(v);
 
  437     path_found = 
Yapf().FindPath(v);
 
  449       while (pNode->m_parent != NULL) {
 
  451         pNode = pNode->m_parent;
 
  456       Node &best_next_node = *pPrev;
 
  457       next_trackdir = best_next_node.GetTrackdir();
 
  459       if (reserve_track && path_found) this->
TryReservePath(target, pNode->GetLastTile());
 
  463     path_found |= 
Yapf().m_stopped_on_first_two_way_signal;
 
  464     return next_trackdir;
 
  470     bool result1 = pf1.CheckReverseTrain(v, t1, td1, t2, td2, reverse_penalty);
 
  472     if (_debug_desync_level >= 2) {
 
  474       pf2.DisableCache(
true);
 
  475       bool result2 = pf2.CheckReverseTrain(v, t1, td1, t2, td2, reverse_penalty);
 
  476       if (result1 != result2) {
 
  477         DEBUG(desync, 2, 
"CACHE ERROR: CheckReverseTrain() = [%s, %s]", result1 ? 
"T" : 
"F", result2 ? 
"T" : 
"F");
 
  489     Yapf().SetOrigin(t1, td1, t2, td2, reverse_penalty, 
false);
 
  490     Yapf().SetDestination(v);
 
  493     bool bFound = 
Yapf().FindPath(v);
 
  495     if (!bFound) 
return false;
 
  500     while (pNode->m_parent != NULL) {
 
  501       pNode = pNode->m_parent;
 
  505     Node &best_org_node = *pNode;
 
  506     bool reversed = (best_org_node.m_cost != 0);
 
  511 template <
class Tpf_, 
class Ttrack_follower, 
class Tnode_list, 
template <
class Types> 
class TdestinationT, 
template <
class Types> 
class TfollowT>
 
  517   typedef Ttrack_follower                     TrackFollower;
 
  518   typedef Tnode_list                          NodeList;
 
  528 struct CYapfRail1         : 
CYapfT<CYapfRail_TypesT<CYapfRail1        , CFollowTrackRail    , CRailNodeListTrackDir, CYapfDestinationTileOrStationRailT, CYapfFollowRailT> > {};
 
  529 struct CYapfRail2         : 
CYapfT<CYapfRail_TypesT<CYapfRail2        , CFollowTrackRailNo90, CRailNodeListTrackDir, CYapfDestinationTileOrStationRailT, CYapfFollowRailT> > {};
 
  531 struct CYapfAnyDepotRail1 : 
CYapfT<CYapfRail_TypesT<CYapfAnyDepotRail1, CFollowTrackRail    , CRailNodeListTrackDir, CYapfDestinationAnyDepotRailT     , CYapfFollowAnyDepotRailT> > {};
 
  532 struct CYapfAnyDepotRail2 : 
CYapfT<CYapfRail_TypesT<CYapfAnyDepotRail2, CFollowTrackRailNo90, CRailNodeListTrackDir, CYapfDestinationAnyDepotRailT     , CYapfFollowAnyDepotRailT> > {};
 
  534 struct CYapfAnySafeTileRail1 : 
CYapfT<CYapfRail_TypesT<CYapfAnySafeTileRail1, CFollowTrackFreeRail    , CRailNodeListTrackDir, CYapfDestinationAnySafeTileRailT , CYapfFollowAnySafeTileRailT> > {};
 
  535 struct CYapfAnySafeTileRail2 : 
CYapfT<CYapfRail_TypesT<CYapfAnySafeTileRail2, CFollowTrackFreeRailNo90, CRailNodeListTrackDir, CYapfDestinationAnySafeTileRailT , CYapfFollowAnySafeTileRailT> > {};
 
  542   PfnChooseRailTrack pfnChooseRailTrack = &CYapfRail1::stChooseRailTrack;
 
  546     pfnChooseRailTrack = &CYapfRail2::stChooseRailTrack; 
 
  549   Trackdir td_ret = pfnChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target);
 
  565   int reverse_penalty = 0;
 
  597   PfnCheckReverseTrain pfnCheckReverseTrain = CYapfRail1::stCheckReverseTrain;
 
  601     pfnCheckReverseTrain = &CYapfRail2::stCheckReverseTrain; 
 
  605   if (reverse_penalty == 0) reverse_penalty = 1;
 
  607   bool reverse = pfnCheckReverseTrain(v, tile, td, tile_rev, td_rev, reverse_penalty);
 
  623   PfnFindNearestDepotTwoWay pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail1::stFindNearestDepotTwoWay;
 
  627     pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail2::stFindNearestDepotTwoWay; 
 
  631   fdd.
best_length = ret ? max_penalty / 2 : UINT_MAX; 
 
  638   PfnFindNearestSafeTile pfnFindNearestSafeTile = CYapfAnySafeTileRail1::stFindNearestSafeTile;
 
  642     pfnFindNearestSafeTile = &CYapfAnySafeTileRail2::stFindNearestSafeTile;
 
  645   return pfnFindNearestSafeTile(v, tile, td, override_railtype);
 
  653   CSegmentCostCacheBase::NotifyTrackLayoutChange(tile, track);