]> git.tdb.fi Git - r2c2.git/blob - source/libmarklin/trafficmanager.cpp
49dda42954d05ccdcb8b58f067899743111c4dbf
[r2c2.git] / source / libmarklin / trafficmanager.cpp
1 /* $Id$
2
3 This file is part of the MSP Märklin suite
4 Copyright © 2006-2009 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #include <algorithm>
9 #include <msp/datafile/writer.h>
10 #include <msp/time/utils.h>
11 #include "catalogue.h"
12 #include "control.h"
13 #include "layout.h"
14 #include "locotype.h"
15 #include "tracktype.h"
16 #include "trafficmanager.h"
17 #include "turnout.h"
18
19 using namespace std;
20 using namespace Msp;
21
22 namespace Marklin {
23
24 TrafficManager::TrafficManager(Control &c, Layout &l):
25         control(c),
26         layout(l)
27 {
28         const set<Track *> &tracks = layout.get_tracks();
29
30         set<Track *> used_tracks;
31         for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
32         {
33                 if(unsigned tid=(*i)->get_turnout_id())
34                         new Turnout(control, tid, (*i)->get_type().get_n_paths()>=3);
35                 if(unsigned sid=(*i)->get_sensor_id())
36                         if(!control.get_sensors().count(sid))
37                                 new Sensor(control, sid);
38
39                 if(used_tracks.count(*i)==0)
40                 {
41                         Block *block = new Block(*this, **i);
42                         blocks.push_back(block);
43                         used_tracks.insert(block->get_tracks().begin(), block->get_tracks().end());
44                 }
45         }
46
47         for(list<Block *>::iterator i=blocks.begin(); i!=blocks.end(); ++i)
48                 for(list<Block *>::iterator j=i; j!=blocks.end(); ++j)
49                         if(j!=i)
50                                 (*i)->check_link(**j);
51 }
52
53 TrafficManager::~TrafficManager()
54 {
55         for(list<Block *>::iterator i=blocks.begin(); i!=blocks.end(); ++i)
56                 delete *i;
57         for(list<Train *>::iterator i=trains.begin(); i!=trains.end(); ++i)
58                 delete *i;
59 }
60
61 Block &TrafficManager::get_block(unsigned id) const
62 {
63         for(list<Block *>::const_iterator i=blocks.begin(); i!=blocks.end(); ++i)
64                 if((*i)->get_id()==id)
65                         return **i;
66
67         throw KeyError("Unknown block", lexical_cast(id));
68 }
69
70 Block &TrafficManager::get_block_by_track(const Track &t) const
71 {
72         for(list<Block *>::const_iterator i=blocks.begin(); i!=blocks.end(); ++i)
73         {
74                 const set<Track *> &tracks = (*i)->get_tracks();
75                 if(tracks.count(const_cast<Track *>(&t)))
76                         return **i;
77         }
78
79         throw InvalidParameterValue("Unknown track");
80 }
81
82 Train &TrafficManager::get_train_by_locomotive(const Locomotive &loco) const
83 {
84         for(list<Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
85                 if(&(*i)->get_locomotive()==&loco)
86                         return **i;
87
88         throw InvalidParameterValue("Unknown locomotive");
89 }
90
91 void TrafficManager::add_train(Train *t)
92 {
93         if(find(trains.begin(), trains.end(), t)==trains.end())
94         {
95                 trains.push_back(t);
96                 signal_train_added.emit(*t);
97         }
98 }
99
100 void TrafficManager::tick()
101 {
102         Time::TimeStamp t = Time::now();
103         Time::TimeDelta dt;
104         if(last_tick)
105                 dt = t-last_tick;
106         last_tick = t;
107
108         for(list<Train *>::iterator i=trains.begin(); i!=trains.end(); ++i)
109                 (*i)->tick(t, dt);
110 }
111
112 void TrafficManager::save(const string &fn) const
113 {
114         IO::BufferedFile out(fn, IO::M_WRITE);
115         DataFile::Writer writer(out);
116         for(list<Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
117         {
118                 const Locomotive &loco = (*i)->get_locomotive();
119                 DataFile::Statement st("train");
120                 st.append(loco.get_type().get_article_number());
121                 st.append(loco.get_address());
122                 (*i)->save(st.sub);
123                 writer.write(st);
124         }
125 }
126
127 void TrafficManager::turnout_path_changed(unsigned, Turnout *)
128 {
129 }
130
131
132 TrafficManager::Loader::Loader(TrafficManager &tm):
133         DataFile::BasicLoader<TrafficManager>(tm)
134 {
135         add("train", &Loader::train);
136 }
137
138 void TrafficManager::Loader::train(unsigned art_nr, unsigned addr)
139 {
140         Locomotive *loco = new Locomotive(obj.layout.get_catalogue().get_locomotive(art_nr), obj.control, addr);
141         Train *trn = new Train(obj, *loco);
142         load_sub(*trn);
143 }
144
145 } // namespace Marklin