]> git.tdb.fi Git - r2c2.git/blob - source/libmarklin/tracktype.cpp
Major architecture rework
[r2c2.git] / source / libmarklin / tracktype.cpp
1 /* $Id$
2
3 This file is part of the MSP Märklin suite
4 Copyright © 2006-2010  Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #include <cmath>
9 #include "tracktype.h"
10
11 using namespace std;
12
13 namespace Marklin {
14
15 TrackType::TrackType(unsigned a):
16         art_nr(a)
17 { }
18
19 float TrackType::get_total_length() const
20 {
21         return get_path_length(-1);
22 }
23
24 float TrackType::get_path_length(int p) const
25 {
26         float len = 0;
27         for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
28                 if(p<0 || i->path==static_cast<unsigned>(p))
29                 {
30                         float l = i->length;
31                         if(i->radius)
32                                 l *= abs(i->radius);
33                         len += l;
34                 }
35         return len;
36 }
37
38 unsigned TrackType::get_paths() const
39 {
40         unsigned mask = 0;
41         for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
42                 mask |= 1<<i->path;
43         return mask;
44 }
45
46 unsigned TrackType::get_n_paths() const
47 {
48         unsigned n = 0;
49         for(unsigned mask = get_paths(); mask; ++n)
50                 mask &= mask-1;
51         return n;
52 }
53
54 bool TrackType::is_turnout() const
55 {
56         return endpoints.size()>2;
57 }
58
59 bool TrackType::is_double_address() const
60 {
61         return get_n_paths()>2;
62 }
63
64 void TrackType::collect_endpoints()
65 {
66         endpoints.clear();
67
68         for(vector<TrackPart>::iterator i=parts.begin(); i!=parts.end(); ++i)
69                 i->collect_endpoints(endpoints);
70
71         for(vector<Endpoint>::iterator i=endpoints.begin(); i!=endpoints.end();)
72         {
73                 bool rm = false;
74                 for(vector<Endpoint>::iterator j=i+1; j!=endpoints.end();)
75                 {
76                         float dx = i->pos.x-j->pos.x;
77                         float dy = i->pos.y-j->pos.y;
78                         if(dx*dx+dy*dy<0.0001)
79                         {
80                                 float da = i->dir-j->dir;
81                                 if(da<-M_PI)
82                                         da += M_PI*2;
83                                 if(da>M_PI)
84                                         da -= M_PI*2;
85                                 if(da<-3.1 || da>3.1)
86                                         rm = true;
87                                 i->paths |= j->paths;
88                                 j = endpoints.erase(j);
89                         }
90                         else
91                                 ++j;
92                 }
93
94                 if(rm)
95                         i = endpoints.erase(i);
96                 else
97                         ++i;
98         }
99 }
100
101
102 TrackType::Loader::Loader(TrackType &t):
103         Msp::DataFile::BasicLoader<TrackType>(t)
104 {
105         add("description", &TrackType::description);
106         add("part",        &Loader::part);
107 }
108
109 void TrackType::Loader::finish()
110 {
111         obj.collect_endpoints();
112 }
113
114 void TrackType::Loader::part()
115 {
116         TrackPart p;
117         load_sub(p);
118         obj.parts.push_back(p);
119 }
120
121 } // namespace Marklin