3 This file is part of the MSP Märklin suite
4 Copyright © 2006-2010 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
16 TrackType::TrackType(unsigned a):
21 float TrackType::get_total_length() const
23 return get_path_length(-1);
26 float TrackType::get_path_length(int p) const
29 for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
30 if(p<0 || i->get_path()==static_cast<unsigned>(p))
31 len += i->get_length();
35 unsigned TrackType::get_paths() const
38 for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
39 mask |= 1<<i->get_path();
43 unsigned TrackType::get_n_paths() const
46 for(unsigned mask = get_paths(); mask; ++n)
51 bool TrackType::is_turnout() const
53 return endpoints.size()>2;
56 bool TrackType::is_dead_end() const
58 return endpoints.size()<2;
61 TrackPoint TrackType::get_point(unsigned epi, unsigned path, float d) const
63 if(epi>=endpoints.size())
64 throw InvalidParameterValue("Endpoint index out of range");
66 const TrackPart *part = 0;
68 for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
70 if((endpoints[epi].paths&(1<<path)) && i->get_path()!=path)
73 unsigned n_part_eps = (i->is_dead_end() ? 1 : 2);
74 for(unsigned j=0; j<n_part_eps; ++j)
76 TrackPoint p = i->get_point(j ? i->get_length() : 0);
77 float dx = p.pos.x-endpoints[epi].pos.x;
78 float dy = p.pos.y-endpoints[epi].pos.y;
88 throw Exception("Internal error (endpoint does not match any part)");
92 float plen = part->get_length();
97 TrackPoint p = part->get_point(d);
105 TrackPart *next = part->get_link(1-part_ep);
107 throw InvalidParameterValue("Distance out of range");
108 part_ep = (next->get_link(0)==part ? 0 : 1);
114 void TrackType::collect_endpoints()
118 for(vector<TrackPart>::iterator i=parts.begin(); i!=parts.end(); ++i)
120 for(vector<TrackPart>::iterator j=i; ++j!=parts.end();)
123 unsigned n_part_eps = (i->is_dead_end() ? 1 : 2);
124 for(unsigned j=0; j<n_part_eps; ++j)
127 TrackPoint p = i->get_point(j ? i->get_length() : 0);
132 for(vector<Endpoint>::iterator k=endpoints.begin(); k!=endpoints.end(); ++k)
134 float dx = k->pos.x-p.pos.x;
135 float dy = k->pos.y-p.pos.y;
137 float da = k->dir-p.dir;
143 if(dx*dx+dy*dy<1e-6 && da>-0.01 && da<0.01)
145 k->paths |= 1<<i->get_path();
152 endpoints.push_back(Endpoint(p.pos.x, p.pos.y, p.dir, 1<<i->get_path()));
158 TrackType::Loader::Loader(TrackType &t):
159 Msp::DataFile::BasicLoader<TrackType>(t)
161 add("description", &TrackType::description);
162 add("double_address", &TrackType::double_address);
163 add("part", &Loader::part);
166 void TrackType::Loader::finish()
168 obj.collect_endpoints();
171 void TrackType::Loader::part()
175 obj.parts.push_back(p);
178 } // namespace Marklin