12 #include "../../stdafx.h"
19 #include "../../viewport_func.h"
20 #include "../../newgrf_station.h"
22 #include "../../safeguards.h"
24 #define DEBUG_YAPF_CACHE 0
27 template <
typename Tpf>
void DumpState(Tpf &pf1, Tpf &pf2)
32 FILE *f1 = fopen(
"yapf1.txt",
"wt");
33 FILE *f2 = fopen(
"yapf2.txt",
"wt");
41 int _total_pf_time_us = 0;
43 template <
class Types>
47 typedef typename Types::Tpf
Tpf;
48 typedef typename Types::TrackFollower TrackFollower;
49 typedef typename Types::NodeList::Titem
Node;
55 return *
static_cast<Tpf*
>(
this);
143 assert(node->m_parent != NULL);
146 if (node->m_parent->m_num_signals_passed >= 2)
return;
159 if (target != NULL) {
162 target->
okay =
false;
168 for (
Node *node =
m_res_node; node->m_parent != NULL; node = node->m_parent) {
178 }
while (fail_node != node && (fail_node = fail_node->m_parent) != NULL);
184 if (target != NULL) target->
okay =
true;
194 template <
class Types>
198 typedef typename Types::Tpf
Tpf;
199 typedef typename Types::TrackFollower TrackFollower;
200 typedef typename Types::NodeList::Titem
Node;
201 typedef typename Node::Key
Key;
207 return *
static_cast<Tpf*
>(
this);
218 TrackFollower F(
Yapf().GetVehicle());
219 if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir())) {
220 Yapf().AddMultipleNodes(&old_node, F);
242 if (max_penalty != 0) pf1.DisableCache(
true);
243 bool result1 = pf1.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_penalty, reverse_penalty, depot_tile, reversed);
248 bool reversed2 =
false;
249 pf2.DisableCache(
true);
250 bool result2 = pf2.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_penalty, reverse_penalty, &depot_tile2, &reversed2);
251 if (result1 != result2 || (result1 && (*depot_tile != depot_tile2 || *reversed != reversed2))) {
252 DEBUG(yapf, 0,
"CACHE ERROR: FindNearestDepotTwoWay() = [%s, %s]", result1 ?
"T" :
"F", result2 ?
"T" :
"F");
263 Yapf().SetOrigin(t1, td1, t2, td2, reverse_penalty,
true);
264 Yapf().SetDestination(v);
265 Yapf().SetMaxCost(max_penalty);
268 bool bFound =
Yapf().FindPath(v);
269 if (!bFound)
return false;
274 *depot_tile = n->GetLastTile();
278 while (pNode->m_parent != NULL) {
279 pNode = pNode->m_parent;
284 *reversed = (pNode->m_cost != 0);
290 template <
class Types>
294 typedef typename Types::Tpf
Tpf;
295 typedef typename Types::TrackFollower TrackFollower;
296 typedef typename Types::NodeList::Titem
Node;
297 typedef typename Node::Key
Key;
303 return *
static_cast<Tpf*
>(
this);
314 TrackFollower F(
Yapf().GetVehicle(),
Yapf().GetCompatibleRailTypes());
315 if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir()) && F.MaskReservedTracks()) {
316 Yapf().AddMultipleNodes(&old_node, F);
330 #if !DEBUG_YAPF_CACHE
331 bool result1 = pf1.FindNearestSafeTile(v, t1, td, override_railtype,
false);
334 bool result2 = pf1.FindNearestSafeTile(v, t1, td, override_railtype,
true);
336 pf2.DisableCache(
true);
337 bool result1 = pf2.FindNearestSafeTile(v, t1, td, override_railtype,
false);
338 if (result1 != result2) {
339 DEBUG(yapf, 0,
"CACHE ERROR: FindSafeTile() = [%s, %s]", result2 ?
"T" :
"F", result1 ?
"T" :
"F");
347 bool FindNearestSafeTile(
const Train *v,
TileIndex t1,
Trackdir td,
bool override_railtype,
bool dont_reserve)
350 Yapf().SetOrigin(t1, td);
351 Yapf().SetDestination(v, override_railtype);
353 bool bFound =
Yapf().FindPath(v);
354 if (!bFound)
return false;
362 while (pNode->m_parent != NULL) {
364 pNode = pNode->m_parent;
369 return dont_reserve || this->
TryReservePath(NULL, pNode->GetLastTile());
373 template <
class Types>
377 typedef typename Types::Tpf
Tpf;
378 typedef typename Types::TrackFollower TrackFollower;
379 typedef typename Types::NodeList::Titem
Node;
380 typedef typename Node::Key
Key;
386 return *
static_cast<Tpf*
>(
this);
397 TrackFollower F(
Yapf().GetVehicle());
398 if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir())) {
399 Yapf().AddMultipleNodes(&old_node, F);
413 #if !DEBUG_YAPF_CACHE
414 Trackdir result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target);
417 Trackdir result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found,
false, NULL);
419 pf2.DisableCache(
true);
420 Trackdir result2 = pf2.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target);
421 if (result1 != result2) {
422 DEBUG(yapf, 0,
"CACHE ERROR: ChooseRailTrack() = [%d, %d]", result1, result2);
437 Yapf().SetDestination(v);
440 path_found =
Yapf().FindPath(v);
452 while (pNode->m_parent != NULL) {
454 pNode = pNode->m_parent;
459 Node& best_next_node = *pPrev;
460 next_trackdir = best_next_node.GetTrackdir();
462 if (reserve_track && path_found) this->
TryReservePath(target, pNode->GetLastTile());
466 path_found |=
Yapf().m_stopped_on_first_two_way_signal;
467 return next_trackdir;
473 bool result1 = pf1.CheckReverseTrain(v, t1, td1, t2, td2, reverse_penalty);
477 pf2.DisableCache(
true);
478 bool result2 = pf2.CheckReverseTrain(v, t1, td1, t2, td2, reverse_penalty);
479 if (result1 != result2) {
480 DEBUG(yapf, 0,
"CACHE ERROR: CheckReverseTrain() = [%s, %s]", result1 ?
"T" :
"F", result2 ?
"T" :
"F");
492 Yapf().SetOrigin(t1, td1, t2, td2, reverse_penalty,
false);
493 Yapf().SetDestination(v);
496 bool bFound =
Yapf().FindPath(v);
498 if (!bFound)
return false;
503 while (pNode->m_parent != NULL) {
504 pNode = pNode->m_parent;
508 Node& best_org_node = *pNode;
509 bool reversed = (best_org_node.m_cost != 0);
514 template <
class Tpf_,
class Ttrack_follower,
class Tnode_list,
template <
class Types>
class TdestinationT,
template <
class Types>
class TfollowT>
520 typedef Ttrack_follower TrackFollower;
521 typedef Tnode_list NodeList;
531 struct CYapfRail1 :
CYapfT<CYapfRail_TypesT<CYapfRail1 , CFollowTrackRail , CRailNodeListTrackDir, CYapfDestinationTileOrStationRailT, CYapfFollowRailT> > {};
532 struct CYapfRail2 :
CYapfT<CYapfRail_TypesT<CYapfRail2 , CFollowTrackRailNo90, CRailNodeListTrackDir, CYapfDestinationTileOrStationRailT, CYapfFollowRailT> > {};
534 struct CYapfAnyDepotRail1 :
CYapfT<CYapfRail_TypesT<CYapfAnyDepotRail1, CFollowTrackRail , CRailNodeListTrackDir, CYapfDestinationAnyDepotRailT , CYapfFollowAnyDepotRailT> > {};
535 struct CYapfAnyDepotRail2 :
CYapfT<CYapfRail_TypesT<CYapfAnyDepotRail2, CFollowTrackRailNo90, CRailNodeListTrackDir, CYapfDestinationAnyDepotRailT , CYapfFollowAnyDepotRailT> > {};
537 struct CYapfAnySafeTileRail1 :
CYapfT<CYapfRail_TypesT<CYapfAnySafeTileRail1, CFollowTrackFreeRail , CRailNodeListTrackDir, CYapfDestinationAnySafeTileRailT , CYapfFollowAnySafeTileRailT> > {};
538 struct CYapfAnySafeTileRail2 :
CYapfT<CYapfRail_TypesT<CYapfAnySafeTileRail2, CFollowTrackFreeRailNo90, CRailNodeListTrackDir, CYapfDestinationAnySafeTileRailT , CYapfFollowAnySafeTileRailT> > {};
545 PfnChooseRailTrack pfnChooseRailTrack = &CYapfRail1::stChooseRailTrack;
549 pfnChooseRailTrack = &CYapfRail2::stChooseRailTrack;
552 Trackdir td_ret = pfnChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target);
568 int reverse_penalty = 0;
600 PfnCheckReverseTrain pfnCheckReverseTrain = CYapfRail1::stCheckReverseTrain;
604 pfnCheckReverseTrain = &CYapfRail2::stCheckReverseTrain;
608 if (reverse_penalty == 0) reverse_penalty = 1;
610 bool reverse = pfnCheckReverseTrain(v, tile, td, tile_rev, td_rev, reverse_penalty);
626 PfnFindNearestDepotTwoWay pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail1::stFindNearestDepotTwoWay;
630 pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail2::stFindNearestDepotTwoWay;
634 fdd.
best_length = ret ? max_penalty / 2 : UINT_MAX;
641 PfnFindNearestSafeTile pfnFindNearestSafeTile = CYapfAnySafeTileRail1::stFindNearestSafeTile;
645 pfnFindNearestSafeTile = &CYapfAnySafeTileRail2::stFindNearestSafeTile;
648 return pfnFindNearestSafeTile(v, tile, td, override_railtype);
656 CSegmentCostCacheBase::NotifyTrackLayoutChange(tile, track);