]> git.tdb.fi Git - r2c2.git/commitdiff
Apply all planned routes at once
authorMikko Rasa <tdb@tdb.fi>
Wed, 11 Feb 2015 15:35:56 +0000 (17:35 +0200)
committerMikko Rasa <tdb@tdb.fi>
Wed, 11 Feb 2015 15:35:56 +0000 (17:35 +0200)
Letting each router to do it separately in the tick function causes
certain problems with synchronization.  In particular, sequence points
are difficult to synchronize unless the route update is atomic.

source/libr2c2/trainrouter.cpp
source/libr2c2/trainrouter.h

index 2d6ab54550284f636a16d52870fee744f196b405..27fca7a56632c7bb1017844393f103192f1c634a 100644 (file)
@@ -63,6 +63,24 @@ const Route *TrainRouter::get_route() const
        return routes.front();
 }
 
+void TrainRouter::use_planned_route()
+{
+       if(!planner || planner->get_result()!=TrainRoutePlanner::COMPLETE)
+               return;
+
+       const list<Route *> &planned_routes = planner->get_routes_for(train);
+
+       routes.clear();
+       routes.insert(routes.end(), planned_routes.begin(), planned_routes.end());
+       create_lead_route();
+
+       sequence_points = planner->get_sequence_for(train);
+       current_sequence = 0;
+       sequence_check_pending = false;
+
+       route_changed();
+}
+
 void TrainRouter::route_changed()
 {
        BlockIter fncb = train.get_first_noncritical_block();
@@ -218,24 +236,7 @@ void TrainRouter::tick(const Time::TimeDelta &dt)
                start_planning(train.get_layout());
 
        if(planner && planner->check()!=TrainRoutePlanner::PENDING)
-       {
-               waypoints_changed = false;
-               if(planner->get_result()==TrainRoutePlanner::COMPLETE)
-               {
-                       const list<Route *> &planned_routes = planner->get_routes_for(train);
-
-                       routes.clear();
-                       routes.insert(routes.end(), planned_routes.begin(), planned_routes.end());
-                       create_lead_route();
-
-                       sequence_points = planner->get_sequence_for(train);
-                       current_sequence = 0;
-                       sequence_check_pending = false;
-
-                       route_changed();
-               }
-               planner = 0;
-       }
+               apply_plan(train.get_layout(), *planner);
 
        if(sequence_check_pending)
        {
@@ -488,14 +489,19 @@ bool TrainRouter::advance_to_track(RouteList::iterator &route, const TrackIter &
        return true;
 }
 
-void TrainRouter::start_planning(Layout &layout)
+void TrainRouter::get_routers(Layout &layout, vector<TrainRouter *> &routers)
 {
-       vector<TrainRouter *> routers;
        const map<unsigned, Train *> &trains = layout.get_trains();
        routers.reserve(trains.size());
        for(map<unsigned, Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
                if(TrainRouter *router = i->second->get_ai_of_type<TrainRouter>())
                        routers.push_back(router);
+}
+
+void TrainRouter::start_planning(Layout &layout)
+{
+       vector<TrainRouter *> routers;
+       get_routers(layout, routers);
 
        for(vector<TrainRouter *>::const_iterator i=routers.begin(); i!=routers.end(); ++i)
                if((*i)->metrics_stale)
@@ -503,11 +509,27 @@ void TrainRouter::start_planning(Layout &layout)
 
        RefPtr<TrainRoutePlanner> planner = new TrainRoutePlanner(layout);
        for(vector<TrainRouter *>::const_iterator i=routers.begin(); i!=routers.end(); ++i)
+       {
+               (*i)->waypoints_changed = false;
                (*i)->planner = planner;
+       }
 
        planner->plan_async();
 }
 
+void TrainRouter::apply_plan(Layout &layout, TrainRoutePlanner &planner)
+{
+       vector<TrainRouter *> routers;
+       get_routers(layout, routers);
+
+       for(vector<TrainRouter *>::const_iterator i=routers.begin(); i!=routers.end(); ++i)
+               if((*i)->planner.get()==&planner)
+               {
+                       (*i)->use_planned_route();
+                       (*i)->planner = 0;
+               }
+}
+
 
 TrainRouter::SequencePoint::SequencePoint(Block &b, unsigned o):
        block(&b),
index 80908d51b863ab63294f35df5dd994d197480ab2..457120944627cb29b059e4622b787f2389927578 100644 (file)
@@ -79,6 +79,7 @@ public:
        const Route *get_route() const;
        unsigned get_current_sequence() const { return current_sequence; }
 private:
+       void use_planned_route();
        void route_changed();
 
 public:
@@ -108,7 +109,9 @@ private:
        bool is_valid_for_track(const Route &, const TrackIter &) const;
        bool advance_to_track(RouteList::iterator &, const TrackIter &);
 
+       static void get_routers(Layout &, std::vector<TrainRouter *> &);
        static void start_planning(Layout &);
+       static void apply_plan(Layout &, TrainRoutePlanner &);
 };
 
 } // namespace R2C2