]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/trainrouter.cpp
Replace waits with a more robust sequencing system
[r2c2.git] / source / libr2c2 / trainrouter.cpp
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 = █
-       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)
 { }