]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/blockiter.cpp
Sync timetable to clock on first tick
[r2c2.git] / source / libr2c2 / blockiter.cpp
1 #include "block.h"
2 #include "blockiter.h"
3 #include "route.h"
4 #include "trackiter.h"
5
6 using namespace std;
7 using namespace Msp;
8
9 namespace R2C2 {
10
11 BlockIter::BlockIter():
12         _block(0),
13         _entry(0)
14 { }
15
16 BlockIter::BlockIter(Block *b, unsigned e):
17         _block(b),
18         _entry(b ? e : 0)
19 {
20         if(_block && _entry>_block->get_endpoints().size())
21                 throw out_of_range("BlockIter::BlockIter");
22 }
23
24 TrackIter BlockIter::track_iter() const
25 {
26         if(!_block)
27                 return TrackIter();
28
29         return _block->get_endpoint(_entry).track_iter();
30 }
31
32 const Block::Endpoint &BlockIter::endpoint() const
33 {
34         if(!_block)
35                 throw logic_error("null block");
36
37         return _block->get_endpoint(_entry);
38 }
39
40 int BlockIter::get_exit(const Route *route) const
41 {
42         const vector<Block::Endpoint> &eps = _block->get_endpoints();
43         if(_block->get_turnout_address())
44         {
45                 /* The endpoints of a turnout block exactly correspond to the endpoints
46                 of the track. */
47                 TrackIter t_iter = track_iter();
48                 unsigned path = (route ? route->get_path(*t_iter) : t_iter->get_active_path());
49                 return t_iter.reverse(path).entry();
50         }
51         else if(eps.size()==2)
52                 return 1-_entry;
53         else
54                 return -1;
55 }
56
57 BlockIter BlockIter::next(const Route *route) const
58 {
59         if(!_block)
60                 return BlockIter();
61
62         int exit = get_exit(route);
63         if(exit<0)
64                 return BlockIter();
65
66         BlockIter result;
67         result._block = _block->get_link(exit);
68         result._entry = (result._block ? result._block->get_endpoint_by_link(*_block) : 0);
69
70         return result;
71 }
72
73 BlockIter BlockIter::reverse(const Route *route) const
74 {
75         if(!_block)
76                 return BlockIter();
77
78         int exit = get_exit(route);
79         if(exit<0)
80                 return BlockIter();
81
82         return BlockIter(_block, exit);
83 }
84
85 BlockIter BlockIter::flip() const
86 {
87         if(!_block)
88                 return BlockIter();
89
90         BlockIter result;
91         result._block = _block->get_link(_entry);
92         result._entry = (result._block ? result._block->get_endpoint_by_link(*_block) : 0);
93
94         return result;
95 }
96
97 Block &BlockIter::operator*() const
98 {
99         if(!_block)
100                 throw logic_error("null block");
101
102         return *_block;
103 }
104
105 bool BlockIter::operator==(const BlockIter &other) const
106 {
107         return _block==other._block && _entry==other._entry;
108 }
109
110 } // namespace R2C2