From 3d38bcbe8add00b558012fa0cd4e0be26464dbeb Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 3 Oct 2010 18:31:48 +0000 Subject: [PATCH] Use RAII for setting the anti-recursion flags Fix some crashes with empty cur_blocks Refuse to give up the last of cur_blocks --- source/libmarklin/train.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index 96566a6..8166c09 100644 --- a/source/libmarklin/train.cpp +++ b/source/libmarklin/train.cpp @@ -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::iterator i; -- 2.45.2