+
+ const Block::Endpoint &entry_ep = link->get_endpoints()[entry];
+
+ if(cur_route)
+ {
+ if(cur_route!=next_route && next_route && next_route->get_tracks().count(entry_ep.track))
+ cur_route = next_route;
+ else if(!cur_route->get_tracks().count(entry_ep.track))
+ {
+ // Keep the blocks if we arrived at the end of the route
+ if(!blocking_train)
+ {
+ good = last;
+ good_sens = nsens;
+ good_dist = dist;
+ end_of_route = true;
+ }
+ break;
+ }
+ }
+ else if(route && route->get_tracks().count(entry_ep.track))
+ cur_route = route;
+
+ if(link->get_endpoints().size()<2)
+ {
+ if(!blocking_train)
+ {
+ good = last;
+ good_sens = nsens;
+ good_dist = dist;
+ }
+ break;
+ }
+
+ if(blocking_train)
+ {
+ if(link->get_train()!=blocking_train)
+ {
+ // XXX is it possible that this won't free all the blocks we want?
+ if(blocking_train->free_block(*contested_blocks.back().block))
+ {
+ // Roll back and start actually reserving the blocks
+ last = &rsv_blocks.back();
+ if(blocking_train->get_priority()==priority)
+ blocking_train->yield_to(*this);
+ blocking_train = 0;
+ continue;
+ }
+ else
+ {
+ pending_block = contested_blocks.front().block;
+ break;
+ }
+ }
+ else
+ {
+ contested_blocks.push_back(BlockRef(link, entry));
+ last = &contested_blocks.back();
+ continue;
+ }
+ }
+
+ bool reserved = link->reserve(this);
+ if(!reserved)