+/* $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 {
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_paths()>=3);
if(unsigned sid=(*i)->get_sensor_id())
- new Sensor(control, sid);
+ if(!control.get_sensors().count(sid))
+ 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(unsigned id) const
+{
+ for(list<Block *>::const_iterator i=blocks.begin(); i!=blocks.end(); ++i)
+ if((*i)->get_id()==id)
+ return **i;
+
+ throw KeyError("Unknown block", lexical_cast(id));
+}
+
+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_path_changed(unsigned, Turnout *)
+{
+}
+
+
+TrafficManager::Loader::Loader(TrafficManager &tm):
+ DataFile::BasicLoader<TrafficManager>(tm)
+{
+ add("train", &Loader::train);
}
-void TrafficManager::turnout_route_changed(unsigned, Turnout *)
+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