X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;ds=sidebyside;f=source%2Flibmarklin%2Ftrack.cpp;h=fbe3f0a709ffe1d2030c37fccee15b78ac134095;hb=9b05c573a38639827697fe393d55b7c76f5bde45;hp=030af70bc85fd1d2e667b4e47a24830a7ac915ea;hpb=e5cd9e4fbc577036a0385c985b6b65df8218d0a2;p=r2c2.git diff --git a/source/libmarklin/track.cpp b/source/libmarklin/track.cpp index 030af70..fbe3f0a 100644 --- a/source/libmarklin/track.cpp +++ b/source/libmarklin/track.cpp @@ -6,6 +6,8 @@ Distributed under the GPL */ #include +#include "block.h" +#include "catalogue.h" #include "driver.h" #include "layout.h" #include "track.h" @@ -19,12 +21,13 @@ namespace Marklin { Track::Track(Layout &l, const TrackType &t): layout(l), type(t), + block(0), rot(0), slope(0), flex(false), - turnout_id(0), + turnout_id(type.is_turnout() ? layout.allocate_turnout_id(type.is_double_address()) : 0), sensor_id(0), - links(t.get_endpoints().size()), + links(type.get_endpoints().size()), active_path(0) { layout.add_track(*this); @@ -41,6 +44,24 @@ Track::~Track() layout.remove_track(*this); } +void Track::set_block(Block *b) +{ + if(b && !b->has_track(*this)) + throw InvalidParameterValue("Track is not in the Block"); + if(!b && block && block->has_track(*this)) + throw InvalidState("Track is still in a Block"); + + block = b; +} + +Block &Track::get_block() const +{ + if(!block) + throw InvalidState("No Block"); + + return *block; +} + void Track::set_position(const Point &p) { pos = p; @@ -103,6 +124,7 @@ void Track::set_turnout_id(unsigned i) turnout_id = i; layout.create_blocks(*this); + layout.update_routes(); if(layout.has_driver() && turnout_id) { layout.get_driver().add_turnout(turnout_id); @@ -130,11 +152,13 @@ void Track::set_active_path(unsigned p) throw InvalidParameterValue("Invalid path"); layout.get_driver().set_turnout(turnout_id, p&1); - if(type.get_n_paths()>2) + if(type.is_double_address()) layout.get_driver().set_turnout(turnout_id+1, p&2); + else if(type.get_n_paths()>2) + active_path = (active_path&1) | (p&2); } -int Track::get_endpoint_by_link(const Track &other) const +int Track::get_endpoint_by_link(Track &other) const { for(unsigned i=0; i &eps = type.get_endpoints(); + const vector &eps = type.get_endpoints(); if(epi>=eps.size()) - throw InvalidParameterValue("Endpoint index out of range"); + throw InvalidParameterValue("TrackType::Endpoint index out of range"); - const Endpoint &ep = eps[epi]; + const TrackType::Endpoint &ep = eps[epi]; float c = cos(rot); float s = sin(rot); @@ -162,20 +186,27 @@ Point Track::get_endpoint_position(unsigned epi) const float Track::get_endpoint_direction(unsigned epi) const { - const vector &eps = type.get_endpoints(); + const vector &eps = type.get_endpoints(); if(epi>=eps.size()) - throw InvalidParameterValue("Endpoint index out of range"); + throw InvalidParameterValue("TrackType::Endpoint index out of range"); - const Endpoint &ep = eps[epi]; + const TrackType::Endpoint &ep = eps[epi]; return rot+ep.dir; } -bool Track::snap_to(Track &other, bool link) +bool Track::snap_to(Track &other, bool link, float limit) { - float limit = (link && !flex) ? 1e-6 : 1e-4; - const vector &eps = type.get_endpoints(); - const vector &other_eps = other.get_type().get_endpoints(); + if(!limit || link) + { + limit = layout.get_catalogue().get_gauge(); + if(link && !flex && !other.get_flex()) + limit /= 10; + } + limit *= limit; + + const vector &eps = type.get_endpoints(); + const vector &other_eps = other.get_type().get_endpoints(); for(unsigned i=0; i &eps = type.get_endpoints(); + const vector &eps = type.get_endpoints(); for(unsigned i=0; i &eps = type.get_endpoints(); - if(i>=eps.size()) - throw InvalidParameterValue("Endpoint index out of range"); - - const Endpoint &ep = eps[i]; - - if(ep.paths&(1<