]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/trackoffsetiter.cpp
f8e8a2d2a4c54a5270c85a41fd5955011c2f9641
[r2c2.git] / source / libr2c2 / trackoffsetiter.cpp
1 #include <msp/strings/format.h>
2 #include "blockiter.h"
3 #include "route.h"
4 #include "track.h"
5 #include "tracktype.h"
6 #include "trackoffsetiter.h"
7
8 using namespace std;
9 using namespace Msp;
10
11 namespace R2C2 {
12
13 incompatible_path::incompatible_path(unsigned a, unsigned e):
14         logic_error(format("got %d, but %d already set", a, e))
15 { }
16
17
18 TrackOffsetIter::TrackOffsetIter():
19         _offset(0),
20         _path(0)
21 { }
22
23 TrackOffsetIter::TrackOffsetIter(Track *t, unsigned e, float o):
24         _track(t, e),
25         _offset(_track ? o : 0),
26         _path((_track && _offset) ? _track->get_active_path() : -1)
27 { }
28
29 TrackOffsetIter::TrackOffsetIter(Track *t, unsigned e, unsigned p, float o):
30         _track(t, e),
31         _offset(o),
32         _path(p)
33 { }
34
35 TrackOffsetIter::TrackOffsetIter(const TrackIter &t, float o):
36         _track(t),
37         _offset(_track ? o : 0),
38         _path((_track && _offset) ? _track->get_active_path() : -1)
39 { }
40
41 TrackOffsetIter::TrackOffsetIter(const TrackIter &t, unsigned p, float o):
42         _track(t),
43         _offset(o),
44         _path(p)
45 { }
46
47 BlockIter TrackOffsetIter::block_iter() const
48 {
49         return _track.block_iter();
50 }
51
52 OrientedPoint TrackOffsetIter::point() const
53 {
54         if(!_track)
55                 return OrientedPoint();
56
57         if(_path>=0)
58                 return _track->get_point(_track.entry(), _path, _offset);
59         else
60                 return _track->get_point(_track.entry(), _offset);
61 }
62
63 TrackOffsetIter TrackOffsetIter::next() const
64 {
65         if(_path>=0)
66                 return _track.next(_path);
67         else
68                 return _track.next();
69 }
70
71 TrackOffsetIter TrackOffsetIter::next(unsigned p) const
72 {
73         if(_path>=0 && static_cast<unsigned>(_path)!=p)
74                 throw incompatible_path(_path, p);
75         
76         return _track.next(p);
77 }
78
79 TrackOffsetIter TrackOffsetIter::advance(float d, const Route *r) const
80 {
81         if(!_track)
82                 return TrackOffsetIter();
83
84         if(d<0)
85                 return reverse().advance(-d, r).reverse();
86
87         TrackIter t = _track;
88         int p = _path;
89         float o = _offset+d;
90
91         while(t)
92         {
93                 if(p<0)
94                         p = (r ? r->get_path(*t) : t->get_active_path());
95
96                 float length = t->get_type().get_path_length(p);
97                 if(o<length)
98                         return TrackOffsetIter(t, p, o);
99
100                 o -= length;
101                 t = t.next(p);
102                 p = -1;
103         }
104
105         return TrackOffsetIter();
106 }
107         
108 TrackOffsetIter TrackOffsetIter::reverse() const
109 {
110         if(!_track)
111                 return TrackOffsetIter();
112
113         int p = (_path>=0 ? _path : _track->get_active_path());
114         TrackIter t = _track.reverse(p);
115         if(!t)
116                 return TrackOffsetIter();
117
118         float o = t->get_type().get_path_length(p)-_offset;
119
120         return TrackOffsetIter(t, p, o);
121 }
122
123 bool TrackOffsetIter::operator==(const TrackOffsetIter &other) const
124 {
125         return _track==other._track && _offset==other._offset && _path==other._path;
126 }
127
128 } // namespaec R2C2