- }
- else
- b_iter_next = b_iter.next();
-
- // Check if there's another train and ask it to free the block if appropriate
- if(b_iter_next)
- {
- if(Train *other_train = b_iter_next->get_train())
- {
- /* There's another train ahead of us. If it wants to exit the block
- from the same endpoint we're trying to enter from or the other way
- around, treat it as coming towards us. Otherwise treat it as going
- in the same direction. */
- int other_entry = other_train->get_entry_to_block(*b_iter_next);
- if(other_entry<0)
- throw logic_error("block reservation inconsistency");
-
- unsigned exit = b_iter_next.reverse().entry();
- unsigned other_exit = BlockIter(b_iter_next.block(), other_entry).reverse().entry();
- bool entry_conflict = (b_iter_next.entry()==other_exit);
- bool exit_conflict = (exit==static_cast<unsigned>(other_entry));
- // TODO: speed matching with preceding train
-
- TrainRouter *other_router = other_train->get_ai_of_type<TrainRouter>();
- int other_prio = (other_router ? other_router->get_priority() : 0);
-
- if(!entry_conflict && !exit_conflict && other_prio<priority)
- {
- /* Ask a lesser priority train going to the same direction to free
- the block for us */
- other_train->free_block(*b_iter_next);
- }
- else if(other_train!=yielding_to && (other_prio<priority || (other_prio==priority && entry_conflict)))
- {
- /* A lesser priority train is coming at us, we must ask it to free
- enough blocks to get clear of it to avoid a potential deadlock */
- BlockIter last_contested;
- RouteList::iterator j = route;
- for(BlockIter i=b_iter_next; (i && i->get_train()==other_train);)
- {
- if(!advance_route(j, *i))
- break;
- last_contested = i;
- i = i.next(*j);
- }
-
- if(last_contested)
- {
- if(other_train->free_block(*last_contested))
- other_router->yield_to(train);
- else
- yield_to(*other_train);
- }
- }
- }