3 #include "trackchain.h"
4 #include "trainroutemetric.h"
10 TrainRouteMetric::TrainRouteMetric(const TrackChain &tc, TrackChain::Direction dir)
12 const TrackChain::TrackSet &ctracks = tc.get_tracks();
13 for(TrackChain::TrackSet::const_iterator i=ctracks.begin(); i!=ctracks.end(); ++i)
15 if(dir==TrackChain::UNSPECIFIED)
17 unsigned nls = (*i)->get_n_link_slots();
18 for(unsigned j=0; j<nls; ++j)
19 if(Track *link = (*i)->get_link(j))
20 if(!ctracks.count(link))
21 goals.push_back(TrackIter(*i, j));
23 else if(TrackIter iter = tc.iter_for(**i, reverse_dir))
24 goals.push_back(iter);
27 list<TrackIter> queue;
28 for(vector<Goal>::iterator i=goals.begin(); i!=goals.end(); ++i)
30 tracks[Key(i->track.track(), i->track.entry())] = Data(0, &*i);
31 queue.push_back(i->track);
36 TrackIter track = queue.front();
38 const Data &data = tracks[Key(track.track(), track.entry())];
40 const TrackType::Endpoint &ep = track.endpoint();
41 for(unsigned i=0; ep.paths>>i; ++i)
44 TrackIter next = track.next(i);
48 Data &target = tracks[Key(next.track(), next.entry())];
49 float dist = data.distance+track->get_type().get_path_length(i);
50 if(target.distance<0 || target.distance>dist)
52 target = Data(dist, data.goal);
53 queue.push_back(next);
59 void TrainRouteMetric::chain_to(const TrainRouteMetric &metric)
61 for(vector<Goal>::iterator i=goals.begin(); i!=goals.end(); ++i)
62 i->base_distance = metric.get_distance_from(*i->track.track(), i->track.entry());
65 float TrainRouteMetric::get_distance_from(const Track &track, unsigned exit) const
67 map<Key, Data>::const_iterator i = tracks.find(Key(&track, exit));
71 return i->second.distance+i->second.goal->base_distance;
75 TrainRouteMetric::Goal::Goal():
79 TrainRouteMetric::Goal::Goal(const TrackIter &t):
85 TrainRouteMetric::Data::Data():
90 TrainRouteMetric::Data::Data(float d, const Goal *g):