]> git.tdb.fi Git - r2c2.git/commitdiff
Fix block releasing logic
authorMikko Rasa <tdb@tdb.fi>
Wed, 10 Jul 2013 17:04:26 +0000 (20:04 +0300)
committerMikko Rasa <tdb@tdb.fi>
Wed, 10 Jul 2013 17:56:54 +0000 (20:56 +0300)
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

index 8d3381da20ecada6172781d064b9feba998e669a..a054c157331c9b5e9ed074da4fc99469e2b0ee8e 100644 (file)
@@ -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<Sensor *> 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<Sensor *>::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<Sensor *>::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<BeamGate *>(*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;
                }
        }
 }