X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibr2c2%2Fblock.cpp;h=25b3bc8b85163d0bfd2ece6a54718f02b840ec6d;hb=ece91e92af821bd6b468bd1134302efb7c28f019;hp=ca404de569046f2a2824eb7641bbbbbc20425c8e;hpb=1ff06c5bc46a677fa389ef86c6b26664368f1653;p=r2c2.git diff --git a/source/libr2c2/block.cpp b/source/libr2c2/block.cpp index ca404de..25b3bc8 100644 --- a/source/libr2c2/block.cpp +++ b/source/libr2c2/block.cpp @@ -1,14 +1,11 @@ -/* $Id$ - -This file is part of R²C² -Copyright © 2006-2010 Mikkosoft Productions, Mikko Rasa -Distributed under the GPL -*/ - #include +#include +#include +#include #include "block.h" #include "layout.h" #include "route.h" +#include "trackcircuit.h" #include "trackiter.h" #include "tracktype.h" @@ -18,48 +15,47 @@ using namespace Msp; namespace R2C2 { Block::Block(Layout &l, Track &start): - layout(l), + TrackChain(l), id(0), - sensor_id(start.get_sensor_id()), - turnout_id(start.get_turnout_id()), - train(0) + sensor_addr(start.get_sensor_address()), + turnout_addr(start.get_turnout_address()), + conflict(false), + sensor(0), + train(0), + pending_train(0), + emitting_reserve(false) { - tracks.insert(&start); - start.set_block(this); - - list queue; - queue.push_back(&start); + add_track(start); - while(!queue.empty()) + if(start.get_type().is_turnout()) { - Track *track = queue.front(); - queue.erase(queue.begin()); - - const vector &links = track->get_links(); - for(unsigned i=0; iget_sensor_id()==sensor_id && links[i]->get_turnout_id()==turnout_id) - { - queue.push_back(links[i]); - tracks.insert(links[i]); - links[i]->set_block(this); - } - else - endpoints.push_back(Endpoint(track, i)); - } + unsigned nls = start.get_n_link_slots(); + for(unsigned i=0; i &blocks = layout.get_all(); + for(set::const_iterator i=blocks.begin(); (!conflict && i!=blocks.end()); ++i) + conflict = (id==(*i)->get_id()); + + if(!conflict && sensor_addr) + sensor = new TrackCircuit(layout, *this); - layout.add_block(*this); + layout.add(*this); } Block::~Block() @@ -76,18 +72,33 @@ Block::~Block() blk->break_link(*this); } - layout.remove_block(*this); + layout.remove(*this); + + delete sensor; +} + +void Block::set_name(const string &) +{ + throw logic_error("Block names can't be set"); +} + +void Block::on_track_added(Track &track) +{ + track.set_block(this); } -bool Block::has_track(Track &t) const +TrackChain::Validity Block::check_validity(Track &track) const { - return tracks.count(&t); + if(track.get_sensor_address()!=sensor_addr || track.get_turnout_address()!=turnout_addr) + return INCOMPATIBLE; + + return TrackChain::check_validity(track); } const Block::Endpoint &Block::get_endpoint(unsigned i) const { if(i>=endpoints.size()) - throw InvalidParameterValue("Endpoint index out of range"); + throw out_of_range("Block::get_endpoint"); return endpoints[i]; } @@ -104,9 +115,9 @@ int Block::get_endpoint_by_link(Block &other) const float Block::get_path_length(unsigned entry, const Route *route) const { if(entry>=endpoints.size()) - throw InvalidParameterValue("Endpoint index out of range"); + throw out_of_range("Block::get_path_length"); - TrackIter t_iter(endpoints[entry].track, endpoints[entry].track_ep); + TrackIter t_iter = endpoints[entry].track_iter(); float result = 0; while(t_iter && has_track(*t_iter)) @@ -153,49 +164,44 @@ void Block::break_link(Block &other) Block *Block::get_link(unsigned epi) const { if(epi>=endpoints.size()) - throw InvalidParameterValue("Endpoint index out of range"); + throw out_of_range("Block::get_link"); return endpoints[epi].link; } bool Block::reserve(Train *t) { - if(!t || !train) + if(!t || !(emitting_reserve ? pending_train : train)) { - train = t; - layout.signal_block_reserved.emit(*this, train); - return true; - } - else - return false; -} - -void Block::find_paths(TrackIter track, unsigned path) -{ - unsigned mask = track.endpoint().paths; - for(unsigned i=0; mask>>i; ++i) - if(mask&(1<::iterator j=endpoints.begin(); j!=endpoints.end(); ++j) - if(j->track==next.track() && j->track_ep==next.entry()) - j->paths |= path; + train = pending_train; + SetFlag setf(emitting_reserve); + signal_reserved.emit(train); } } + + return true; + } + else + return false; } void Block::determine_id() { - if(sensor_id) - id = 0x1000|sensor_id; - else if(turnout_id) - id = 0x2000|turnout_id; + string n; + if(sensor_addr) + { + id = 0x1000|sensor_addr; + n = format("Sensor %d", sensor_addr); + } + else if(turnout_addr) + { + id = 0x2000|turnout_addr; + n = format("Turnout %d", turnout_addr); + } else if(endpoints.size()==2) { unsigned id1 = endpoints[0].link ? endpoints[0].link->get_id() : 1; @@ -209,14 +215,29 @@ void Block::determine_id() unsigned id1 = endpoints[0].link ? endpoints[0].link->get_id() : 1; id = 0x10000 | id1; } + + if(n.empty()) + n = format("Block %x", id); + + name = n; + signal_name_changed.emit(name); +} + +DataFile::Statement Block::save_reference() const +{ + return (DataFile::Statement("block"), id); } Block::Endpoint::Endpoint(Track *t, unsigned e): track(t), track_ep(e), - link(0), - paths(0) + link(0) { } +TrackIter Block::Endpoint::track_iter() const +{ + return TrackIter(track, track_ep); +} + } // namespace R2C2