From 80dcfa55c913037066e43fa115ae56fa51b974f2 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 26 Dec 2009 19:26:00 +0000 Subject: [PATCH] Improve the handling of sensor events in Train --- source/libmarklin/train.cpp | 43 +++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index e64ef00..e992f41 100644 --- a/source/libmarklin/train.cpp +++ b/source/libmarklin/train.cpp @@ -228,6 +228,7 @@ void Train::sensor_event(bool state, Sensor *sensor) if(state) { + // Find the first sensor block from our reserved blocks that isn't this sensor list::iterator i; for(i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i) if(i->block->get_sensor_id() && i->block->get_sensor_id()!=addr) @@ -235,6 +236,7 @@ void Train::sensor_event(bool state, Sensor *sensor) if(i!=rsv_blocks.begin()) { + // Compute speed and update related state float travel_time_secs = (Time::now()-last_entry_time)/Time::sec; travel_speed = static_cast(round(travel_dist/travel_time_secs*87*3.6/5))*5; @@ -250,35 +252,44 @@ void Train::sensor_event(bool state, Sensor *sensor) { j->block->traverse(j->entry, &block_len); travel_dist += block_len; + + if(j->block->get_sensor_id()==addr) + set_position(j->block->get_endpoints()[j->entry]); } last_entry_time = Time::now(); pure_speed = true; + // Move blocks up to the next sensor to our current blocks cur_blocks.splice(cur_blocks.end(), rsv_blocks, rsv_blocks.begin(), i); - } - - for(i=cur_blocks.begin(); i!=cur_blocks.end(); ++i) - if(i->block->get_sensor_id()==addr) - set_position(i->block->get_endpoints()[i->entry]); - if(target_speed && reserve_more()<2) - update_speed(); + // Try to get more blocks if we're moving + if(target_speed && reserve_more()<2) + update_speed(); + } } else { + // Find the first sensor in our current blocks that's still active + list::iterator end = cur_blocks.begin(); for(list::iterator i=cur_blocks.begin(); i!=cur_blocks.end(); ++i) - if(unsigned b_addr = i->block->get_sensor_id()) + if(i->block->get_sensor_id()) { - if(b_addr==addr) - { - ++i; - for(list::iterator j=cur_blocks.begin(); j!=i; ++j) - j->block->reserve(0); - cur_blocks.erase(cur_blocks.begin(), i); - } - break; + if(trfc_mgr.get_control().get_sensor(i->block->get_sensor_id()).get_state()) + break; + else + end = i; } + + if(end!=cur_blocks.begin()) + { + // Free blocks up to the last inactive sensor + ++end; + for(list::iterator i=cur_blocks.begin(); i!=end; ++i) + i->block->reserve(0); + cur_blocks.erase(cur_blocks.begin(), end); + } + // XXX Should watch for trfc_mgr.signal_block_reserved rather than sensors if(target_speed && pending_block && addr==pending_block->get_sensor_id()) reserve_more(); } -- 2.43.0