+ 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;
+ }
+
+ return nsens;
+}
+
+void Train::update_speed()
+{
+ if(!target_speed)
+ {
+ loco.set_speed(0);
+ try_reserve = Time::TimeStamp();
+ set_status("Stopped");
+ }
+ else
+ {
+ unsigned nsens = 0;
+ for(list<BlockRef>::const_iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
+ if(i->block->get_sensor_id())
+ ++nsens;
+
+ if(nsens==0)
+ {
+ loco.set_speed(0);
+ pure_speed = false;
+ try_reserve = Time::now()+2*Time::sec;
+ set_status("Blocked");
+ }
+ else if(nsens==1 && target_speed>3)
+ {
+ loco.set_speed(3);
+ pure_speed = false;
+ try_reserve = Time::now()+2*Time::sec;
+ set_status("Slow");
+ }
+ else
+ {
+ loco.set_speed(target_speed);
+ try_reserve = Time::TimeStamp();
+ set_status(format("Traveling %d kmh", travel_speed));
+ }
+ }
+}
+
+void Train::set_status(const string &s)
+{
+ status = s;
+ signal_status_changed.emit(s);
+}
+
+void Train::set_position(const Block::Endpoint &bep)
+{
+ cur_track = bep.track;
+ cur_track_ep = bep.track_ep;
+ offset = 0;
+ pos = cur_track->get_endpoint_position(cur_track_ep);
+}
+
+
+Train::Loader::Loader(Train &t):
+ DataFile::BasicLoader<Train>(t)
+{
+ add("name", &Train::name);
+ add("speed_scale", &Train::speed_scale, &Train::speed_scale_weight);