]> git.tdb.fi Git - r2c2.git/commitdiff
Simplify sequence handling
authorMikko Rasa <tdb@tdb.fi>
Mon, 14 Apr 2014 06:00:30 +0000 (09:00 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 14 Apr 2014 15:42:27 +0000 (18:42 +0300)
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
source/libr2c2/trainrouter.h

index 2fac984f03eba6ba23ee1c1ffad0c735d755aaf1..4b7e1bc9ca54395a3a9221c71230e93eb9832dec 100644 (file)
@@ -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<SequencePoint *>::iterator i=pending_sequence_checks.begin(); i!=pending_sequence_checks.end(); ++i)
-               if((*i)->preceding_train->get_ai_of_type<TrainRouter>()->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<SequencePoint>::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<TrainRouter>();
-                               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<TrainRouter>();
+       return router->get_current_sequence()>=sequence_in;
+}
+
 
 TrainRouter::Loader::Loader(TrainRouter &r):
        DataFile::ObjectLoader<TrainRouter>(r)
index cbaa520cd20d945c5e1249ba5679fddb07c9b9b9..47a409cd7cb2bdb36064f753e5c2f9cadd4bca77 100644 (file)
@@ -37,6 +37,8 @@ public:
                unsigned sequence_out;
 
                SequencePoint(Block &, unsigned);
+
+               bool is_cleared() const;
        };
 
 private:
@@ -51,8 +53,8 @@ private:
        std::vector<TrainRouteMetric *> metrics;
        bool metrics_stale;
        std::list<SequencePoint> sequence_points;
-       std::list<SequencePoint *> pending_sequence_checks;
        unsigned current_sequence;
+       bool sequence_check_pending;
        Msp::Time::TimeDelta delay;
        Msp::RefPtr<TrainRoutePlanner> planner;