]> git.tdb.fi Git - r2c2.git/blobdiff - source/libmarklin/train.cpp
Allow setting sensor ID for multiple tracks at once
[r2c2.git] / source / libmarklin / train.cpp
index a0943a7c76370d28a3679d24330295154e4d98e6..4974318fba6e78687b842d5e0ea5baadc2b62378 100644 (file)
@@ -1,7 +1,7 @@
 /* $Id$
 
 This file is part of the MSP Märklin suite
-Copyright © 2006-2008 Mikkosoft Productions, Mikko Rasa
+Copyright © 2006-2009 Mikkosoft Productions, Mikko Rasa
 Distributed under the GPL
 */
 
@@ -54,15 +54,31 @@ void Train::set_speed(unsigned speed)
                        i->block->reserve(0);
                rsv_blocks.clear();
                try_reserve=Time::TimeStamp();
+               loco.set_speed(0);
+               if(old_speed)
+                       set_status("Stopped");
+       }
+       else
+       {
+               unsigned n=reserve_more();
+               if(n==0)
+               {
+                       try_reserve=Time::now()+2*Time::sec;
+                       set_status("Blocked");
+               }
+               else if(n==1)
+               {
+                       loco.set_speed(3);
+                       try_reserve=Time::now()+2*Time::sec;
+                       set_status("Slow");
+               }
+               else
+               {
+                       loco.set_speed(speed);
+                       if(!old_speed)
+                               set_status("Traveling --- kmh");
+               }
        }
-       else if(rsv_blocks.empty() && !reserve_more())
-               return;
-
-       loco.set_speed(speed);
-       if(!old_speed && target_speed)
-               set_status("Traveling --- kmh");
-       else if(old_speed && !target_speed)
-               set_status("Stopped");
 }
 
 void Train::place(Block *block, unsigned entry)
@@ -110,12 +126,19 @@ void Train::tick(const Time::TimeStamp &t)
 {
        if(try_reserve && t>try_reserve)
        {
-               if(reserve_more() || !rsv_blocks.empty())
+               unsigned n=reserve_more();
+               if(n>=2)
                {
                        loco.set_speed(target_speed);
                        set_status("Traveling --- kmh");
                        try_reserve=Time::TimeStamp();
                }
+               else if(n==1)
+               {
+                       loco.set_speed(3);
+                       set_status("Slow");
+                       try_reserve=t+2*Time::sec;
+               }
                else
                        try_reserve=t+2*Time::sec;
        }
@@ -151,19 +174,27 @@ void Train::sensor_event(bool state, Sensor *sensor)
                        cout<<"Train "<<name<<" advanced, "<<cur_blocks.size()<<" cur_blocks, "<<rsv_blocks.size()<<" rsv_blocks\n";
                }
 
-               if(target_speed && !reserve_more() && rsv_blocks.empty())
+               if(target_speed)
                {
-                       loco.set_speed(0);
-                       try_reserve=Time::now()+2*Time::sec;
-                       set_status("Blocked");
+                       unsigned n=reserve_more();
+                       if(n==0)
+                       {
+                               loco.set_speed(0);
+                               try_reserve=Time::now()+2*Time::sec;
+                               set_status("Blocked");
+                       }
+                       else if(n==1)
+                       {
+                               loco.set_speed(3);
+                               try_reserve=Time::now()+2*Time::sec;
+                               set_status("Slow");
+                       }
                }
        }
        else
        {
                cout<<"Train "<<name<<" finding blocks to free\n";
-               list<BlockRef>::iterator i;
-               for(i=cur_blocks.begin(); i!=cur_blocks.end(); ++i)
-               {
+               for(list<BlockRef>::iterator i=cur_blocks.begin(); i!=cur_blocks.end(); ++i)
                        if(i->block->get_sensor_id()==addr)
                        {
                                ++i;
@@ -173,14 +204,13 @@ void Train::sensor_event(bool state, Sensor *sensor)
                                cur_blocks.erase(cur_blocks.begin(), i);
                                cout<<cur_blocks.size()<<" cur_blocks\n";
                        }
-               }
 
                if(target_speed)
                        reserve_more();
        }
 }
 
-bool Train::reserve_more()
+unsigned Train::reserve_more()
 {
        BlockRef *last=0;
        if(!rsv_blocks.empty())
@@ -188,13 +218,17 @@ bool Train::reserve_more()
        else if(!cur_blocks.empty())
                last=&cur_blocks.back();
        if(!last)
-               return false;
+               return 0;
 
        cout<<"Train "<<name<<" reserving more blocks\n";
 
+       unsigned nsens=0;
+       for(list<BlockRef>::const_iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
+               if(i->block->get_sensor_id())
+                       ++nsens;
+
        bool result=false;
-       unsigned size=rsv_blocks.size();
-       while(size<3)
+       while(nsens<2)
        {
                int exit=last->block->traverse(last->entry);
                if(exit>=0) 
@@ -204,8 +238,11 @@ bool Train::reserve_more()
                        {
                                rsv_blocks.push_back(BlockRef(link, link->get_endpoint_by_link(*last->block)));
                                last=&rsv_blocks.back();
-                               ++size;
-                               result=true;
+                               if(last->block->get_sensor_id())
+                               {
+                                       ++nsens;
+                                       result=true;
+                               }
                        }
                        else
                                break;
@@ -214,9 +251,19 @@ bool Train::reserve_more()
                        break;
        }
 
+       while(last && !last->block->get_sensor_id())
+       {
+               last->block->reserve(0);
+               rsv_blocks.erase(--rsv_blocks.end());
+               if(!rsv_blocks.empty())
+                       last=&rsv_blocks.back();
+               else
+                       last=0;
+       }
+
        cout<<"  "<<rsv_blocks.size()<<" rsv_blocks\n";
 
-       return result;
+       return nsens;
 }
 
 void Train::set_status(const string &s)