]> git.tdb.fi Git - r2c2.git/blobdiff - source/libmarklin/train.cpp
Block reservation fixes
[r2c2.git] / source / libmarklin / train.cpp
index 341921aaf511000a406869cd78f0b566641ec420..d7b422039ea71e43b740f619a59c33a03f9edd6a 100644 (file)
@@ -36,6 +36,8 @@ Train::Train(TrafficManager &tm, Locomotive &l):
 {
        trfc_mgr.add_train(this);
 
+       loco.signal_reverse_changed.connect(sigc::mem_fun(this, &Train::locomotive_reverse_changed));
+
        const map<unsigned, Sensor *> &sensors = trfc_mgr.get_control().get_sensors();
        for(map<unsigned, Sensor *>::const_iterator i=sensors.begin(); i!=sensors.end(); ++i)
                i->second->signal_state_changed.connect(sigc::bind(sigc::mem_fun(this, &Train::sensor_event), i->second));
@@ -57,24 +59,31 @@ void Train::set_name(const string &n)
 
 void Train::set_speed(unsigned speed)
 {
+       if(speed==target_speed)
+               return;
        if(!target_speed && speed)
                travel_speed = static_cast<int>(round(speed*speed_scale*87*3.6/5))*5;
 
        target_speed = speed;
        if(!target_speed)
        {
-               // XXX We might roll onto a new sensor and get confused - should delay freeing blocks a bit
-               for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
-                       i->block->reserve(0);
-               rsv_blocks.clear();
+               trfc_mgr.get_control().set_timer(3*Time::sec).signal_timeout.connect(
+                       sigc::bind_return(sigc::mem_fun(this, &Train::release_reserved_blocks), false));
        }
        else
                reserve_more();
 
+       signal_target_speed_changed.emit(target_speed);
+
        update_speed();
        pure_speed = false;
 }
 
+void Train::set_reverse(bool rev)
+{
+       loco.set_reverse(rev);
+}
+
 void Train::place(Block *block, unsigned entry)
 {
        for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end();)
@@ -166,6 +175,18 @@ void Train::save(list<DataFile::Statement> &st) const
        st.push_back((DataFile::Statement("speed_scale"), speed_scale, speed_scale_weight));
 }
 
+void Train::locomotive_reverse_changed(bool)
+{
+       for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
+               i->block->reserve(0);
+       rsv_blocks.clear();
+       cur_blocks.reverse();
+       for(list<BlockRef>::iterator i=cur_blocks.begin(); i!=cur_blocks.end(); ++i)
+               i->entry = i->block->traverse(i->entry);
+       reserve_more();
+       update_speed();
+}
+
 void Train::sensor_event(bool state, Sensor *sensor)
 {
        unsigned addr = sensor->get_address();
@@ -222,12 +243,15 @@ void Train::sensor_event(bool state, Sensor *sensor)
        else
        {
                for(list<BlockRef>::iterator i=cur_blocks.begin(); i!=cur_blocks.end(); ++i)
-                       if(i->block->get_sensor_id()==addr)
+                       if(unsigned b_addr = i->block->get_sensor_id())
                        {
-                               ++i;
-                               for(list<BlockRef>::iterator j=cur_blocks.begin(); j!=i; ++j)
-                                       j->block->reserve(0);
-                               cur_blocks.erase(cur_blocks.begin(), i);
+                               if(b_addr==addr)
+                               {
+                                       ++i;
+                                       for(list<BlockRef>::iterator j=cur_blocks.begin(); j!=i; ++j)
+                                               j->block->reserve(0);
+                                       cur_blocks.erase(cur_blocks.begin(), i);
+                               }
                                break;
                        }
 
@@ -378,6 +402,13 @@ void Train::set_position(const Block::Endpoint &bep)
        pos = cur_track->get_endpoint_position(cur_track_ep);
 }
 
+void Train::release_reserved_blocks()
+{
+       for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
+               i->block->reserve(0);
+       rsv_blocks.clear();
+}
+
 
 Train::Loader::Loader(Train &t):
        DataFile::BasicLoader<Train>(t)