#include <cmath>
#include <msp/core/maputils.h>
+#include <msp/strings/format.h>
#include "block.h"
#include "catalogue.h"
#include "driver.h"
sensor_addr(0),
links(type.get_endpoints().size()),
active_path(0),
- path_changing(false)
+ path_changing(false),
+ preferred_exit(-1)
{
if(type.is_turnout())
{
Driver &driver = layout.get_driver();
turnout_id = driver.add_turnout(turnout_addr, type);
driver.signal_turnout.connect(sigc::mem_fun(this, &Track::turnout_event));
+ driver.signal_turnout_failed.connect(sigc::mem_fun(this, &Track::turnout_failed));
}
}
layout.add(*this);
-
for(unsigned paths = type.get_paths(); !(paths&1); ++active_path, paths>>=1) ;
}
layout.create_blocks(*this);
}
+void Track::set_preferred_exit(int e)
+{
+ preferred_exit = e;
+}
+
void Track::set_active_path(unsigned p)
{
if(!type.is_turnout())
if(!(type.get_paths()&(1<<p)))
throw invalid_argument("Track::set_active_path");
- signal_path_changing(p);
+ if(active_path==p)
+ return;
+
+ signal_path_changing.emit(p);
path_changing = true;
layout.get_driver().set_turnout(turnout_id, p);
}
if(!otrack)
return false;
- float limit = layout.get_catalogue().get_gauge();
+ float gauge_ratio = otrack->get_type().get_gauge()/type.get_gauge();
+ if(gauge_ratio<0.99 || gauge_ratio>1.01)
+ return false;
+
+ float limit = type.get_gauge();
if(!flex && !otrack->get_flex())
limit /= 10;
limit *= limit;
st.push_back((DataFile::Statement("flex"), true));
}
+void Track::save_dynamic(list<DataFile::Statement> &st) const
+{
+ if(turnout_addr)
+ st.push_back((DataFile::Statement("path"), active_path));
+}
+
void Track::turnout_event(unsigned id, unsigned state)
{
if(id==turnout_id)
}
}
+void Track::turnout_failed(unsigned id)
+{
+ if(id==turnout_id)
+ {
+ path_changing = false;
+ layout.emergency(block, "Turnout failed");
+ }
+}
+
Track::Loader::Loader(Track &t):
DataFile::ObjectLoader<Track>(t)
{
+ add("path", &Loader::path);
add("position", &Loader::position);
add("rotation", &Loader::rotation);
add("tilt", &Loader::tilt);
add("slope", &Loader::slope);
}
+void Track::Loader::path(unsigned p)
+{
+ obj.set_active_path(p);
+ if(obj.path_changing)
+ {
+ obj.active_path = p;
+ obj.signal_path_changed.emit(p);
+ }
+}
+
void Track::Loader::position(float x, float y, float z)
{
obj.set_position(Vector(x, y, z));