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);