]> git.tdb.fi Git - r2c2.git/blob - source/libmarklin/trafficmanager.cpp
4075415ac95fdbe703a3287ad0e1f8d6e586d2d0
[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_routes()>=3);
35                 if(unsigned sid=(*i)->get_sensor_id())
36                         new Sensor(control, sid);
37
38                 if(used_tracks.count(*i)==0)
39                 {
40                         Block *block=new Block(*this, **i);
41                         blocks.push_back(block);
42                         used_tracks.insert(block->get_tracks().begin(), block->get_tracks().end());
43                 }
44         }
45
46         for(list<Block *>::iterator i=blocks.begin(); i!=blocks.end(); ++i)
47                 for(list<Block *>::iterator j=i; j!=blocks.end(); ++j)
48                         if(j!=i)
49                                 (*i)->check_link(**j);
50 }
51
52 TrafficManager::~TrafficManager()
53 {
54         for(list<Block *>::iterator i=blocks.begin(); i!=blocks.end(); ++i)
55                 delete *i;
56         for(list<Train *>::iterator i=trains.begin(); i!=trains.end(); ++i)
57                 delete *i;
58 }
59
60 Block &TrafficManager::get_block_by_track(const Track &t) const
61 {
62         for(list<Block *>::const_iterator i=blocks.begin(); i!=blocks.end(); ++i)
63         {
64                 const set<Track *> &tracks=(*i)->get_tracks();
65                 if(tracks.count(const_cast<Track *>(&t)))
66                         return **i;
67         }
68
69         throw InvalidParameterValue("Unknown track");
70 }
71
72 void TrafficManager::add_train(Train *t)
73 {
74         if(find(trains.begin(), trains.end(), t)==trains.end())
75                 trains.push_back(t);
76 }
77
78 void TrafficManager::tick()
79 {
80         Time::TimeStamp t=Time::now();
81         Time::TimeDelta dt;
82         if(last_tick)
83                 dt=t-last_tick;
84         last_tick=t;
85
86         for(list<Train *>::iterator i=trains.begin(); i!=trains.end(); ++i)
87                 (*i)->tick(t, dt);
88 }
89
90 void TrafficManager::save(const string &fn) const
91 {
92         IO::BufferedFile out(fn, IO::M_WRITE);
93         DataFile::Writer writer(out);
94         for(list<Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
95         {
96                 const Locomotive &loco=(*i)->get_locomotive();
97                 DataFile::Statement st("train");
98                 st.append(loco.get_type().get_article_number());
99                 st.append(loco.get_address());
100                 (*i)->save(st.sub);
101                 writer.write(st);
102         }
103 }
104
105 void TrafficManager::turnout_route_changed(unsigned, Turnout *)
106 {
107 }
108
109
110 TrafficManager::Loader::Loader(TrafficManager &tm):
111         DataFile::BasicLoader<TrafficManager>(tm)
112 {
113         add("train", &Loader::train);
114 }
115
116 void TrafficManager::Loader::train(unsigned art_nr, unsigned addr)
117 {
118         Locomotive *loco=new Locomotive(obj.layout.get_catalogue().get_locomotive(art_nr), obj.control, addr);
119         Train *trn=new Train(obj, *loco);
120         load_sub(*trn);
121 }
122
123 } // namespace Marklin