]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/train.cpp
Rearrange block reservations to present consistent state in signal_reserved
[r2c2.git] / source / libr2c2 / train.cpp
index f43969d1949b0729eed8ba9132fb1bb37125d23f..599f2dcdf28b27d92a1401b9fe025d701c4949d1 100644 (file)
@@ -430,10 +430,13 @@ void Train::place(Block &block, unsigned entry)
        set_active(false);
        accurate_position = false;
 
+       blocks.push_back(BlockIter(&block, entry));
        if(!block.reserve(this))
+       {
+               blocks.pop_back();
                return;
+       }
 
-       blocks.push_back(BlockIter(&block, entry));
        if(reverse)
        {
                TrackIter track = BlockIter(&block, entry).reverse().track_iter();
@@ -542,7 +545,7 @@ void Train::free_noncritical_blocks()
        }
 }
 
-int Train::get_entry_to_block(Block &block) const
+int Train::get_entry_to_block(const Block &block) const
 {
        for(BlockList::const_iterator i=blocks.begin(); i!=blocks.end(); ++i)
                if(i->block()==&block)
@@ -648,8 +651,9 @@ void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt)
 
                if(dist>10*layout.get_catalogue().get_scale())
                {
-                       blocks.front()->reserve(0);
+                       Block &block = *blocks.front();
                        blocks.pop_front();
+                       block.reserve(0);
                }
        }
 }
@@ -967,9 +971,11 @@ void Train::reserve_more()
                        }
                }
 
+               blocks.push_back(block);
                bool reserved = block->reserve(this);
                if(!reserved)
                {
+                       blocks.pop_back();
                        /* We've found another train.  If it wants to exit the block from the
                        same endpoint we're trying to enter from or the other way around,
                        treat it as coming towards us.  Otherwise treat it as going in the
@@ -1000,7 +1006,11 @@ void Train::reserve_more()
                                /* Ask a lesser priority train going to the same direction to free
                                the block for us */
                                if(other_train->free_block(*block))
-                                       reserved = block->reserve(this);
+                               {
+                                       blocks.push_back(block);
+                                       if(!(reserved = block->reserve(this)))
+                                               blocks.pop_back();
+                               }
                        }
                        else if(other_train!=yielding_to && (other_prio<priority || (other_prio==priority && entry_conflict)))
                        {
@@ -1036,8 +1046,6 @@ void Train::reserve_more()
                if(!contested_blocks.empty() && contested_blocks.front()==block)
                        contested_blocks.pop_front();
 
-               blocks.push_back(block);
-
                if(cur_blocks_end==blocks.end())
                        --cur_blocks_end;
                if(clear_blocks_end==blocks.end())
@@ -1105,6 +1113,8 @@ void Train::check_turnout_paths(bool set)
 
                if(i==clear_blocks_end)
                        ++clear_blocks_end;
+               if(i==cur_blocks_end && !(*i)->get_sensor_id())
+                       ++cur_blocks_end;
        }
 }
 
@@ -1335,8 +1345,8 @@ void Train::Loader::block(unsigned id)
        if(entry<0)
                entry = 0;
 
-       blk->reserve(&obj);
        obj.blocks.push_back(BlockIter(blk, entry));
+       blk->reserve(&obj);
 
        if(blk->get_sensor_id())
                obj.layout.get_driver().set_sensor(blk->get_sensor_id(), true);