X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibr2c2%2Fsignal.cpp;h=bece13d7c6078cd3dac8e300cc0ec5417b33fe89;hb=b36f3dc43853c76b4710cb1a7b932a758e1693a1;hp=3494467d84daf3c166ccbf851742712987b72d8d;hpb=7a36d396eded897c421424905b2c938d770df341;p=r2c2.git diff --git a/source/libr2c2/signal.cpp b/source/libr2c2/signal.cpp index 3494467..bece13d 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,24 +14,24 @@ using namespace Msp; namespace R2C2 { Signal::Signal(Layout &l, const SignalType &t): - Object(l), + TrackAttachment(l), type(t), address(0), - track(0), - block(0), - entry(0), + id(0), train(0), check_allocated_blocks(false), passing(false) { - layout.add_signal(*this); + layout.add(*this); layout.signal_block_reserved.connect(sigc::mem_fun(this, &Signal::block_reserved)); } Signal::~Signal() { - layout.remove_signal(*this); + if(layout.has_driver() && id) + layout.get_driver().remove_signal(id); + layout.remove(*this); } Signal *Signal::clone(Layout *to_layout) const @@ -43,59 +44,41 @@ Signal *Signal::clone(Layout *to_layout) const void Signal::set_address(unsigned a) { + Driver *driver = (layout.has_driver() ? &layout.get_driver() : 0); + + if(driver && id) + driver->remove_signal(id); address = a; - - if(layout.has_driver() && address) - layout.get_driver().add_signal(address, type); + if(driver && address) + id = driver->add_signal(address, type); + else + id = 0; } void Signal::set_position(const Vector &p) { - const set &tracks = layout.get_tracks(); - float dist = -1; - for(set::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) - if(!(*i)->get_type().is_turnout()) - { - Snap sn; - sn.position = p; - sn.rotation = rotation; - (*i)->snap(sn, 1000, SNAP_SEGMENT); - float d = distance(p, sn.position); - if(dget_block(); + rotation = r; - unsigned n_endpoints = track->get_type().get_endpoints().size(); - for(unsigned j=0; jget_snap_node(j).rotation-rotation, -Angle::quarter_turn()); - if(a>=Angle::quarter_turn()) - { - BlockIter biter = TrackIter(track, j).block_iter(); - entry = biter.entry(); - } - } + update_attachment(); + signal_moved.emit(); } -void Signal::set_rotation(const Angle &r) +void Signal::update_attachment() { - Angle a = wrap_with_base(rotation-r, -Angle::quarter_turn()); - if(a>=Angle::quarter_turn()) - rotation = wrap_positive(rotation+Angle::half_turn()); + attach_to_closest(2); - normalize_location(); + if(track) + block = track.block_iter(); + else + block = BlockIter(); } unsigned Signal::get_n_snap_nodes() const @@ -122,31 +105,21 @@ SnapType Signal::get_default_snap_type_to(const Object &other) const return NO_SNAP; } -bool Signal::collide_ray(const Vector &start, const Vector &ray) const -{ - // XXX Totally hardcoded stuff, should be replaced with a geometry system - Vector center = position+rotated_vector(Vector(0, -0.035, 0), rotation); - Vector span = center-start; - float x = (span.x*ray.x+span.y*ray.y)/(ray.x*ray.x+ray.y*ray.y); - Vector nearest = start+ray*x-center; - if(nearest.z<0 || nearest.z>0.12) - return false; - nearest.z = 0; - return dot(nearest, nearest)<0.0001; -} - void Signal::tick(const Time::TimeDelta &) { if(check_allocated_blocks) { unsigned n_blocks = 0; - BlockIter iter(block, entry); - iter = iter.next(); - while(iter && iter->get_train()==train) + const Block *last = train->get_block_allocator().last().block(); + if(block.block()!=last) { - if(iter->get_sensor_id()) - ++n_blocks; - iter=iter.next(); + BlockIter iter = block.next(); + while(iter && iter->get_train()==train && iter.block()!=last) + { + if(iter->get_sensor_address()) + ++n_blocks; + iter = iter.next(); + } } check_allocated_blocks = false; @@ -159,18 +132,18 @@ void Signal::tick(const Time::TimeDelta &) break; } - layout.get_driver().set_signal(address, aspect); + layout.get_driver().set_signal(id, aspect); } } void Signal::block_reserved(const Block &b, Train *t) { - if(&b==block) + if(&b==block.block()) { if(t) { - int train_entry = t->get_entry_to_block(*block); - if(train_entry>=0 && static_cast(train_entry)==entry) + const BlockIter &b_iter = t->get_block_allocator().iter_for(b); + if(b_iter && b_iter.entry()==block.entry()) { if(train_conn) train_conn.disconnect(); @@ -182,7 +155,7 @@ void Signal::block_reserved(const Block &b, Train *t) } else { - layout.get_driver().set_signal(address, type.get_indications().back().aspect); + layout.get_driver().set_signal(id, type.get_indications().back().aspect); reset(); } } @@ -192,11 +165,11 @@ void Signal::block_reserved(const Block &b, Train *t) void Signal::train_advanced(Block &b) { - if(&b==block) + if(&b==block.block()) passing = true; - else if(passing && b.get_sensor_id()) + else if(passing && b.get_sensor_address()) { - layout.get_driver().set_signal(address, type.get_indications().back().aspect); + layout.get_driver().set_signal(id, type.get_indications().back().aspect); reset(); } }