-void Train::block_state_changed(Block &block, Block::State state)
-{
- if(state==Block::MAYBE_ACTIVE)
- {
- // Find the first sensor block from our reserved blocks that isn't this sensor
- BlockList::iterator end;
- unsigned result = 0;
- for(end=cur_blocks_end; end!=blocks.end(); ++end)
- if((*end)->get_sensor_id())
- {
- if(&**end!=&block)
- {
- if(result==0)
- result = 2;
- else if(result==1)
- break;
- }
- else if(result==0)
- result = 1;
- else if(result==2)
- result = 3;
- }
-
- if(result==1)
- {
- // Compute speed and update related state
- float travel_time_secs = (Time::now()-last_entry_time)/Time::sec;
-
- if(pure_speed && speed_quantizer && current_speed_step>0 && travel_time_secs>=2)
- speed_quantizer->learn(current_speed_step, travel_dist/travel_time_secs, travel_time_secs);
-
- travel_dist = 0;
- for(BlockList::iterator j=cur_blocks_end; j!=end; ++j)
- {
- travel_dist += (*j)->get_path_length(j->entry());
-
- if(&**j==&block && !advancing)
- {
- TrackIter track = j->track_iter();
- if(reverse)
- {
- track = track.flip();
- vehicles.back()->place(*track, track.entry(), 0, Vehicle::BACK_AXLE);
- }
- else
- vehicles.front()->place(*track, track.entry(), 0, Vehicle::FRONT_AXLE);
- }
- }
- last_entry_time = Time::now();
- pure_speed = true;
- accurate_position = true;
- overshoot_dist = 0;
-
- // Check if we've reached the next route
- if(routes.size()>1)
- {
- const Route &route = **(++routes.begin());
- for(BlockList::iterator j=cur_blocks_end; j!=end; ++j)
- if(route.has_track(*j->track_iter()))
- {
- routes.pop_front();
- // XXX Exceptions?
- signal_route_changed.emit(routes.front());
- break;
- }
- }
-
- // Move blocks up to the next sensor to our current blocks
- for(BlockList::iterator j=cur_blocks_end; j!=end; ++j)
- signal_advanced.emit(**j);
- cur_blocks_end = end;
-
- // Try to get more blocks if we're moving
- if(active)
- reserve_more();
- }
- else if(result==3)
- layout.emergency("Sensor for "+name+" triggered out of order");
- }
- else if(state==Block::INACTIVE)
- {
- const Vehicle &veh = *(reverse ? vehicles.front() : vehicles.back());
-
- // Find the first sensor in our current blocks that's still active
- BlockList::iterator end = blocks.begin();
- for(BlockList::iterator i=blocks.begin(); i!=cur_blocks_end; ++i)
- {
- if((*i)->has_track(*veh.get_track()))
- break;
- if((*i)->get_sensor_id())
- {
- if(layout.get_driver().get_sensor((*i)->get_sensor_id()))
- break;
- else
- {
- end = i;
- ++end;
- }
- }
- }
-
- if(end!=blocks.begin() && end!=cur_blocks_end)
- // Free blocks up to the last inactive sensor
- release_blocks(blocks.begin(), end);
- }
-}
-
-void Train::turnout_path_changed(Track &track)
-{
- for(list<BlockIter>::iterator i=blocks.begin(); i!=blocks.end(); ++i)
- if((*i)->get_turnout_id()==track.get_turnout_id() && !reserving)
- check_turnout_paths(false);
-}
-
-void Train::halt_event(bool h)
-{
- if(h)
- accurate_position = false;
-}
-
-void Train::block_reserved(const Block &block, const Train *train)