X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibmarklin%2Fblock.cpp;h=ec07947d7e1cbffa500f05b29661ba7178b99fa8;hb=f74ce147edde73319e55475433adb8e1d87b7201;hp=ee0a48cb950498474e0fe7d2b8bc602a5ac77987;hpb=7839b7c3d782abb5c98a24d51cae109407068c02;p=r2c2.git diff --git a/source/libmarklin/block.cpp b/source/libmarklin/block.cpp index ee0a48c..ec07947 100644 --- a/source/libmarklin/block.cpp +++ b/source/libmarklin/block.cpp @@ -1,40 +1,40 @@ /* $Id$ This file is part of the MSP Märklin suite -Copyright © 2006-2009 Mikkosoft Productions, Mikko Rasa +Copyright © 2006-2010 Mikkosoft Productions, Mikko Rasa Distributed under the GPL */ -#include -#include "control.h" +#include #include "block.h" +#include "layout.h" +#include "route.h" #include "tracktype.h" -#include "trafficmanager.h" -#include "turnout.h" using namespace std; using namespace Msp; namespace Marklin { -Block::Block(TrafficManager &tm, Track &start): - trfc_mgr(tm), - id(next_id++), +Block::Block(Layout &l, Track &start): + layout(l), + id(0), sensor_id(start.get_sensor_id()), turnout_id(start.get_turnout_id()), train(0) { tracks.insert(&start); + start.set_block(this); list queue; queue.push_back(&start); while(!queue.empty()) { - Track *track=queue.front(); + Track *track = queue.front(); queue.erase(queue.begin()); - const vector &links=track->get_links(); + const vector &links = track->get_links(); for(unsigned i=0; iset_block(this); } else endpoints.push_back(Endpoint(track, i)); } } + determine_id(); + for(unsigned i=0; i visited; - find_routes(*endpoints[i].track, endpoints[i].track_ep, route, visited); + find_paths(*endpoints[i].track, endpoints[i].track_ep, path, visited); } + + layout.add_block(*this); +} + +Block::~Block() +{ + set trks = tracks; + tracks.clear(); + for(set::iterator i=trks.begin(); i!=trks.end(); ++i) + (*i)->set_block(0); + + for(vector::iterator i=endpoints.begin(); i!=endpoints.end(); ++i) + if(Block *blk = i->link) + { + i->link = 0; + blk->break_link(*this); + } + + layout.remove_block(*this); } -int Block::get_endpoint_by_link(const Block &other) const +bool Block::has_track(Track &t) const +{ + return tracks.count(&t); +} + +int Block::get_endpoint_by_link(Block &other) const { for(unsigned i=0; i=endpoints.size()) throw InvalidParameterValue("Endpoint index out of range"); - const Endpoint &ep=endpoints[epi]; - Track *track=ep.track; - unsigned track_ep=ep.track_ep; + const Endpoint &ep = endpoints[epi]; + Track *track = ep.track; + unsigned track_ep = ep.track_ep; if(len) - *len=0; + *len = 0; while(1) { - unsigned cur_route=0; - unsigned tid=track->get_turnout_id(); - if(tid) - { - Turnout &turnout=trfc_mgr.get_control().get_turnout(tid); - cur_route=turnout.get_route(); - } + int cur_path = -1; + if(track->get_turnout_id() && route) + cur_path = route->get_turnout(track->get_turnout_id()); + if(cur_path==-1) + cur_path = track->get_active_path(); if(len) - *len+=track->get_type().get_route_length(cur_route); - - int other_ep=track->traverse(track_ep, cur_route); - if(other_ep<0) - return -1; + *len += track->get_type().get_path_length(cur_path); + unsigned other_ep = track->traverse(track_ep, cur_path); for(unsigned i=0; i(other_ep)) return i; - Track *next=track->get_link(other_ep); - if(tracks.count(next)==0) - return -1; - track_ep=next->get_endpoint_by_link(*track); - track=next; + Track *next = track->get_link(other_ep); + if(!tracks.count(next)) + throw LogicError("Block traversal strayed out of the block"); + track_ep = next->get_endpoint_by_link(*track); + track = next; } } @@ -117,12 +144,26 @@ void Block::check_link(Block &other) for(vector::iterator j=other.endpoints.begin(); j!=other.endpoints.end(); ++j) if(j->track==i->track->get_link(i->track_ep) && j->track->get_link(j->track_ep)==i->track && !j->link) { - i->link=&other; - j->link=this; + i->link = &other; + j->link = this; + + determine_id(); + other.determine_id(); } } } +void Block::break_link(Block &other) +{ + for(vector::iterator i=endpoints.begin(); i!=endpoints.end(); ++i) + if(i->link==&other) + { + i->link = 0; + other.break_link(*this); + determine_id(); + } +} + Block *Block::get_link(unsigned epi) const { if(epi>=endpoints.size()) @@ -130,67 +171,69 @@ Block *Block::get_link(unsigned epi) const return endpoints[epi].link; } -bool Block::reserve(const Train *t) +bool Block::reserve(Train *t) { if(!t || !train) { - train=t; - trfc_mgr.signal_block_reserved.emit(*this, train); + train = t; + layout.signal_block_reserved.emit(*this, train); return true; } else return false; } -void Block::print_debug() -{ - cout<<"Block "<get_sensor_id()) - cout<<", sensor="<<(*tracks.begin())->get_sensor_id(); - cout<<'\n'; - for(vector::iterator i=endpoints.begin(); i!=endpoints.end(); ++i) - { - cout<<" Endpoint, link="; - if(i->link) - cout<link->id; - else - cout<<"none"; - cout<<", routes="<routes<<'\n'; - } -} - -void Block::find_routes(Track &track, unsigned track_ep, unsigned route, set &visited) +void Block::find_paths(Track &track, unsigned track_ep, unsigned path, set &visited) { visited.insert(&track); - const vector &eps=track.get_type().get_endpoints(); + const vector &eps = track.get_type().get_endpoints(); for(unsigned i=0; iget_endpoint_by_link(track), route, visited); + find_paths(*link, link->get_endpoint_by_link(track), path, visited); else { for(vector::iterator j=endpoints.begin(); j!=endpoints.end(); ++j) if(j->track==&track && j->track_ep==i) - j->routes|=route; + j->paths |= path; } } } -unsigned Block::next_id=1; +void Block::determine_id() +{ + if(sensor_id) + id = 0x1000|sensor_id; + else if(turnout_id) + id = 0x2000|turnout_id; + else if(endpoints.size()==2) + { + unsigned id1 = endpoints[0].link ? endpoints[0].link->get_id() : 1; + unsigned id2 = endpoints[1].link ? endpoints[1].link->get_id() : 1; + if(id2get_id() : 1; + id = 0x10000 | id1; + } +} Block::Endpoint::Endpoint(Track *t, unsigned e): track(t), track_ep(e), link(0), - routes(0) + paths(0) { } } // namespace Marklin