From: Mikko Rasa Date: Mon, 8 Jul 2013 15:02:18 +0000 (+0300) Subject: Some more refactoring of BlockAllocator X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=fafc91bc79152890e5c2f43f29811cb10a3a7ecb;p=r2c2.git Some more refactoring of BlockAllocator --- diff --git a/source/libr2c2/blockallocator.cpp b/source/libr2c2/blockallocator.cpp index 215d746..2a24737 100644 --- a/source/libr2c2/blockallocator.cpp +++ b/source/libr2c2/blockallocator.cpp @@ -247,7 +247,7 @@ void BlockAllocator::reserve_more() { update_next_sensor(0); // Immediately advance to just before the next sensor - advance_to(next_sensor ? next_sensor->get_block() : 0); + advance_front(next_sensor); } } @@ -273,7 +273,7 @@ bool BlockAllocator::reserve_block(const BlockIter &block) } } -void BlockAllocator::advance_to(const Block *block) +void BlockAllocator::advance_front(const Block *block) { BlockList::iterator end; if(block) @@ -289,6 +289,33 @@ void BlockAllocator::advance_to(const Block *block) train.signal_advanced.emit(**i); } +void BlockAllocator::advance_front(const Sensor *sensor) +{ + advance_front(sensor ? sensor->get_block() : 0); +} + +void BlockAllocator::advance_back() +{ + const Vehicle &veh = train.get_vehicle(train.get_controller().get_reverse() ? 0 : train.get_n_vehicles()-1); + const Block &veh_block = veh.get_track()->get_block(); + + /* Sensors aren't guaranteed to be detriggered in order. Go through the + block list and locate the first sensor that's still active. */ + Sensor *last_inactive = 0; + for(BlockList::iterator i=blocks.begin(); (i!=cur_blocks_end && i->block()!=&veh_block); ++i) + if(Sensor *sensor = (*i)->get_sensor()) + { + if(sensor->get_state()) + { + if(last_inactive) + release_blocks_begin(i); + return; + } + else + last_inactive = sensor; + } +} + void BlockAllocator::release_blocks_begin(const BlockList::iterator &end) { for(BlockList::iterator i=blocks.begin(); i!=end; ) @@ -375,7 +402,7 @@ void BlockAllocator::sensor_state_changed(Sensor &sensor, Sensor::State state) if(&sensor==next_sensor) { update_next_sensor(next_sensor); - advance_to(next_sensor ? next_sensor->get_block() : 0); + advance_front(next_sensor); if(active) reserve_more(); @@ -384,32 +411,7 @@ void BlockAllocator::sensor_state_changed(Sensor &sensor, Sensor::State state) train.get_layout().emergency("Sensor for "+train.get_name()+" triggered out of order"); } else if(state==Sensor::INACTIVE) - { - const Vehicle &veh = train.get_vehicle(train.get_controller().get_reverse() ? 0 : train.get_n_vehicles()-1); - const Block &veh_block = veh.get_track()->get_block(); - - /* Sensors aren't guaranteed to be detriggered in order. Go through the - block list and locate the first sensor that's still active. */ - BlockList::iterator end = blocks.end(); - for(BlockList::iterator i=blocks.begin(); i!=cur_blocks_end; ++i) - { - // Avoid freeing blocks that still hold the train's vehicles - if(&**i==&veh_block) - break; - - if(Sensor *s = (*i)->get_sensor()) - { - if(s->get_state()>=Sensor::MAYBE_INACTIVE) - break; - else - end = i; - } - } - - if(end!=blocks.end()) - // Free blocks up to the last inactive sensor - release_blocks_begin(++end); - } + advance_back(); } void BlockAllocator::update_next_sensor(Sensor *after) diff --git a/source/libr2c2/blockallocator.h b/source/libr2c2/blockallocator.h index 95cb910..ba939f7 100644 --- a/source/libr2c2/blockallocator.h +++ b/source/libr2c2/blockallocator.h @@ -65,7 +65,9 @@ public: private: void reserve_more(); bool reserve_block(const BlockIter &); - void advance_to(const Block *); + void advance_front(const Block *); + void advance_front(const Sensor *); + void advance_back(); void release_blocks_begin(const BlockList::iterator &); void release_blocks_end(const BlockList::iterator &); void release_block(const BlockList::iterator &);