From d051af7264ee62d03473f1929414e262e918c30a Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 9 Aug 2013 13:30:30 +0300 Subject: [PATCH] Reserve enough blocks for the entire train when placing --- source/libr2c2/blockallocator.cpp | 44 +++++++++++++++++++++++++++++-- source/libr2c2/blockallocator.h | 2 +- source/libr2c2/train.cpp | 18 +++++++++---- source/libr2c2/train.h | 2 +- 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/source/libr2c2/blockallocator.cpp b/source/libr2c2/blockallocator.cpp index 547415a..2e81677 100644 --- a/source/libr2c2/blockallocator.cpp +++ b/source/libr2c2/blockallocator.cpp @@ -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; iget_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_type().get_path_length(t->get_active_path()); + 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) diff --git a/source/libr2c2/blockallocator.h b/source/libr2c2/blockallocator.h index f5af90e..fe05603 100644 --- a/source/libr2c2/blockallocator.h +++ b/source/libr2c2/blockallocator.h @@ -48,7 +48,7 @@ public: void set_active(bool); bool is_active() const { return active; } - void start_from(const BlockIter &); + bool start_from(const BlockIter &); void rewind_to(const Block &); void clear(); bool empty() const { return blocks.empty(); } diff --git a/source/libr2c2/train.cpp b/source/libr2c2/train.cpp index 95b78b5..07461b8 100644 --- a/source/libr2c2/train.cpp +++ b/source/libr2c2/train.cpp @@ -185,21 +185,29 @@ void Train::ai_message(const TrainAI::Message &msg) (*i)->message(msg); } -void Train::place(const BlockIter &block) +bool Train::place(const BlockIter &block) { if(!block) throw invalid_argument("Train::place"); if(controller->get_speed()) throw logic_error("moving"); - allocator.start_from(block); accurate_position = false; last_entry_block = BlockIter(); - if(reverse) - vehicles.front()->place(block.reverse().track_iter(), VehiclePlacement::FRONT_BUFFER); + if(allocator.start_from(block)) + { + if(reverse) + vehicles.front()->place(block.reverse().track_iter(), VehiclePlacement::FRONT_BUFFER); + else + vehicles.back()->place(block.track_iter(), VehiclePlacement::BACK_BUFFER); + return true; + } else - vehicles.back()->place(block.track_iter(), VehiclePlacement::BACK_BUFFER); + { + unplace(); + return false; + } } void Train::unplace() diff --git a/source/libr2c2/train.h b/source/libr2c2/train.h index 3aaf6b1..340537a 100644 --- a/source/libr2c2/train.h +++ b/source/libr2c2/train.h @@ -112,7 +112,7 @@ public: return 0; } - void place(const BlockIter &); + bool place(const BlockIter &); void unplace(); bool is_placed() const { return !allocator.empty(); } void stop_at(Block *); -- 2.45.2