- // If we found another train and it's not headed straight for us, we can keep the blocks we got
- int other_entry = link->get_train()->get_entry_to_block(*link);
+ 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)
+ {
+ /* We've found another train. 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. */
+ Train *other_train = link->get_train();
+ int other_entry = other_train->get_entry_to_block(*link);