X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibmarklin%2Fblock.cpp;h=03cb2dc3fa60c259f64590ed015a58f789c11c0f;hb=80e10207bee4d774f3015a5e946d463d2c828029;hp=b3a96e67f4f59850c58a599c92eced8dc70d96c4;hpb=06c100aacb559fbbe7380e15981c4772092c269b;p=r2c2.git diff --git a/source/libmarklin/block.cpp b/source/libmarklin/block.cpp index b3a96e6..03cb2dc 100644 --- a/source/libmarklin/block.cpp +++ b/source/libmarklin/block.cpp @@ -1,5 +1,13 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2006-2009 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + #include "control.h" #include "block.h" +#include "tracktype.h" #include "trafficmanager.h" #include "turnout.h" @@ -10,69 +18,65 @@ using namespace std; namespace Marklin { -Block::Block(TrafficManager &tm, Track *start): +Block::Block(TrafficManager &tm, Track &start): trfc_mgr(tm), id(next_id++), - sensor_id(0), + sensor_id(start.get_sensor_id()), train(0) { - tracks.insert(start); + tracks.insert(&start); - if(start->get_sensor_id()) - { - sensor_id=start->get_sensor_id(); - const Track::EndpointSeq &eps=start->get_endpoints(); - for(Track::EndpointSeq::const_iterator i=eps.begin(); i!=eps.end(); ++i) - endpoints.push_back(Endpoint(start, &*i)); - } - else - { - TrackSeq queue; - queue.push_back(start); + list queue; + queue.push_back(&start); - while(!queue.empty()) - { - Track *track=queue.front(); - queue.erase(queue.begin()); + while(!queue.empty()) + { + Track *track=queue.front(); + queue.erase(queue.begin()); - const Track::EndpointSeq &eps=track->get_endpoints(); - for(Track::EndpointSeq::const_iterator i=eps.begin(); i!=eps.end(); ++i) - if(i->link && tracks.count(i->link)==0) + const vector &links=track->get_links(); + for(unsigned i=0; iget_sensor_id()==sensor_id && !links[i]->get_turnout_id() && !track->get_turnout_id()) { - if(!i->link->get_sensor_id()) - { - queue.push_back(i->link); - tracks.insert(i->link); - } - else - endpoints.push_back(Endpoint(track, &*i)); + queue.push_back(links[i]); + tracks.insert(links[i]); } - } + else + endpoints.push_back(Endpoint(track, i)); + } } - unsigned n=0; - for(EndpointSeq::iterator i=endpoints.begin(); i!=endpoints.end(); ++i, ++n) + for(unsigned i=0; iroutes|=route; + unsigned route=1< visited; - find_routes(i->track, i->track_ep, route, visited); + find_routes(*endpoints[i].track, endpoints[i].track_ep, route, visited); } } -const Block::Endpoint *Block::get_endpoint_by_link(const Block *other) const +int Block::get_endpoint_by_link(const Block &other) const { - for(EndpointSeq::const_iterator i=endpoints.begin(); i!=endpoints.end(); ++i) - if(i->link==other) - return &*i; + for(unsigned i=0; itrack; - const Track::Endpoint *track_ep=ep->track_ep; + if(epi>=endpoints.size()) + throw InvalidParameterValue("Endpoint index out of range"); + + const Endpoint &ep=endpoints[epi]; + Track *track=ep.track; + unsigned track_ep=ep.track_ep; + + if(len) + *len=0; while(1) { @@ -80,36 +84,38 @@ const Block::Endpoint *Block::traverse(const Endpoint *ep) const unsigned tid=track->get_turnout_id(); if(tid) { - Turnout *turnout=trfc_mgr.get_control().get_turnout(tid); - if(turnout) - cur_route=turnout->get_route(); + Turnout &turnout=trfc_mgr.get_control().get_turnout(tid); + cur_route=turnout.get_route(); } - const Track::Endpoint *other_ep=track->traverse(track_ep, cur_route); - if(!other_ep) - return 0; + if(len) + *len+=track->get_type().get_route_length(cur_route); - for(EndpointSeq::const_iterator i=endpoints.begin(); i!=endpoints.end(); ++i) - if(i->track==track && i->track_ep==other_ep) - return &*i; + int other_ep=track->traverse(track_ep, cur_route); + if(other_ep<0) + return -1; - track_ep=other_ep->link->get_endpoint_by_link(track); - track=other_ep->link; + for(unsigned i=0; i(other_ep)) + return i; - if(tracks.count(track)==0) - return 0; + Track *next=track->get_link(other_ep); + if(tracks.count(next)==0) + return -1; + track_ep=next->get_endpoint_by_link(*track); + track=next; } } void Block::check_link(Block &other) { - for(EndpointSeq::iterator i=endpoints.begin(); i!=endpoints.end(); ++i) + for(vector::iterator i=endpoints.begin(); i!=endpoints.end(); ++i) { if(i->link) continue; - for(EndpointSeq::iterator j=other.endpoints.begin(); j!=other.endpoints.end(); ++j) - if(j->track==i->track_ep->link && j->track_ep->link==i->track && !j->link) + 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; @@ -117,12 +123,22 @@ void Block::check_link(Block &other) } } +Block *Block::get_link(unsigned epi) const +{ + if(epi>=endpoints.size()) + throw InvalidParameterValue("Endpoint index out of range"); + return endpoints[epi].link; +} + bool Block::reserve(const Train *t) { if(!t || !train) { train=t; - cout<<"Block "<get_name()<<'\n'; + else + cout<<"Block "<get_sensor_id()) cout<<", sensor="<<(*tracks.begin())->get_sensor_id(); cout<<'\n'; - for(EndpointSeq::iterator i=endpoints.begin(); i!=endpoints.end(); ++i) + for(vector::iterator i=endpoints.begin(); i!=endpoints.end(); ++i) { cout<<" Endpoint, link="; if(i->link) @@ -147,35 +163,34 @@ void Block::print_debug() } } -void Block::find_routes(Track *track, const Track::Endpoint *track_ep, unsigned route, std::set &visited) +void Block::find_routes(Track &track, unsigned track_ep, unsigned route, set &visited) { - visited.insert(track); + visited.insert(&track); - const Track::EndpointSeq &eps=track->get_endpoints(); - for(Track::EndpointSeq::const_iterator i=eps.begin(); i!=eps.end(); ++i) + const vector &eps=track.get_type().get_endpoints(); + for(unsigned i=0; ilink) continue; - if(!(i->routes&track_ep->routes)) continue; - if(visited.count(i->link)) continue; - - if(tracks.count(i->link)) - find_routes(i->link, i->link->get_endpoint_by_link(track), route, visited); + if(i==track_ep) continue; + Track *link=track.get_link(i); + if(!link) continue; + if(visited.count(link)) continue; + if(!(eps[i].routes&eps[track_ep].routes)) continue; + + if(tracks.count(link)) + find_routes(*link, link->get_endpoint_by_link(track), route, visited); else { - for(EndpointSeq::iterator j=endpoints.begin(); j!=endpoints.end(); ++j) - if(j->track==track && j->track_ep==&*i) + for(vector::iterator j=endpoints.begin(); j!=endpoints.end(); ++j) + if(j->track==&track && j->track_ep==i) j->routes|=route; } } - - visited.erase(--visited.end()); } unsigned Block::next_id=1; -Block::Endpoint::Endpoint(Track *t, const Track::Endpoint *e): +Block::Endpoint::Endpoint(Track *t, unsigned e): track(t), track_ep(e), link(0),