From 67cd1b26d2833903e51b91e167a3d1f7ae884a31 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 11 Feb 2015 18:28:49 +0200 Subject: [PATCH] Better sequence syncing on route change Immediately go into the wait state if an uncleared sequence point is encountered during sync. --- source/libr2c2/trainrouter.cpp | 44 +++++++++++++++++++++------------- source/libr2c2/trainrouter.h | 1 + 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/source/libr2c2/trainrouter.cpp b/source/libr2c2/trainrouter.cpp index 27fca7a..e38e29c 100644 --- a/source/libr2c2/trainrouter.cpp +++ b/source/libr2c2/trainrouter.cpp @@ -85,8 +85,8 @@ void TrainRouter::route_changed() { BlockIter fncb = train.get_first_noncritical_block(); + arrival = ON_THE_WAY; reserving_route = routes.begin(); - bool already_at_end = false; if(!routes.empty()) { /* Find the route that should be used for the next allocated block. We @@ -98,7 +98,7 @@ void TrainRouter::route_changed() { if(!advance_to_track(reserving_route, track)) { - already_at_end = true; + arrival = RESERVED_TO_END; break; } if(&track->get_block()==fncb.block()) @@ -106,30 +106,34 @@ void TrainRouter::route_changed() if(seq_begin!=sequence_points.end() && seq_begin->block==&track->get_block()) { + // Assume any sequence points within critical blocks to be cleared current_sequence = seq_begin->sequence_out; ++seq_begin; } } sequence_points.erase(sequence_points.begin(), seq_begin); - } - if(!already_at_end) - { - // We are not at the end of the route now, but might have been before. - arrival = ON_THE_WAY; - train.refresh_blocks_from(*fncb); - if(!arrival) - train.stop_at(0); + if(!sequence_points.empty()) + { + const SequencePoint &sp = sequence_points.front(); + if(sp.block==fncb.block() && !sp.is_cleared()) + { + arrival = WAITING_FOR_SEQUENCE; + sequence_check_pending = true; + } + } } - else if(!arrival) - { - /* If arrival wasn't set before (perhaps because we weren't on a route), - set it now. */ - arrival = RESERVED_TO_END; + + /* Refresh from the first non-critical block to pick up any changes in the + route. Set stop marker first in case an arrival condition was met within the + critical blocks. */ + if(arrival) train.stop_at(&*fncb.flip()); - train.refresh_blocks_from(*fncb); - } + train.refresh_blocks_from(*fncb); + // If no arrival condition was found, clear a possible previous stop marker. + if(!arrival) + train.stop_at(0); const Route *route = get_route(); signal_route_changed.emit(route); @@ -241,7 +245,10 @@ void TrainRouter::tick(const Time::TimeDelta &dt) if(sequence_check_pending) { if(sequence_points.front().is_cleared()) + { + arrival = ON_THE_WAY; train.stop_at(0); + } sequence_check_pending = false; } @@ -345,7 +352,10 @@ void TrainRouter::block_reserved(Block &block, Train *t) { SequencePoint &sp = sequence_points.front(); if(sp.block==&track->get_block() && !sp.is_cleared()) + { + arrival = WAITING_FOR_SEQUENCE; train.stop_at(&block); + } } } diff --git a/source/libr2c2/trainrouter.h b/source/libr2c2/trainrouter.h index 4571209..542d1ff 100644 --- a/source/libr2c2/trainrouter.h +++ b/source/libr2c2/trainrouter.h @@ -43,6 +43,7 @@ private: enum ArrivalState { ON_THE_WAY, + WAITING_FOR_SEQUENCE, RESERVED_TO_END, ARRIVED }; -- 2.43.0