]> git.tdb.fi Git - r2c2.git/commitdiff
Consider block deallocation when planning routes
authorMikko Rasa <tdb@tdb.fi>
Fri, 6 Feb 2015 14:32:18 +0000 (16:32 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 6 Feb 2015 14:48:22 +0000 (16:48 +0200)
Blocks are not released until a sensor is detriggered.  Not taking that
into account could cause situations where the planner tries to drive
trains through a balloon loop which is actually too small for them.

source/libr2c2/trainrouteplanner.cpp

index a05e97ea7fb2fed688651a3b6b81c104d3d5d19c..5bffec1d899c535fc295bf2847faea29d7a2987d 100644 (file)
@@ -375,20 +375,37 @@ void TrainRoutePlanner::TrainRoutingState::advance(float distance)
        offset += distance;
        back_offset += distance;
 
-       OccupiedTrack *last_occ = occupied_tracks;
-       for(unsigned n=occupied_tracks->n_tracks; n>1; --n)
-               last_occ = last_occ->next;
+       unsigned count_to_free = 0;
+       unsigned last_sensor_addr = 0;
+       float distance_after_sensor = 0;
+       OccupiedTrack *occ = occupied_tracks;
+       for(unsigned n=occupied_tracks->n_tracks; n>0; --n)
+       {
+               if(unsigned saddr = occ->track->get_sensor_address())
+               {
+                       if(saddr!=last_sensor_addr)
+                       {
+                               count_to_free = 0;
+                               distance_after_sensor = 0;
+                       }
+                       last_sensor_addr = saddr;
+               }
+
+               ++count_to_free;
+               distance_after_sensor += occ->path_length;
+
+               occ = occ->next;
+       }
 
-       // XXX What if there's multiple tracks to remove?
-       if(back_offset>last_occ->path_length)
+       if(count_to_free && back_offset>distance_after_sensor)
        {
-               back_offset -= last_occ->path_length;
+               back_offset -= distance_after_sensor;
                if(occupied_tracks->refcount>1)
                {
                        --occupied_tracks->refcount;
                        occupied_tracks = new OccupiedTrack(*occupied_tracks);
                }
-               --occupied_tracks->n_tracks;
+               occupied_tracks->n_tracks -= count_to_free;
        }
 
        distance_traveled += distance;