]> git.tdb.fi Git - r2c2.git/commitdiff
Use RAII for setting the anti-recursion flags
authorMikko Rasa <tdb@tdb.fi>
Sun, 3 Oct 2010 18:31:48 +0000 (18:31 +0000)
committerMikko Rasa <tdb@tdb.fi>
Sun, 3 Oct 2010 18:31:48 +0000 (18:31 +0000)
Fix some crashes with empty cur_blocks
Refuse to give up the last of cur_blocks

source/libmarklin/train.cpp

index 96566a63a5f48fe89049b5c1f7c3a2a601d46e66..8166c09a86944d1bb4251dec61a38819d08b8920 100644 (file)
@@ -24,6 +24,19 @@ Distributed under the GPL
 using namespace std;
 using namespace Msp;
 
+namespace {
+
+struct SetFlag
+{
+       bool &flag;
+
+       SetFlag(bool &f): flag(f) { flag = true; }
+       ~SetFlag() { flag = false; }
+};
+
+}
+
+
 namespace Marklin {
 
 Train::Train(Layout &l, const VehicleType &t, unsigned a):
@@ -202,7 +215,7 @@ void Train::set_route(const Route *r)
        next_route = 0;
        end_of_route = false;
 
-       if(route)
+       if(route && !cur_blocks.empty())
        {
                BlockRef &last = (rsv_blocks.empty() ? cur_blocks.back() : rsv_blocks.back());
                BlockRef next = last.next();
@@ -310,6 +323,9 @@ int Train::get_entry_to_block(Block &block) const
 
 float Train::get_reserved_distance() const
 {
+       if(cur_blocks.empty())
+               return 0;
+
        Vehicle &veh = *(reverse ? vehicles.back() : vehicles.front());
        const VehicleType &vtype = veh.get_type();
 
@@ -410,9 +426,8 @@ void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt)
                float d = get_real_speed(current_speed)*(dt/Time::sec);
                if(ok)
                {
-                       advancing = true;
+                       SetFlag setf(advancing);
                        vehicle.advance(reverse ? -d : d);
-                       advancing = false;
                }
                else if(accurate_position)
                {
@@ -657,7 +672,7 @@ void Train::sensor_event(unsigned addr, bool state)
                                }
                        }
                
-               if(end!=cur_blocks.begin())
+               if(end!=cur_blocks.begin() && end!=cur_blocks.end())
                        // Free blocks up to the last inactive sensor
                        release_blocks(cur_blocks, cur_blocks.begin(), end);
        }
@@ -728,7 +743,7 @@ unsigned Train::reserve_more()
                }
        }
 
-       reserving = true;
+       SetFlag setf(reserving);
 
        bool got_more = false;
        BlockRef *good = last;
@@ -846,7 +861,6 @@ unsigned Train::reserve_more()
                        last = &rsv_blocks.back();
        }
 
-       reserving = false;
 
        // Make any sensorless blocks at the beginning immediately current
        list<BlockRef>::iterator i;