]> git.tdb.fi Git - r2c2.git/blobdiff - source/libmarklin/trafficmanager.cpp
Add networking library and a remote control program
[r2c2.git] / source / libmarklin / trafficmanager.cpp
index cc2089b32780fdcc210bea450265ef606b69ee55..b7301d3dd63e19674ebc0f0896c9aa1ce3ff6f5e 100644 (file)
@@ -1,9 +1,23 @@
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2006-2009 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#include <algorithm>
+#include <msp/datafile/writer.h>
+#include <msp/time/utils.h>
+#include "catalogue.h"
 #include "control.h"
 #include "layout.h"
+#include "locotype.h"
+#include "tracktype.h"
 #include "trafficmanager.h"
 #include "turnout.h"
 
 using namespace std;
+using namespace Msp;
 
 namespace Marklin {
 
@@ -11,61 +25,111 @@ TrafficManager::TrafficManager(Control &c, Layout &l):
        control(c),
        layout(l)
 {
-       const set<Track *> &tracks=layout.get_tracks();
+       const set<Track *> &tracks = layout.get_tracks();
 
        set<Track *> used_tracks;
        for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
                if(unsigned tid=(*i)->get_turnout_id())
-                       new Turnout(control, tid);
+                       new Turnout(control, tid, (*i)->get_type().get_n_routes()>=3);
                if(unsigned sid=(*i)->get_sensor_id())
                        new Sensor(control, sid);
 
                if(used_tracks.count(*i)==0)
                {
-                       Block *block=new Block(*this, **i);
+                       Block *block = new Block(*this, **i);
                        blocks.push_back(block);
                        used_tracks.insert(block->get_tracks().begin(), block->get_tracks().end());
                }
        }
 
-       for(BlockSeq::iterator i=blocks.begin(); i!=blocks.end(); ++i)
-       {
-               for(BlockSeq::iterator j=i; j!=blocks.end(); ++j)
+       for(list<Block *>::iterator i=blocks.begin(); i!=blocks.end(); ++i)
+               for(list<Block *>::iterator j=i; j!=blocks.end(); ++j)
                        if(j!=i)
                                (*i)->check_link(**j);
-               (*i)->print_debug();
-       }
 }
 
 TrafficManager::~TrafficManager()
 {
-       for(BlockSeq::iterator i=blocks.begin(); i!=blocks.end(); ++i)
+       for(list<Block *>::iterator i=blocks.begin(); i!=blocks.end(); ++i)
                delete *i;
-       for(TrainSeq::iterator i=trains.begin(); i!=trains.end(); ++i)
+       for(list<Train *>::iterator i=trains.begin(); i!=trains.end(); ++i)
                delete *i;
 }
 
-Block *TrafficManager::get_block_by_track(const Track *t) const
+Block &TrafficManager::get_block_by_track(const Track &t) const
 {
-       for(BlockSeq::const_iterator i=blocks.begin(); i!=blocks.end(); ++i)
+       for(list<Block *>::const_iterator i=blocks.begin(); i!=blocks.end(); ++i)
        {
-               const set<Track *> &tracks=(*i)->get_tracks();
-               if(tracks.count(const_cast<Track *>(t)))
-                       return *i;
+               const set<Track *> &tracks = (*i)->get_tracks();
+               if(tracks.count(const_cast<Track *>(&t)))
+                       return **i;
        }
 
-       return 0;
+       throw InvalidParameterValue("Unknown track");
+}
+
+Train &TrafficManager::get_train_by_locomotive(const Locomotive &loco) const
+{
+       for(list<Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
+               if(&(*i)->get_locomotive()==&loco)
+                       return **i;
+
+       throw InvalidParameterValue("Unknown locomotive");
 }
 
 void TrafficManager::add_train(Train *t)
 {
        if(find(trains.begin(), trains.end(), t)==trains.end())
+       {
                trains.push_back(t);
+               signal_train_added.emit(*t);
+       }
+}
+
+void TrafficManager::tick()
+{
+       Time::TimeStamp t = Time::now();
+       Time::TimeDelta dt;
+       if(last_tick)
+               dt = t-last_tick;
+       last_tick = t;
+
+       for(list<Train *>::iterator i=trains.begin(); i!=trains.end(); ++i)
+               (*i)->tick(t, dt);
+}
+
+void TrafficManager::save(const string &fn) const
+{
+       IO::BufferedFile out(fn, IO::M_WRITE);
+       DataFile::Writer writer(out);
+       for(list<Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
+       {
+               const Locomotive &loco = (*i)->get_locomotive();
+               DataFile::Statement st("train");
+               st.append(loco.get_type().get_article_number());
+               st.append(loco.get_address());
+               (*i)->save(st.sub);
+               writer.write(st);
+       }
 }
 
 void TrafficManager::turnout_route_changed(unsigned, Turnout *)
 {
 }
 
+
+TrafficManager::Loader::Loader(TrafficManager &tm):
+       DataFile::BasicLoader<TrafficManager>(tm)
+{
+       add("train", &Loader::train);
+}
+
+void TrafficManager::Loader::train(unsigned art_nr, unsigned addr)
+{
+       Locomotive *loco = new Locomotive(obj.layout.get_catalogue().get_locomotive(art_nr), obj.control, addr);
+       Train *trn = new Train(obj, *loco);
+       load_sub(*trn);
+}
+
 } // namespace Marklin