X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibmarklin%2Fblock.cpp;h=e8e367f7255715dc3c7ac2343763ae7da11021bf;hb=9b05c573a38639827697fe393d55b7c76f5bde45;hp=780ee1bbd293e75a9e442f6a83a80c8a38a28f26;hpb=2029c5e4220e0809a39744a28ca9e2ff22e8ad28;p=r2c2.git diff --git a/source/libmarklin/block.cpp b/source/libmarklin/block.cpp index 780ee1b..e8e367f 100644 --- a/source/libmarklin/block.cpp +++ b/source/libmarklin/block.cpp @@ -9,6 +9,7 @@ Distributed under the GPL #include "block.h" #include "layout.h" #include "route.h" +#include "trackiter.h" #include "tracktype.h" using namespace std; @@ -24,6 +25,7 @@ Block::Block(Layout &l, Track &start): train(0) { tracks.insert(&start); + start.set_block(this); list queue; queue.push_back(&start); @@ -41,6 +43,7 @@ Block::Block(Layout &l, Track &start): { queue.push_back(links[i]); tracks.insert(links[i]); + links[i]->set_block(this); } else endpoints.push_back(Endpoint(track, i)); @@ -53,8 +56,7 @@ Block::Block(Layout &l, Track &start): { unsigned path = 1< visited; - find_paths(*endpoints[i].track, endpoints[i].track_ep, path, visited); + find_paths(TrackIter(endpoints[i].track, endpoints[i].track_ep), path); } layout.add_block(*this); @@ -62,6 +64,11 @@ Block::Block(Layout &l, Track &start): 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) { @@ -77,6 +84,14 @@ bool Block::has_track(Track &t) const return tracks.count(&t); } +const Block::Endpoint &Block::get_endpoint(unsigned i) const +{ + if(i>=endpoints.size()) + throw InvalidParameterValue("Endpoint index out of range"); + + return endpoints[i]; +} + int Block::get_endpoint_by_link(Block &other) const { for(unsigned i=0; i=endpoints.size()) + if(entry>=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; + TrackIter t_iter(endpoints[entry].track, endpoints[entry].track_ep); - while(1) + float result = 0; + while(t_iter && has_track(*t_iter)) { - 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_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)) - throw LogicError("Block traversal strayed out of the block"); - track_ep = next->get_endpoint_by_link(*track); - track = next; + unsigned path = (route ? route->get_path(*t_iter) : t_iter->get_active_path()); + result += t_iter->get_type().get_path_length(path); + + t_iter = t_iter.next(path); } + + return result; } void Block::check_link(Block &other) @@ -176,28 +169,25 @@ bool Block::reserve(Train *t) return false; } -void Block::find_paths(Track &track, unsigned track_ep, unsigned path, set &visited) +void Block::find_paths(TrackIter track, unsigned path) { - visited.insert(&track); - - const vector &eps = track.get_type().get_endpoints(); - for(unsigned i=0; iget_endpoint_by_link(track), path, visited); - else + 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==&track && j->track_ep==i) - j->paths |= path; + TrackIter next = track.next(i); + if(!next) + continue; + else if(has_track(*next)) + find_paths(track.next(i), path); + else + { + next = next.flip(); + for(vector::iterator j=endpoints.begin(); j!=endpoints.end(); ++j) + if(j->track==next.track() && j->track_ep==next.entry()) + j->paths |= path; + } } - } } void Block::determine_id()