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 FindDepotData result1 = pf1.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_penalty, reverse_penalty);
241 if (_debug_desync_level >= 2) {
243 pf2.DisableCache(
true);
244 FindDepotData result2 = pf2.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_penalty, reverse_penalty);
246 DEBUG(desync, 2,
"CACHE ERROR: FindNearestDepotTwoWay() = [%s, %s]",
259 Yapf().SetOrigin(t1, td1, t2, td2, reverse_penalty,
true);
260 Yapf().SetDestination(v);
261 Yapf().SetMaxCost(max_penalty);
271 while (pNode->m_parent != NULL) {
272 pNode = pNode->m_parent;
277 return FindDepotData(n->GetLastTile(), n->m_cost, pNode->m_cost != 0);
281 template <
class Types>
285 typedef typename Types::Tpf
Tpf;
286 typedef typename Types::TrackFollower TrackFollower;
287 typedef typename Types::NodeList::Titem
Node;
288 typedef typename Node::Key
Key;
294 return *
static_cast<Tpf *
>(
this);
305 TrackFollower F(
Yapf().GetVehicle(),
Yapf().GetCompatibleRailTypes());
306 if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir()) && F.MaskReservedTracks()) {
307 Yapf().AddMultipleNodes(&old_node, F);
322 if (_debug_desync_level < 2) {
323 result1 = pf1.FindNearestSafeTile(v, t1, td, override_railtype,
false);
325 bool result2 = pf1.FindNearestSafeTile(v, t1, td, override_railtype,
true);
327 pf2.DisableCache(
true);
328 result1 = pf2.FindNearestSafeTile(v, t1, td, override_railtype,
false);
329 if (result1 != result2) {
330 DEBUG(desync, 2,
"CACHE ERROR: FindSafeTile() = [%s, %s]", result2 ?
"T" :
"F", result1 ?
"T" :
"F");
338 bool FindNearestSafeTile(
const Train *v,
TileIndex t1,
Trackdir td,
bool override_railtype,
bool dont_reserve)
341 Yapf().SetOrigin(t1, td);
342 Yapf().SetDestination(v, override_railtype);
344 bool bFound =
Yapf().FindPath(v);
345 if (!bFound)
return false;
353 while (pNode->m_parent != NULL) {
355 pNode = pNode->m_parent;
360 return dont_reserve || this->
TryReservePath(NULL, pNode->GetLastTile());
364 template <
class Types>
368 typedef typename Types::Tpf
Tpf;
369 typedef typename Types::TrackFollower TrackFollower;
370 typedef typename Types::NodeList::Titem
Node;
371 typedef typename Node::Key
Key;
377 return *
static_cast<Tpf *
>(
this);
388 TrackFollower F(
Yapf().GetVehicle());
389 if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir())) {
390 Yapf().AddMultipleNodes(&old_node, F);
406 if (_debug_desync_level < 2) {
407 result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target);
409 result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found,
false, NULL);
411 pf2.DisableCache(
true);
412 Trackdir result2 = pf2.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target);
413 if (result1 != result2) {
414 DEBUG(desync, 2,
"CACHE ERROR: ChooseRailTrack() = [%d, %d]", result1, result2);
429 Yapf().SetDestination(v);
432 path_found =
Yapf().FindPath(v);
444 while (pNode->m_parent != NULL) {
446 pNode = pNode->m_parent;
451 Node &best_next_node = *pPrev;
452 next_trackdir = best_next_node.GetTrackdir();
454 if (reserve_track && path_found) this->
TryReservePath(target, pNode->GetLastTile());
458 path_found |=
Yapf().m_stopped_on_first_two_way_signal;
459 return next_trackdir;
465 bool result1 = pf1.CheckReverseTrain(v, t1, td1, t2, td2, reverse_penalty);
467 if (_debug_desync_level >= 2) {
469 pf2.DisableCache(
true);
470 bool result2 = pf2.CheckReverseTrain(v, t1, td1, t2, td2, reverse_penalty);
471 if (result1 != result2) {
472 DEBUG(desync, 2,
"CACHE ERROR: CheckReverseTrain() = [%s, %s]", result1 ?
"T" :
"F", result2 ?
"T" :
"F");
484 Yapf().SetOrigin(t1, td1, t2, td2, reverse_penalty,
false);
485 Yapf().SetDestination(v);
488 bool bFound =
Yapf().FindPath(v);
490 if (!bFound)
return false;
495 while (pNode->m_parent != NULL) {
496 pNode = pNode->m_parent;
500 Node &best_org_node = *pNode;
501 bool reversed = (best_org_node.m_cost != 0);
506 template <
class Tpf_,
class Ttrack_follower,
class Tnode_list,
template <
class Types>
class TdestinationT,
template <
class Types>
class TfollowT>
512 typedef Ttrack_follower TrackFollower;
513 typedef Tnode_list NodeList;
523 struct CYapfRail1 :
CYapfT<CYapfRail_TypesT<CYapfRail1 , CFollowTrackRail , CRailNodeListTrackDir, CYapfDestinationTileOrStationRailT, CYapfFollowRailT> > {};
524 struct CYapfRail2 :
CYapfT<CYapfRail_TypesT<CYapfRail2 , CFollowTrackRailNo90, CRailNodeListTrackDir, CYapfDestinationTileOrStationRailT, CYapfFollowRailT> > {};
526 struct CYapfAnyDepotRail1 :
CYapfT<CYapfRail_TypesT<CYapfAnyDepotRail1, CFollowTrackRail , CRailNodeListTrackDir, CYapfDestinationAnyDepotRailT , CYapfFollowAnyDepotRailT> > {};
527 struct CYapfAnyDepotRail2 :
CYapfT<CYapfRail_TypesT<CYapfAnyDepotRail2, CFollowTrackRailNo90, CRailNodeListTrackDir, CYapfDestinationAnyDepotRailT , CYapfFollowAnyDepotRailT> > {};
529 struct CYapfAnySafeTileRail1 :
CYapfT<CYapfRail_TypesT<CYapfAnySafeTileRail1, CFollowTrackFreeRail , CRailNodeListTrackDir, CYapfDestinationAnySafeTileRailT , CYapfFollowAnySafeTileRailT> > {};
530 struct CYapfAnySafeTileRail2 :
CYapfT<CYapfRail_TypesT<CYapfAnySafeTileRail2, CFollowTrackFreeRailNo90, CRailNodeListTrackDir, CYapfDestinationAnySafeTileRailT , CYapfFollowAnySafeTileRailT> > {};
537 PfnChooseRailTrack pfnChooseRailTrack = &CYapfRail1::stChooseRailTrack;
541 pfnChooseRailTrack = &CYapfRail2::stChooseRailTrack;
544 Trackdir td_ret = pfnChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target);
560 int reverse_penalty = 0;
592 PfnCheckReverseTrain pfnCheckReverseTrain = CYapfRail1::stCheckReverseTrain;
596 pfnCheckReverseTrain = &CYapfRail2::stCheckReverseTrain;
600 if (reverse_penalty == 0) reverse_penalty = 1;
602 bool reverse = pfnCheckReverseTrain(v, tile, td, tile_rev, td_rev, reverse_penalty);
616 PfnFindNearestDepotTwoWay pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail1::stFindNearestDepotTwoWay;
620 pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail2::stFindNearestDepotTwoWay;
629 PfnFindNearestSafeTile pfnFindNearestSafeTile = CYapfAnySafeTileRail1::stFindNearestSafeTile;
633 pfnFindNearestSafeTile = &CYapfAnySafeTileRail2::stFindNearestSafeTile;
636 return pfnFindNearestSafeTile(v, tile, td, override_railtype);
644 CSegmentCostCacheBase::NotifyTrackLayoutChange(tile, track);