]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/train.cpp
Tighten safety measures
[r2c2.git] / source / libr2c2 / train.cpp
index b7dc2470c4c1a98e98e5aae789c39e4130e1f31f..91387d85297e7f2a6b5bed13a1b620cf01f687b9 100644 (file)
@@ -232,7 +232,7 @@ void Train::stop_at(Block *block)
 
 bool Train::free_block(Block &block)
 {
-       if(get_reserved_distance_until(&block, false)<controller->get_braking_distance()*1.3)
+       if(get_reserved_distance_until(&block)<controller->get_braking_distance()*1.3)
                return false;
 
        return allocator.release_from(block);
@@ -252,53 +252,21 @@ void Train::free_noncritical_blocks()
        float margin = 10*layout.get_catalogue().get_scale();
        float min_dist = controller->get_braking_distance()*1.3+margin;
 
-       Vehicle &veh = *(reverse ? vehicles.back() : vehicles.front());
-
-       TrackIter track = veh.get_track_iter();
-       BlockIter block = allocator.first();
-       const BlockIter &last_cur = allocator.last_current();
-       const BlockIter &last = allocator.last();
-       bool in_rsv = false;
-       while(!block->has_track(*track))
-       {
-               if(&*block==&*last_cur)
-                       in_rsv = true;
-               if(&*block==&*last)
-                       break;
-               block = block.next();
-       }
-
-       float dist = veh.get_offset();
-       if(reverse)
-               track.reverse();
-       else
-               dist = track->get_type().get_path_length(track->get_active_path())-dist;
-       dist -= veh.get_type().get_length()/2;
-
-       bool nsens = 0;
-       while(1)
+       BlockIter i = allocator.last_current().next();
+       float dist = 0;
+       bool sensor_seen = false;
+       for(; i->get_train()==this; i=i.next())
        {
-               track = track.next();
-
-               if(!block->has_track(*track))
+               if(dist>min_dist && sensor_seen)
                {
-                       if(&*block==&*last_cur)
-                               in_rsv = true;
-                       if(&*block==&*last)
-                               return;
-                       block = block.next();
-
-                       if(dist>min_dist && nsens>0)
-                       {
-                               allocator.release_from(*block);
-                               return;
-                       }
-
-                       if(in_rsv && block->get_sensor_id())
-                               ++nsens;
+                       allocator.release_from(*i);
+                       return;
                }
 
-               dist += track->get_type().get_path_length(track->get_active_path());
+               dist += i->get_path_length(i.entry());
+
+               if(i->get_sensor_id())
+                       sensor_seen = true;
        }
 }
 
@@ -312,7 +280,7 @@ float Train::get_reserved_distance() const
        if(next && next->get_type().is_turnout())
                margin = 15*layout.get_catalogue().get_scale();
 
-       return max(get_reserved_distance_until(0, false)-margin, 0.0f);
+       return max(get_reserved_distance_until(0)-margin, 0.0f);
 }
 
 void Train::reserve_more()
@@ -386,14 +354,6 @@ void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt)
                        }
                }
        }
-
-       if(!allocator.empty() && !allocator.first()->get_sensor_id())
-       {
-               float dist = get_reserved_distance_until(&*allocator.first(), true);
-
-               if(dist>10*layout.get_catalogue().get_scale())
-                       allocator.release_until(*allocator.first());
-       }
 }
 
 void Train::save(list<DataFile::Statement> &st) const
@@ -521,65 +481,44 @@ void Train::halt_event(bool h)
                accurate_position = false;
 }
 
-float Train::get_reserved_distance_until(const Block *until_block, bool back) const
+float Train::get_reserved_distance_until(const Block *until_block) const
 {
        if(allocator.empty())
                return 0;
 
-       Vehicle &veh = *(reverse!=back ? vehicles.back() : vehicles.front());
-       const VehicleType &vtype = veh.get_type();
+       Vehicle &veh = *(reverse ? vehicles.back() : vehicles.front());
 
        TrackIter track = veh.get_track_iter();
        if(!track)  // XXX Probably unnecessary
                return 0;
 
-       const BlockIter &first = allocator.first();
-       const BlockIter &last = allocator.last();
-       BlockIter block = first;
-       while(!block->has_track(*track))
-       {
-               if(&*block==&*last)
-                       return 0;
-               block = block.next();
-       }
+       BlockIter block = track.block_iter();
        if(&*block==until_block)
                return 0;
 
-       if(back)
-               block = block.reverse();
-
+       // Account for the vehicle's offset on its current track
        float result = veh.get_offset();
-       if(reverse!=back)
+       if(reverse)
                track = track.reverse();
        else
                result = track->get_type().get_path_length(track->get_active_path())-result;
-       result -= vtype.get_length()/2;
+       result -= veh.get_type().get_length()/2;
 
-       while(1)
-       {
-               track = track.next();
-               if(!track)
-                       break;
+       // Count remaining distance in the vehicle's current block
+       for(track=track.next(); &track->get_block()==&*block; track=track.next())
+               result += track->get_type().get_path_length(track->get_active_path());
 
-               if(!block->has_track(*track))
-               {
-                       if(back)
-                       {
-                               if(&*block==&*first)
-                                       break;
-                       }
-                       else
-                       {
-                               if(&*block==&*last)
-                                       break;
-                       }
-                       block = block.next();
+       const BlockIter &last = allocator.last();
+       if(&*block==&*last)
+               return result;
 
-                       if(&*block==until_block)
-                               break;
-               }
+       // Count any remaining blocks
+       for(block=block.next(); (&*block!=until_block && block->get_train()==this); block=block.next())
+       {
+               result += block->get_path_length(block.entry());
 
-               result += track->get_type().get_path_length(track->get_active_path());
+               if(&*block==&*last)
+                       break;
        }
 
        return result;