]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/trackiter.cpp
Strip Id tags and copyright notices from files
[r2c2.git] / source / libr2c2 / trackiter.cpp
1 #include <algorithm>
2 #include <msp/core/except.h>
3 #include "track.h"
4 #include "trackiter.h"
5 #include "tracktype.h"
6
7 using namespace std;
8 using namespace Msp;
9
10 namespace R2C2 {
11
12 TrackIter::TrackIter():
13         _track(0),
14         _entry(0)
15 { }
16
17 TrackIter::TrackIter(Track *t, unsigned e):
18         _track(t),
19         _entry(t ? e : 0)
20 {
21         if(_track && _entry>_track->get_type().get_endpoints().size())
22                 throw InvalidParameterValue("Endpoint index not valid for track");
23 }
24
25 const TrackType::Endpoint &TrackIter::endpoint() const
26 {
27         if(!_track)
28                 throw InvalidState("TrackIter is null");
29
30         return _track->get_type().get_endpoint(_entry);
31 }
32
33 int TrackIter::get_exit(unsigned path) const
34 {
35         const vector<TrackType::Endpoint> &eps = _track->get_type().get_endpoints();
36         
37         // Find an endpoint that's connected to the entry and has the requested path
38         for(unsigned i=0; i<eps.size(); ++i)
39                 if(i!=_entry && (eps[i].paths&(1<<path)) && (eps[i].paths&eps[_entry].paths))
40                         return i;
41
42         return -1;
43 }
44
45 TrackIter TrackIter::next() const
46 {
47         if(!_track)
48                 return TrackIter();
49
50         return next(_track->get_active_path());
51 }
52
53 TrackIter TrackIter::next(unsigned path) const
54 {
55         if(!_track)
56                 return TrackIter();
57
58         int exit = get_exit(path);
59         if(exit<0)
60                 return TrackIter();
61
62         TrackIter result;
63         result._track = _track->get_link(exit);
64         result._entry = (result._track ? result._track->get_endpoint_by_link(*_track) : 0);
65
66         return result;
67 }
68
69 TrackIter TrackIter::reverse() const
70 {
71         if(!_track)
72                 return TrackIter();
73
74         return reverse(_track->get_active_path());
75 }
76
77 TrackIter TrackIter::reverse(unsigned path) const
78 {
79         if(!_track)
80                 return TrackIter();
81
82         int exit = get_exit(path);
83         if(exit<0)
84                 return TrackIter();
85
86         return TrackIter(_track, exit);
87 }
88
89 TrackIter TrackIter::flip() const
90 {
91         if(!_track)
92                 return TrackIter();
93
94         TrackIter result;
95         result._track = _track->get_link(_entry);
96         result._entry = (result._track ? result._track->get_endpoint_by_link(*_track) : 0);
97
98         return result;
99 }
100
101 Track &TrackIter::operator*() const
102 {
103         if(!_track)
104                 throw InvalidState("TrackIter is null");
105
106         return *_track;
107 }
108
109 bool TrackIter::operator==(const TrackIter &other) const
110 {
111         return _track==other._track && _entry==other._entry;
112 }
113
114
115 TrackLoopIter::TrackLoopIter():
116         _looped(false)
117 { }
118
119 TrackLoopIter::TrackLoopIter(Track *t, unsigned e):
120         TrackIter(t, e),
121         _visited(new TrackList()),
122         _last(_visited->insert(_visited->end(), track())),
123         _looped(false)
124 { }
125
126 TrackLoopIter::TrackLoopIter(const TrackIter &i):
127         TrackIter(i),
128         _visited(new TrackList()),
129         _last(_visited->insert(_visited->end(), track())),
130         _looped(false)
131 { }
132
133 TrackLoopIter::TrackLoopIter(const TrackIter &i, RefPtr<TrackList> v, const TrackList::iterator &l):
134         TrackIter(i),
135         _looped(false)
136 {
137         if(track())
138         {
139                 _visited = v;
140                 _last = l;
141                 _looped = (_visited && find(_visited->begin(), _last, track())!=_last);
142
143                 ++_last;
144                 if(_last!=_visited->end())
145                 {
146                         _visited = new TrackList(_visited->begin(), _last);
147                         _last = _visited->end();
148                 }
149                 _visited->push_back(track());
150                 --_last;
151         }
152 }
153
154 TrackLoopIter TrackLoopIter::next() const
155 {
156         return TrackLoopIter(TrackIter::next(), _visited, _last);
157 }
158
159 TrackLoopIter TrackLoopIter::next(unsigned path) const
160 {
161         return TrackLoopIter(TrackIter::next(path), _visited, _last);
162 }
163
164 } // namespace R2C2