From 13f72e25cd6cb68d7fa0c0ab798616a148c39e43 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 10 Jul 2013 20:04:26 +0300 Subject: [PATCH] Fix block releasing logic The previous attempt didn't release any blocks if the last vehicle was still behind the last active sensor, which is almost always the case. And if it did manage to release anything, it would have released too much. --- source/libr2c2/blockallocator.cpp | 42 ++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/source/libr2c2/blockallocator.cpp b/source/libr2c2/blockallocator.cpp index 8d3381d..a054c15 100644 --- a/source/libr2c2/blockallocator.cpp +++ b/source/libr2c2/blockallocator.cpp @@ -312,14 +312,14 @@ void BlockAllocator::advance_back() /* Sensors aren't guaranteed to be detriggered in order. Go through the block list and locate the first sensor that's still active. */ - Sensor *last_inactive = 0; - for(BlockList::iterator i=blocks.begin(); (i!=cur_blocks_end && i->block()!=&veh_block); ++i) + BlockList::iterator end = blocks.end(); + for(BlockList::iterator i=blocks.begin(); i!=cur_blocks_end; ++i) { + Block *block = &**i; list sensors; - if(Sensor *sensor = (*i)->get_sensor()) - sensors.push_back(sensor); - Block *block = &**i; + /* Collect all sensors from the block in the order they are expected to + detrigger. */ for(TrackIter j=i->track_iter(); (j && &j->get_block()==block); j=j.next()) if(!j->get_attachments().empty()) { @@ -329,20 +329,32 @@ void BlockAllocator::advance_back() sensors.push_back(gate); } - for(list::const_iterator j=sensors.begin(); j!=sensors.end(); ++j) + if(Sensor *sensor = (*i)->get_sensor()) + sensors.push_back(sensor); + + /* See if any sensor is still active, and record the position of the + last inactive sensor. */ + bool active_sensor = false; + for(list::const_iterator j=sensors.begin(); (!active_sensor && j!=sensors.end()); ++j) { if((*j)->get_state()) + active_sensor = true; + else + end = i; + } + + // Stop if we encounter an active sensor or the train's last vehicle + if(block==&veh_block || active_sensor) + { + if(end!=blocks.end()) { - if(last_inactive) - { - if(dynamic_cast(*j)) - ++i; - release_blocks_begin(i); - } - return; + /* If the last inactive sensor was in an earlier block, release + that block as well. */ + if(i!=end) + ++end; + release_blocks_begin(end); } - else - last_inactive = *j; + return; } } } -- 2.45.2