From 0ac334781fcb5029e4ea9236a8e93f43169eb7f2 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 14 Apr 2014 09:00:30 +0300 Subject: [PATCH] Simplify sequence handling Instead of checking all sequence points when another train reserves a block, only check the first one. The subsequent ones can be checked when they become relevant. --- source/libr2c2/trainrouter.cpp | 56 ++++++++++++++++++---------------- source/libr2c2/trainrouter.h | 4 ++- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/source/libr2c2/trainrouter.cpp b/source/libr2c2/trainrouter.cpp index 2fac984..4b7e1bc 100644 --- a/source/libr2c2/trainrouter.cpp +++ b/source/libr2c2/trainrouter.cpp @@ -18,7 +18,9 @@ TrainRouter::TrainRouter(Train &t): arriving(0), destination(0), destination_changed(false), - metrics_stale(false) + metrics_stale(false), + current_sequence(0), + sequence_check_pending(false) { train.get_layout().signal_block_reserved.connect(sigc::mem_fun(this, &TrainRouter::block_reserved)); train.signal_advanced.connect(sigc::mem_fun(this, &TrainRouter::train_advanced)); @@ -65,8 +67,8 @@ bool TrainRouter::set_route(const Route *r) destination = 0; waypoints.clear(); sequence_points.clear(); - pending_sequence_checks.clear(); current_sequence = 0; + sequence_check_pending = false; route_changed(); @@ -195,8 +197,8 @@ void TrainRouter::tick(const Time::TimeDelta &dt) routes.push_back(create_lead_route(0, planned_routes.front())); routes.insert(routes.end(), planned_routes.begin(), planned_routes.end()); sequence_points = planner->get_sequence_for(train); - pending_sequence_checks.clear(); current_sequence = 0; + sequence_check_pending = false; route_changed(); } @@ -204,14 +206,12 @@ void TrainRouter::tick(const Time::TimeDelta &dt) } } - for(list::iterator i=pending_sequence_checks.begin(); i!=pending_sequence_checks.end(); ++i) - if((*i)->preceding_train->get_ai_of_type()->get_current_sequence()>=(*i)->sequence_in) - { - (*i)->preceding_train = 0; - if(*i==&sequence_points.front()) - train.stop_at(0); - } - pending_sequence_checks.clear(); + if(sequence_check_pending) + { + if(sequence_points.front().is_cleared()) + train.stop_at(0); + sequence_check_pending = false; + } if(arriving==1 && !train.get_speed()) { @@ -243,21 +243,14 @@ void TrainRouter::block_reserved(Block &block, Train *t) if(!t) return; - TrainRouter *other_router = 0; - for(list::iterator i=sequence_points.begin(); i!=sequence_points.end(); ++i) - if(i->block==&block && i->preceding_train==t) - { - if(!other_router) - other_router = t->get_ai_of_type(); - if(other_router->get_current_sequence()>=i->sequence_in) - { - i->preceding_train = 0; - if(i==sequence_points.begin()) - train.stop_at(0); - } - else - pending_sequence_checks.push_back(&*i); - } + SequencePoint &sp = sequence_points.front(); + if(sp.preceding_train==t && sp.block==&block) + { + if(sp.is_cleared()) + train.stop_at(0); + else + sequence_check_pending = true; + } return; } @@ -298,7 +291,7 @@ void TrainRouter::block_reserved(Block &block, Train *t) if(!sequence_points.empty()) { SequencePoint &sp = sequence_points.front(); - if(sp.preceding_train && sp.block==b_iter_next.block()) + if(sp.block==b_iter_next.block() && !sp.is_cleared()) train.stop_at(&block); } } @@ -462,6 +455,15 @@ TrainRouter::SequencePoint::SequencePoint(Block &b, unsigned o): sequence_out(o) { } +bool TrainRouter::SequencePoint::is_cleared() const +{ + if(!preceding_train) + return true; + + TrainRouter *router = preceding_train->get_ai_of_type(); + return router->get_current_sequence()>=sequence_in; +} + TrainRouter::Loader::Loader(TrainRouter &r): DataFile::ObjectLoader(r) diff --git a/source/libr2c2/trainrouter.h b/source/libr2c2/trainrouter.h index cbaa520..47a409c 100644 --- a/source/libr2c2/trainrouter.h +++ b/source/libr2c2/trainrouter.h @@ -37,6 +37,8 @@ public: unsigned sequence_out; SequencePoint(Block &, unsigned); + + bool is_cleared() const; }; private: @@ -51,8 +53,8 @@ private: std::vector metrics; bool metrics_stale; std::list sequence_points; - std::list pending_sequence_checks; unsigned current_sequence; + bool sequence_check_pending; Msp::Time::TimeDelta delay; Msp::RefPtr planner; -- 2.45.2