]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/blockallocator.cpp
Add a utility function to get path length from Track
[r2c2.git] / source / libr2c2 / blockallocator.cpp
index 3b70f5a0ef6c2647c2e6ee44758e6af591802a67..674722bb9d21b6951bd0f8b0405fad8e4ecd4db3 100644 (file)
@@ -60,13 +60,53 @@ void BlockAllocator::set_active(bool a)
        }
 }
 
-void BlockAllocator::start_from(const BlockIter &block)
+bool BlockAllocator::start_from(const BlockIter &block)
 {
        if(!block)
                throw invalid_argument("BlockAllocator::start_from");
 
+       float remaining_length = 0;
+       unsigned n_vehs = train.get_n_vehicles();
+       for(unsigned i=0; i<n_vehs; ++i)
+               remaining_length += train.get_vehicle(i).get_type().get_length();
+
        clear();
-       reserve_block(block);
+
+       BlockList blocks_to_reserve;
+       for(BlockIter b=block; b; b=b.next())
+       {
+               if(b->get_train())
+                       break;
+               blocks_to_reserve.push_back(b);
+               for(TrackIter t=b.track_iter(); (t && &t->get_block()==&*b); t=t.next())
+                       remaining_length -= t->get_path_length();
+               if(remaining_length<=0)
+                       break;
+       }
+
+       if(remaining_length>0)
+               return false;
+
+       for(BlockList::iterator i=blocks_to_reserve.begin(); i!=blocks_to_reserve.end(); ++i)
+       {
+               blocks.push_back(*i);
+               try
+               {
+                       (*i)->reserve(&train);
+               }
+               catch(...)
+               {
+                       blocks.pop_back();
+                       while(i!=blocks_to_reserve.begin())
+                       {
+                               blocks.pop_back();
+                               (*--i)->reserve(0);
+                       }
+                       throw;
+               }
+       }
+
+       return true;
 }
 
 void BlockAllocator::rewind_to(const Block &block)
@@ -316,8 +356,9 @@ void BlockAllocator::advance_front(const Sensor *sensor)
 
 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();
+       bool rev = train.get_controller().get_reverse();
+       const Vehicle &veh = train.get_vehicle(rev ? 0 : train.get_n_vehicles()-1);
+       const Block &veh_block = veh.get_placement().get_position(rev ? VehiclePlacement::FRONT_AXLE : VehiclePlacement::BACK_AXLE)->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. */
@@ -422,7 +463,7 @@ void BlockAllocator::reverse()
 
 void BlockAllocator::turnout_path_changing(Track &track)
 {
-       BlockList::iterator i = find_if(blocks.begin(), blocks.end(), BlockMatch(track.get_block()));
+       BlockList::iterator i = find_if(cur_blocks_end, blocks.end(), BlockMatch(track.get_block()));
        if(i!=blocks.end())
        {
                ++i;