2 #include <msp/strings/formatter.h>
3 #include <msp/time/units.h>
4 #include <msp/time/utils.h>
6 #include "trafficmanager.h"
16 Train::Train(TrafficManager &tm, Locomotive &l):
24 trfc_mgr.add_train(this);
26 const map<unsigned, Sensor *> &sensors=trfc_mgr.get_control().get_sensors();
27 for(map<unsigned, Sensor *>::const_iterator i=sensors.begin(); i!=sensors.end(); ++i)
28 i->second->signal_state_changed.connect(sigc::bind(sigc::mem_fun(this, &Train::sensor_event), i->second));
31 void Train::set_name(const string &n)
35 signal_name_changed.emit(name);
38 void Train::set_speed(unsigned speed)
40 unsigned old_speed=target_speed;
45 // XXX We might roll onto a new sensor and get confused - should delay freeing blocks a bit
46 for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
49 try_reserve=Time::TimeStamp();
51 else if(rsv_blocks.empty() && !reserve_more())
54 loco.set_speed(speed);
55 if(!old_speed && target_speed)
56 set_status("Traveling --- kmh");
57 else if(old_speed && !target_speed)
58 set_status("Stopped");
61 void Train::place(Block *block, unsigned entry)
63 for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end();)
66 i=rsv_blocks.erase(i);
69 for(list<BlockRef>::iterator i=cur_blocks.begin(); i!=cur_blocks.end();)
72 i=cur_blocks.erase(i);
75 if(!block->reserve(this))
77 set_status("Unplaced");
81 cur_blocks.push_back(BlockRef(block, entry));
83 set_status("Stopped");
86 bool Train::free_block(Block *block)
88 for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
91 while(i!=rsv_blocks.end())
94 i=rsv_blocks.erase(i);
102 void Train::tick(const Time::TimeStamp &t)
104 if(try_reserve && t>try_reserve)
106 if(reserve_more() || !rsv_blocks.empty())
108 loco.set_speed(target_speed);
109 set_status("Traveling --- kmh");
110 try_reserve=Time::TimeStamp();
113 try_reserve=t+2*Time::sec;
117 void Train::sensor_event(bool state, Sensor *sensor)
119 unsigned addr=sensor->get_address();
123 list<BlockRef>::iterator i;
124 for(i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
125 if(i->block->get_sensor_id() && i->block->get_sensor_id()!=addr)
128 if(i!=rsv_blocks.begin())
130 real_speed=static_cast<int>(round(travel_dist/((Time::now()-last_entry_time)/Time::sec)*87*3.6/5))*5;
131 set_status(format("Traveling %3d kmh", real_speed));
135 for(list<BlockRef>::iterator j=rsv_blocks.begin(); j!=i; ++j)
137 j->block->traverse(j->entry, &block_len);
138 cout<<"Advancing: block "<<j->block<<" (sensor "<<j->block->get_sensor_id()<<") length "<<block_len<<'\n';
139 travel_dist+=block_len;
141 last_entry_time=Time::now();
143 cur_blocks.splice(cur_blocks.end(), rsv_blocks, rsv_blocks.begin(), i);
144 cout<<"Train "<<name<<" advanced, "<<cur_blocks.size()<<" cur_blocks, "<<rsv_blocks.size()<<" rsv_blocks\n";
147 if(target_speed && !reserve_more() && rsv_blocks.empty())
150 try_reserve=Time::now()+2*Time::sec;
151 set_status("Blocked");
156 cout<<"Train "<<name<<" finding blocks to free\n";
157 list<BlockRef>::iterator i;
158 for(i=cur_blocks.begin(); i!=cur_blocks.end(); ++i)
160 if(i->block->get_sensor_id()==addr)
163 for(list<BlockRef>::iterator j=cur_blocks.begin(); j!=i; ++j)
164 j->block->reserve(0);
165 cout<<" "<<distance(cur_blocks.begin(), i)<<" blocks freed, ";
166 cur_blocks.erase(cur_blocks.begin(), i);
167 cout<<cur_blocks.size()<<" cur_blocks\n";
176 bool Train::reserve_more()
179 if(!rsv_blocks.empty())
180 last=&rsv_blocks.back();
181 else if(!cur_blocks.empty())
182 last=&cur_blocks.back();
186 cout<<"Train "<<name<<" reserving more blocks\n";
189 unsigned size=rsv_blocks.size();
192 int exit=last->block->traverse(last->entry);
195 Block *link=last->block->get_link(exit);
196 if(link && link->reserve(this))
198 rsv_blocks.push_back(BlockRef(link, link->get_endpoint_by_link(*last->block)));
199 last=&rsv_blocks.back();
210 cout<<" "<<rsv_blocks.size()<<" rsv_blocks\n";
215 void Train::set_status(const string &s)
218 signal_status_changed.emit(s);
221 } // namespace Marklin