- if(&block==pending_block && !train && !reserving)
- reserve_more();
-}
-
-void Train::reserve_more()
-{
- if(!active || blocks.empty())
- return;
-
- BlockIter start = blocks.back();
- if(&*start==stop_at_block)
- return;
- else if(&*start==pending_block)
- {
- TrackIter track = start.track_iter();
- if(!track.endpoint().has_path(track->get_active_path()))
- return;
- }
-
- pending_block = 0;
- preceding_train = 0;
-
- // See how many sensor blocks and how much track we already have
- unsigned nsens = 0;
- float dist = 0;
- for(BlockList::const_iterator i=cur_blocks_end; i!=blocks.end(); ++i)
- {
- if((*i)->get_sensor_id())
- ++nsens;
- if(nsens>0)
- dist += (*i)->get_path_length(i->entry());
- }
-
- float approach_margin = 50*layout.get_catalogue().get_scale();
- float min_dist = controller->get_braking_distance()*1.3+approach_margin*2;
-
- BlockIter block = start;
-
- SetFlag setf(reserving);
-
- while(1)
- {
- BlockIter last = block;
- block = block.next();
- if(!block || block->get_endpoints().size()<2)
- // The track ends here
- break;
-
- if(block->get_turnout_id() && !last->get_turnout_id())
- {
- /* We are arriving at a turnout. See if we have enough blocks and
- distance reserved. */
- if(nsens>=3 && dist>=min_dist)
- break;
- }
-
- blocks.push_back(block);
- if(!block->reserve(this))
- {
- blocks.pop_back();
- pending_block = &*block;
- break;
- }
-
- if(cur_blocks_end==blocks.end())
- --cur_blocks_end;
-
- TrackIter track = block.track_iter();
- if(track->is_path_changing())
- {
- pending_block = &*block;
- break;
- }
- else
- {
- const TrackType::Endpoint &entry_ep = track.endpoint();
- unsigned path = track->get_active_path();
- if(!entry_ep.has_path(path))
- {
- const TrackType::Endpoint &exit_ep = track.reverse().endpoint();
- if(entry_ep.has_common_paths(exit_ep))
- {
- unsigned mask = entry_ep.paths&exit_ep.paths;
- for(path=0; mask>1; ++path, mask>>=1) ;
-
- track->set_active_path(path);
- if(track->is_path_changing())
- {
- pending_block = &*block;
- break;
- }
- }
- else
- // XXX Do something here
- break;
- }
- }
-
- if(&*block==stop_at_block)
- break;
-
- if(block->get_sensor_id())
- ++nsens;
- if(nsens>0)
- dist += block->get_path_length(block.entry());
- }
-
- // Make any sensorless blocks at the beginning immediately current
- while(cur_blocks_end!=blocks.end() && !(*cur_blocks_end)->get_sensor_id())
- ++cur_blocks_end;
-}
-
-float Train::get_reserved_distance_until(const Block *until_block, bool back) const
-{
- if(blocks.empty())