+ add("route", &Loader::route);
+ add("timetable", &Loader::timetable);
+ add("vehicle", &Loader::vehicle);
+}
+
+void Train::Loader::finish()
+{
+ if(!obj.cur_blocks.empty())
+ {
+ const BlockRef &blkref = obj.cur_blocks.front();
+ const Block::Endpoint &bep = blkref.block->get_endpoints()[blkref.entry];
+ obj.vehicles.back()->place(bep.track, bep.track_ep, 0, Vehicle::BACK_BUFFER);
+
+ obj.set_status("Stopped");
+ }
+}
+
+void Train::Loader::block(unsigned id)
+{
+ if(!blocks_valid)
+ return;
+
+ Block *blk;
+ try
+ {
+ blk = &obj.layout.get_block(id);
+ }
+ catch(const KeyError &)
+ {
+ blocks_valid = false;
+ return;
+ }
+
+ int entry = -1;
+ if(prev_block)
+ entry = blk->get_endpoint_by_link(*prev_block);
+ if(entry<0)
+ entry = 0;
+
+ blk->reserve(&obj);
+ obj.cur_blocks.push_back(BlockRef(blk, entry));
+
+ if(blk->get_sensor_id())
+ obj.layout.get_driver().set_sensor(blk->get_sensor_id(), true);
+
+ prev_block = blk;
+}
+
+void Train::Loader::block_hint(unsigned id)
+{
+ try
+ {
+ prev_block = &obj.layout.get_block(id);
+ }
+ catch(const KeyError &)
+ {
+ blocks_valid = false;
+ }
+}
+
+void Train::Loader::name(const string &n)
+{
+ obj.set_name(n);