X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibr2c2%2Fsignal.cpp;h=a858e0dc92b99293eb142f8172f7902d563acb22;hb=5c1ddd2f213af3fea15237e02f7da112c0abba36;hp=6efc250256477a7115cae0cff3962da7667be158;hpb=3acb396462f2d6361423b744e489c13ef64c8114;p=r2c2.git diff --git a/source/libr2c2/signal.cpp b/source/libr2c2/signal.cpp index 6efc250..a858e0d 100644 --- a/source/libr2c2/signal.cpp +++ b/source/libr2c2/signal.cpp @@ -1,4 +1,5 @@ #include "blockiter.h" +#include "catalogue.h" #include "driver.h" #include "layout.h" #include "signal.h" @@ -13,14 +14,13 @@ using namespace Msp; namespace R2C2 { Signal::Signal(Layout &l, const SignalType &t): - layout(l), + Object(l), type(t), address(0), track(0), block(0), entry(0), train(0), - check_train_direction(false), check_allocated_blocks(false), passing(false) { @@ -34,6 +34,14 @@ Signal::~Signal() layout.remove_signal(*this); } +Signal *Signal::clone(Layout *to_layout) const +{ + Signal *sig = new Signal((to_layout ? *to_layout : layout), type); + sig->set_position(position); + sig->set_rotation(rotation); + return sig; +} + void Signal::set_address(unsigned a) { address = a; @@ -43,78 +51,86 @@ void Signal::set_address(unsigned a) } void Signal::set_position(const Vector &p) +{ + position = p; + + update_location(); +} + +void Signal::update_location() { const set &tracks = layout.get_tracks(); + float limit = layout.get_catalogue().get_gauge()*2; float dist = -1; for(set::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) if(!(*i)->get_type().is_turnout()) { - TrackPoint n = (*i)->get_nearest_point(p); - float d = distance(p, n.pos); + Snap sn; + sn.position = position; + sn.rotation = rotation; + (*i)->snap(sn, limit, SNAP_SEGMENT); + float d = distance(position, sn.position); if(dget_block(); + if(!track) + return; unsigned n_endpoints = track->get_type().get_endpoints().size(); for(unsigned j=0; jget_endpoint_direction(j)-direction; - while(a<-M_PI/2) - a += M_PI*2; - while(a>M_PI*3/2) - a -= M_PI*2; - if(a>=M_PI/2) + Angle a = wrap_with_base(track->get_snap_node(j).rotation-rotation, -Angle::quarter_turn()); + if(a>=Angle::quarter_turn()) { BlockIter biter = TrackIter(track, j).block_iter(); - entry = biter.entry(); + if(biter) + { + block = &track->get_block(); + entry = biter.entry(); + } } } } -void Signal::set_direction(float d) +void Signal::set_rotation(const Angle &r) { - float a = direction-d; - while(a>M_PI*3/2) - a -= M_PI*2; - while(a<-M_PI/2) - a += M_PI*2; - if(a>=M_PI/2) - { - direction += M_PI; - if(direction>M_PI*2) - direction -= M_PI*2; - } + rotation = r; - normalize_location(); + update_location(); } -void Signal::tick(const Time::TimeDelta &) +unsigned Signal::get_n_snap_nodes() const { - if(check_train_direction) - { - int train_entry = train->get_entry_to_block(*block); - if(train_entry>=0 && static_cast(train_entry)==entry) - { - if(train_conn) - train_conn.disconnect(); - train_conn = train->signal_advanced.connect(sigc::mem_fun(this, &Signal::train_advanced)); - } - check_train_direction = false; - check_allocated_blocks = true; - } + return 1; +} + +Snap Signal::get_snap_node(unsigned i) const +{ + if(i>=1) + throw out_of_range("Signal::get_snap_node"); + + Snap sn; + sn.position = position; + sn.rotation = rotation; + return sn; +} + +SnapType Signal::get_default_snap_type_to(const Object &other) const +{ + if(dynamic_cast(&other)) + return SNAP_SEGMENT; + + return NO_SNAP; +} +void Signal::tick(const Time::TimeDelta &) +{ if(check_allocated_blocks) { unsigned n_blocks = 0; @@ -147,9 +163,16 @@ void Signal::block_reserved(const Block &b, Train *t) { if(t) { - train = t; - passing = false; - check_train_direction = true; + const BlockIter &b_iter = t->get_block_allocator().iter_for(b); + if(b_iter && b_iter.entry()==entry) + { + if(train_conn) + train_conn.disconnect(); + train = t; + passing = false; + train_conn = train->signal_advanced.connect(sigc::mem_fun(this, &Signal::train_advanced)); + check_allocated_blocks = true; + } } else { @@ -177,14 +200,13 @@ void Signal::reset() train = 0; if(train_conn) train_conn.disconnect(); - check_train_direction = false; check_allocated_blocks = false; } void Signal::save(list &st) const { st.push_back((DataFile::Statement("position"), position.x, position.y, position.z)); - st.push_back((DataFile::Statement("direction"), direction)); + st.push_back((DataFile::Statement("rotation"), rotation.radians())); if(address) st.push_back((DataFile::Statement("address"), address)); } @@ -193,9 +215,9 @@ void Signal::save(list &st) const Signal::Loader::Loader(Signal &s): DataFile::ObjectLoader(s) { - add("address", &Loader::address); - add("direction", &Loader::direction); - add("position", &Loader::position); + add("address", &Loader::address); + add("position", &Loader::position); + add("rotation", &Loader::rotation); } void Signal::Loader::address(unsigned a) @@ -203,14 +225,14 @@ void Signal::Loader::address(unsigned a) obj.set_address(a); } -void Signal::Loader::direction(float d) +void Signal::Loader::position(float x, float y, float z) { - obj.set_direction(d); + obj.set_position(Vector(x, y, z)); } -void Signal::Loader::position(float x, float y, float z) +void Signal::Loader::rotation(float d) { - obj.set_position(Vector(x, y, z)); + obj.set_rotation(Angle::from_radians(d)); } } // namespace R2C2