]> git.tdb.fi Git - r2c2.git/blob - source/libmarklin/catalogue.cpp
Support trains with multiple vehicles
[r2c2.git] / source / libmarklin / catalogue.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 <msp/core/refptr.h>
9 #include <msp/datafile/parser.h>
10 #include "catalogue.h"
11 #include "locotype.h"
12 #include "tracktype.h"
13
14 using namespace std;
15 using namespace Msp;
16
17 namespace Marklin {
18
19 Catalogue::Catalogue():
20         scale(1),
21         gauge(1.524),
22         layout(*this)
23 { }
24
25 Catalogue::~Catalogue()
26 {
27         for(map<unsigned, TrackType *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
28                 delete i->second;
29         for(map<unsigned, VehicleType *>::iterator i=vehicles.begin(); i!=vehicles.end(); ++i)
30                 delete i->second;
31 }
32
33 void Catalogue::add_track(TrackType &track)
34 {
35         if(tracks.count(track.get_article_number()))
36                 throw Exception("Duplicate track type");
37
38         tracks[track.get_article_number()] = &track;
39         signal_track_added.emit(track);
40 }
41
42 const TrackType &Catalogue::get_track(unsigned art_nr) const
43 {
44         map<unsigned, TrackType *>::const_iterator i=tracks.find(art_nr);
45         if(i==tracks.end())
46                 throw KeyError("Unknown track type");
47
48         return *i->second;
49 }
50
51 void Catalogue::add_vehicle(VehicleType &veh)
52 {
53         if(vehicles.count(veh.get_article_number()))
54                 throw Exception("Duplicate vehicle type");
55
56         vehicles[veh.get_article_number()] = &veh;
57         signal_vehicle_added.emit(veh);
58 }
59
60 const VehicleType &Catalogue::get_vehicle(unsigned art_nr) const
61 {
62         map<unsigned, VehicleType *>::const_iterator i = vehicles.find(art_nr);
63         if(i==vehicles.end())
64                 throw KeyError("Unknown vehicle type");
65
66         return *i->second;
67 }
68
69 const LocoType &Catalogue::get_locomotive(unsigned art_nr) const
70 {
71         const VehicleType &veh = get_vehicle(art_nr);
72         if(const LocoType *loco = dynamic_cast<const LocoType *>(&veh))
73                 return *loco;
74         
75         throw Exception("Vehicle is not a locomotive");
76 }
77
78
79 Catalogue::Loader::Loader(Catalogue &c):
80         DataFile::BasicLoader<Catalogue>(c)
81 {
82         add("ballast_profile", &Loader::ballast_profile);
83         add("gauge", &Loader::gauge);
84         add("layout", &Loader::layout);
85         add("locomotive", &Loader::locomotive);
86         add("rail_profile", &Loader::rail_profile);
87         add("scale", &Loader::scale);
88         add("track", &Loader::track);
89         add("vehicle", &Loader::vehicle);
90 }
91
92 void Catalogue::Loader::ballast_profile()
93 {
94         load_sub(obj.ballast_profile);
95 }
96
97 void Catalogue::Loader::gauge(float g)
98 {
99         obj.gauge = g/1000;
100         obj.path_profile = Profile();
101         obj.path_profile.append_point(Point(0.1*obj.gauge, 0));
102         obj.path_profile.append_point(Point(-0.1*obj.gauge, 0));
103 }
104
105 void Catalogue::Loader::layout()
106 {
107         load_sub(obj.layout);
108 }
109
110 void Catalogue::Loader::locomotive(unsigned art_nr)
111 {
112         RefPtr<LocoType> loco = new LocoType(art_nr);
113         load_sub(*loco);
114         obj.add_vehicle(*loco);
115         loco.release();
116 }
117
118 void Catalogue::Loader::rail_profile()
119 {
120         load_sub(obj.rail_profile);
121 }
122
123 void Catalogue::Loader::scale(float n, float d)
124 {
125         obj.scale = n/d;
126 }
127
128 void Catalogue::Loader::track(unsigned art_nr)
129 {
130         RefPtr<TrackType> trk = new TrackType(art_nr);
131         load_sub(*trk);
132         obj.add_track(*trk);
133         trk.release();
134 }
135
136 void Catalogue::Loader::vehicle(unsigned art_nr)
137 {
138         RefPtr<VehicleType> veh = new VehicleType(art_nr);
139         load_sub(*veh);
140         obj.add_vehicle(*veh);
141         veh.release();
142 }
143
144 } // namespace Marklin