#include <algorithm>
-#include <msp/core/except.h>
+#include "blockiter.h"
#include "track.h"
#include "trackiter.h"
#include "tracktype.h"
_entry(t ? e : 0)
{
if(_track && _entry>_track->get_type().get_endpoints().size())
- throw InvalidParameterValue("Endpoint index not valid for track");
+ throw out_of_range("TrackIter::TrackIter");
+}
+
+BlockIter TrackIter::block_iter() const
+{
+ if(!_track)
+ return BlockIter();
+
+ Block &block = _track->get_block();
+ const vector<Block::Endpoint> &beps = block.get_endpoints();
+
+ // See if this track matches an endpoint in the block
+ for(unsigned i=0; i<beps.size(); ++i)
+ if(beps[i].track==_track && beps[i].track_ep==_entry)
+ return BlockIter(&block, i);
+
+ if(!_track->get_type().is_turnout())
+ {
+ /* Since there was no endpoint match, the preceding track can't be in a
+ different block. */
+ TrackIter rev = flip();
+ TrackIter last;
+ while(rev && &rev.track()->get_block()==&block)
+ {
+ last = rev;
+ rev = rev.next();
+ }
+
+ // If we ran out of tracks, return an empty iterator
+ if(!rev)
+ return BlockIter();
+
+ TrackIter fwd = last.reverse();
+ for(unsigned i=0; i<beps.size(); ++i)
+ if(beps[i].track==fwd.track() && beps[i].track_ep==fwd.entry())
+ return BlockIter(&block, i);
+ }
+
+ throw logic_error("internal error (didn't find block entry endpoint)");
}
const TrackType::Endpoint &TrackIter::endpoint() const
{
if(!_track)
- throw InvalidState("TrackIter is null");
+ throw logic_error("null track");
return _track->get_type().get_endpoint(_entry);
}
// Find an endpoint that's connected to the entry and has the requested path
for(unsigned i=0; i<eps.size(); ++i)
- if(i!=_entry && (eps[i].paths&(1<<path)) && (eps[i].paths&eps[_entry].paths))
+ if(i!=_entry && eps[i].has_path(path) && eps[i].has_common_paths(eps[_entry]))
return i;
return -1;
TrackIter result;
result._track = _track->get_link(exit);
- result._entry = (result._track ? result._track->get_endpoint_by_link(*_track) : 0);
+ result._entry = (result._track ? result._track->get_link_slot(*_track) : 0);
return result;
}
TrackIter result;
result._track = _track->get_link(_entry);
- result._entry = (result._track ? result._track->get_endpoint_by_link(*_track) : 0);
+ result._entry = (result._track ? result._track->get_link_slot(*_track) : 0);
return result;
}
Track &TrackIter::operator*() const
{
if(!_track)
- throw InvalidState("TrackIter is null");
+ throw logic_error("null track");
return *_track;
}