]> git.tdb.fi Git - r2c2.git/blob - source/libmarklin/trackiter.cpp
Add TrackIter and BlockIter classes
[r2c2.git] / source / libmarklin / trackiter.cpp
1 /* $Id$
2
3 This file is part of the MSP Märklin suite
4 Copyright © 2010  Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #include <msp/core/except.h>
9 #include "track.h"
10 #include "trackiter.h"
11 #include "tracktype.h"
12
13 using namespace std;
14 using namespace Msp;
15
16 namespace Marklin {
17
18 TrackIter::TrackIter():
19         _track(0),
20         _entry(0)
21 { }
22
23 TrackIter::TrackIter(Track *t, unsigned e):
24         _track(t),
25         _entry(t ? e : 0)
26 {
27         if(_track && _entry>_track->get_type().get_endpoints().size())
28                 throw InvalidParameterValue("Endpoint index not valid for track");
29 }
30
31 int TrackIter::get_exit(unsigned path) const
32 {
33         const vector<Endpoint> &eps = _track->get_type().get_endpoints();
34         
35         // Find an endpoint that's connected to the entry and has the requested path
36         for(unsigned i=0; i<eps.size(); ++i)
37                 if(i!=_entry && (eps[i].paths&(1<<path)) && (eps[i].paths&eps[_entry].paths))
38                         return i;
39
40         return -1;
41 }
42
43 TrackIter TrackIter::next() const
44 {
45         if(!_track)
46                 return TrackIter();
47
48         return next(_track->get_active_path());
49 }
50
51 TrackIter TrackIter::next(unsigned path) const
52 {
53         if(!_track)
54                 return TrackIter();
55
56         int exit = get_exit(path);
57         if(exit<0)
58                 return TrackIter();
59
60         TrackIter result;
61         result._track = _track->get_link(exit);
62         result._entry = (result._track ? result._track->get_endpoint_by_link(*_track) : 0);
63
64         return result;
65 }
66
67 TrackIter TrackIter::reverse() const
68 {
69         if(!_track)
70                 return TrackIter();
71
72         return reverse(_track->get_active_path());
73 }
74
75 TrackIter TrackIter::reverse(unsigned path) const
76 {
77         if(!_track)
78                 return TrackIter();
79
80         int exit = get_exit(path);
81         if(exit<0)
82                 return TrackIter();
83
84         return TrackIter(_track, exit);
85 }
86
87 TrackIter TrackIter::flip() const
88 {
89         if(!_track)
90                 return TrackIter();
91
92         TrackIter result;
93         result._track = _track->get_link(_entry);
94         result._entry = (result._track ? result._track->get_endpoint_by_link(*_track) : 0);
95
96         return result;
97 }
98
99 Track &TrackIter::operator*() const
100 {
101         if(!_track)
102                 throw InvalidState("TrackIter is null");
103
104         return *_track;
105 }
106
107 bool TrackIter::operator==(const TrackIter &other) const
108 {
109         return _track==other._track && _entry==other._entry;
110 }
111
112 } // namespace Marklin