#include "blockiter.h"
+#include "catalogue.h"
#include "driver.h"
#include "layout.h"
#include "signal.h"
namespace R2C2 {
Signal::Signal(Layout &l, const SignalType &t):
- Object(l),
+ TrackAttachment(l),
type(t),
address(0),
- track(0),
- block(0),
- entry(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() && address)
+ layout.get_driver().remove_sensor(address);
+ layout.remove(*this);
}
Signal *Signal::clone(Layout *to_layout) const
void Signal::set_address(unsigned a)
{
+ Driver *driver = (layout.has_driver() ? &layout.get_driver() : 0);
+
+ if(driver && address)
+ driver->remove_signal(address);
address = a;
-
- if(layout.has_driver() && address)
- layout.get_driver().add_signal(address, type);
+ if(driver && address)
+ driver->add_signal(address, type);
}
void Signal::set_position(const Vector &p)
{
- const set<Track *> &tracks = layout.get_tracks();
- float dist = -1;
- for(set<Track *>::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(d<dist || dist<0)
- {
- position = sn.position;
- rotation = sn.rotation;
- track = *i;
- dist = d;
- }
- }
+ position = p;
- normalize_location();
+ update_attachment();
+ signal_moved.emit();
}
-void Signal::normalize_location()
+void Signal::set_rotation(const Angle &r)
{
- block = &track->get_block();
+ rotation = r;
- unsigned n_endpoints = track->get_type().get_endpoints().size();
- for(unsigned j=0; j<n_endpoints; ++j)
- {
- 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();
- }
- }
+ 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
if(check_allocated_blocks)
{
unsigned n_blocks = 0;
- BlockIter iter(block, entry);
- iter = iter.next();
+ BlockIter iter = block.next();
while(iter && iter->get_train()==train)
{
- if(iter->get_sensor_id())
+ if(iter->get_sensor_address())
++n_blocks;
iter=iter.next();
}
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<unsigned>(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();
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);
reset();