]> git.tdb.fi Git - r2c2.git/commitdiff
Replace waits with a more robust sequencing system
authorMikko Rasa <tdb@tdb.fi>
Sat, 12 Apr 2014 19:32:03 +0000 (22:32 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 12 Apr 2014 19:32:03 +0000 (22:32 +0300)
source/libr2c2/trainrouteplanner.cpp
source/libr2c2/trainrouteplanner.h
source/libr2c2/trainrouter.cpp
source/libr2c2/trainrouter.h

index 581bd03fa86f9b3786d0989f96e687130f459ac2..69a3bbea55484de54a9d43b584563481f2a98894 100644 (file)
@@ -75,17 +75,15 @@ void TrainRoutePlanner::create_routes(const RoutingStep &goal)
                        i->track_history[j] = 0;
        }
 
+       map<Track *, SequencingInfo *> sequenced_tracks;
+       unsigned sequence = steps.size();
        for(const RoutingStep *i=&goal; i; i=i->prev)
-       {
                for(vector<TrainRoutingState>::const_iterator j=i->trains.begin(); j!=i->trains.end(); ++j)
                {
                        Track **history = j->info->track_history;
                        if(j->track.track()==history[0])
                                continue;
 
-                       if(j->state==WAITING || j->state==BLOCKED)
-                               j->info->waits.push_front(&*j);
-
                        Route *route = j->info->routes.front();
                        if(route->has_track(*j->track))
                        {
@@ -102,8 +100,28 @@ void TrainRoutePlanner::create_routes(const RoutingStep &goal)
                        for(unsigned k=2; k>0; --k)
                                history[k] = history[k-1];
                        history[0] = j->track.track();
+
+                       bool waitable = j->track.endpoint().paths!=j->track->get_type().get_paths();
+                       map<Track *, SequencingInfo *>::iterator k = sequenced_tracks.find(j->track.track());
+                       if(k!=sequenced_tracks.end())
+                       {
+                               if(!k->second->preceding)
+                               {
+                                       k->second->preceding = j->info;
+                                       k->second->sequence_in = sequence;
+                               }
+                               j->info->sequence.push_front(SequencingInfo(j->track.track(), sequence));
+                               if(waitable)
+                                       k->second = &j->info->sequence.front();
+                               --sequence;
+                       }
+                       else if(waitable)
+                       {
+                               j->info->sequence.push_front(SequencingInfo(j->track.track(), sequence));
+                               sequenced_tracks[j->track.track()] = &j->info->sequence.front();
+                               --sequence;
+                       }
                }
-       }
 
        for(vector<TrainRoutingInfo>::iterator i=routed_trains.begin(); i!=routed_trains.end(); ++i)
        {
@@ -115,18 +133,25 @@ void TrainRoutePlanner::create_routes(const RoutingStep &goal)
                                i->router->add_route(**j);
                }
 
-               const TrainRoutingState *current_wait = 0;
-               for(list<const TrainRoutingState *>::const_iterator j=i->waits.begin(); j!=i->waits.end(); ++j)
-                       if(!current_wait || (*j)->track.track()!=current_wait->track.track())
-                       {
-                               Block &block = (*j)->track.next()->get_block();
-                               i->router->add_wait(block, 0);
-                               current_wait = *j;
-                       }
+               for(list<SequencingInfo>::iterator j=i->sequence.begin(); j!=i->sequence.end(); ++j)
+               {
+                       if(j->preceding && j->preceding!=&*i)
+                               i->router->add_sequence_point(j->track->get_block(), *j->preceding->train, j->sequence_in, j->sequence_out);
+                       else
+                               i->router->add_sequence_point(j->track->get_block(), j->sequence_out);
+               }
        }
 }
 
 
+TrainRoutePlanner::SequencingInfo::SequencingInfo(Track *t, unsigned o):
+       track(t),
+       preceding(0),
+       sequence_in(0),
+       sequence_out(o)
+{ }
+
+
 TrainRoutePlanner::TrainRoutingInfo::TrainRoutingInfo(Train &t):
        train(&t),
        speed(train->get_maximum_speed()),
index 57d2de508cdc27be0dbc17c3953d24bc2d9c4c61..c6ca741555282c767bf7247e76c6fa49407aabb3 100644 (file)
@@ -18,6 +18,17 @@ class TrainRoutePlanner
 {
 private:
        struct TrainRoutingState;
+       struct TrainRoutingInfo;
+
+       struct SequencingInfo
+       {
+               Track *track;
+               TrainRoutingInfo *preceding;
+               unsigned sequence_in;
+               unsigned sequence_out;
+
+               SequencingInfo(Track *, unsigned);
+       };
 
        struct TrainRoutingInfo
        {
@@ -26,7 +37,7 @@ private:
                TrainRouter *router;
                std::list<Route *> routes;
                Track *track_history[3];
-               std::list<const TrainRoutingState *> waits;
+               std::list<SequencingInfo> sequence;
 
                TrainRoutingInfo(Train &);
        };
index 9a86263b9bec5922fa58d8201529731e79c01944..8b3433c3ec359f6d205d0d9110a789a4eb063732 100644 (file)
@@ -70,6 +70,9 @@ bool TrainRouter::set_route(const Route *r)
                destination = 0;
                waypoints.clear();
        }
+       sequence_points.clear();
+       pending_sequence_checks.clear();
+       current_sequence = 0;
 
        train.refresh_blocks_from(*fncb);
 
@@ -91,14 +94,6 @@ bool TrainRouter::add_route(const Route &r)
        return true;
 }
 
-void TrainRouter::add_wait(Block &block, Train *tr)
-{
-       Wait wait;
-       wait.block = &block;
-       wait.train = tr;
-       waits.push_back(wait);
-}
-
 const Route *TrainRouter::get_route() const
 {
        if(routes.empty())
@@ -106,6 +101,19 @@ const Route *TrainRouter::get_route() const
        return routes.front();
 }
 
+void TrainRouter::add_sequence_point(Block &b, unsigned o)
+{
+       sequence_points.push_back(SequencePoint(b, o));
+}
+
+void TrainRouter::add_sequence_point(Block &b, Train &t, unsigned i, unsigned o)
+{
+       SequencePoint sp(b, o);
+       sp.preceding_train = &t;
+       sp.sequence_in = i;
+       sequence_points.push_back(sp);
+}
+
 void TrainRouter::set_destination(const TrackChain &d)
 {
        destination = &d;
@@ -196,6 +204,15 @@ void TrainRouter::tick(const Time::TimeDelta &dt)
        if(update_pending)
                create_plans(train.get_layout());
 
+       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(arriving==1 && !train.get_speed())
        {
                signal_arrived.emit(destination);
@@ -223,12 +240,36 @@ void TrainRouter::block_reserved(Block &block, Train *t)
 {
        if(t!=&train)
        {
-               if(!waits.empty() && waits.front().block==&block)
+               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);
+                       }
+
+               return;
+       }
+
+       if(!sequence_points.empty())
+       {
+               SequencePoint &sp = sequence_points.front();
+               if(sp.block==&block)
                {
-                       train.stop_at(0);
-                       waits.pop_front();
+                       current_sequence = sp.sequence_out;
+                       sequence_points.pop_front();
                }
-               return;
        }
 
        BlockIter b_iter = t->get_block_allocator().iter_for(block);
@@ -254,8 +295,12 @@ void TrainRouter::block_reserved(Block &block, Train *t)
                        return;
                }
 
-               if(!waits.empty() && waits.front().block==b_iter_next.block())
-                       train.stop_at(&block);
+               if(!sequence_points.empty())
+               {
+                       SequencePoint &sp = sequence_points.front();
+                       if(sp.preceding_train && sp.block==b_iter_next.block())
+                               train.stop_at(&block);
+               }
        }
 }
 
@@ -406,9 +451,11 @@ void TrainRouter::create_plans(Layout &layout)
 }
 
 
-TrainRouter::Wait::Wait():
-       block(0),
-       train(0)
+TrainRouter::SequencePoint::SequencePoint(Block &b, unsigned o):
+       block(&b),
+       preceding_train(0),
+       sequence_in(0),
+       sequence_out(o)
 { }
 
 
index c1b6977f3734d45b19f615146c899d0ef22dedc0..6f697f997b6349ba686b409022ce9e1d6fd79e86 100644 (file)
@@ -29,12 +29,14 @@ public:
        sigc::signal<void, const TrackChain *> signal_waypoint_reached;
 
 private:
-       struct Wait
+       struct SequencePoint
        {
                Block *block;
-               Train *train;
+               Train *preceding_train;
+               unsigned sequence_in;
+               unsigned sequence_out;
 
-               Wait();
+               SequencePoint(Block &, unsigned);
        };
 
        typedef std::list<const Route *> RouteList;
@@ -45,7 +47,9 @@ private:
        const TrackChain *destination;
        std::vector<const TrackChain *> waypoints;
        std::vector<TrainRouteMetric *> metrics;
-       std::list<Wait> waits;
+       std::list<SequencePoint> sequence_points;
+       std::list<SequencePoint *> pending_sequence_checks;
+       unsigned current_sequence;
        Msp::Time::TimeDelta delay;
 
        bool update_pending;
@@ -59,8 +63,10 @@ public:
 
        bool set_route(const Route *);
        bool add_route(const Route &);
-       void add_wait(Block &, Train *);
        const Route *get_route() const;
+       void add_sequence_point(Block &, unsigned);
+       void add_sequence_point(Block &, Train &, unsigned, unsigned);
+       unsigned get_current_sequence() const { return current_sequence; }
 
        void set_destination(const TrackChain &);
        const TrackChain *get_destination() const { return destination; }