]> git.tdb.fi Git - r2c2.git/commitdiff
Make train advancement logic more robust
authorMikko Rasa <tdb@tdb.fi>
Wed, 26 Jun 2013 21:23:27 +0000 (00:23 +0300)
committerMikko Rasa <tdb@tdb.fi>
Wed, 26 Jun 2013 21:23:27 +0000 (00:23 +0300)
source/libr2c2/blockallocator.cpp
source/libr2c2/blockallocator.h

index 003ffb0dcf44a9ab5c141370667ce7a9c16b5f0a..ff5776d3281f1b166af785b708b2e4e0a267424d 100644 (file)
@@ -30,7 +30,8 @@ BlockAllocator::BlockAllocator(Train &t):
        cur_blocks_end(blocks.end()),
        pending_block(0),
        stop_at_block(0),
-       reserving(false)
+       reserving(false),
+       advancing(false)
 {
        Layout &layout = train.get_layout();
        layout.signal_block_reserved.connect(sigc::mem_fun(this, &BlockAllocator::block_reserved));
@@ -81,8 +82,8 @@ void BlockAllocator::rewind_to(const Block &block)
 
 void BlockAllocator::clear()
 {
-       active = false;
        release_blocks_begin(blocks.end());
+       active = false;
        pending_block = 0;
        stop_at_block = 0;
 }
@@ -294,6 +295,8 @@ void BlockAllocator::release_blocks_end(const BlockList::iterator &begin)
 
 void BlockAllocator::release_block(const BlockList::iterator &i)
 {
+       if(advancing)
+               throw logic_error("cannot release while advancing");
        if(i==cur_blocks_end)
                ++cur_blocks_end;
        if(&**i==pending_block)
@@ -372,10 +375,14 @@ void BlockAllocator::sensor_state_changed(Sensor &sensor, Sensor::State state)
 
                if(result==1)
                {
-                       // Move blocks up to the next sensor to our current blocks
-                       for(BlockList::iterator j=cur_blocks_end; j!=end; ++j)
-                               train.signal_advanced.emit(**j);
+                       /* Advance the train to the new blocks.  Update cur_blocks_end first
+                       to keep things in sync. */
+                       SetFlag setf(advancing);
+                       BlockList::iterator i = cur_blocks_end;
                        cur_blocks_end = end;
+                       for(; i!=end; ++i)
+                               train.signal_advanced.emit(**i);
+                       advancing = false;
 
                        if(active)
                                reserve_more();
index 6ad3891bc4e68fc91b84ba0cb695ffc5aecd239b..c0c265ae0bdf6bb03f0d8e1aa7c45d58b43007d2 100644 (file)
@@ -39,6 +39,7 @@ private:
        Block *pending_block;
        const Block *stop_at_block;
        bool reserving;
+       bool advancing;
 
 public:
        BlockAllocator(Train &);