1 #include <msp/time/units.h>
2 #include <msp/time/utils.h>
4 #include "trafficmanager.h"
14 Train::Train(TrafficManager &tm, Locomotive &l):
20 trfc_mgr.add_train(this);
22 const map<unsigned, Sensor *> &sensors=trfc_mgr.get_control().get_sensors();
23 for(map<unsigned, Sensor *>::const_iterator i=sensors.begin(); i!=sensors.end(); ++i)
24 i->second->signal_state_changed.connect(sigc::bind(sigc::mem_fun(this, &Train::sensor_event), i->second));
27 void Train::set_name(const string &n)
31 signal_name_changed.emit(name);
34 void Train::set_speed(unsigned speed)
39 // XXX We might roll onto a new sensor and get confused - should delay freeing blocks a bit
40 for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
43 try_reserve=Time::TimeStamp();
45 else if(rsv_blocks.empty() && !reserve_more())
48 loco.set_speed(speed);
49 set_status(target_speed ? "Traveling" : "Stopped");
52 void Train::place(Block *block, unsigned entry)
54 for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end();)
57 i=rsv_blocks.erase(i);
60 for(list<BlockRef>::iterator i=cur_blocks.begin(); i!=cur_blocks.end();)
63 i=cur_blocks.erase(i);
66 if(!block->reserve(this))
68 set_status("Unplaced");
72 cur_blocks.push_back(BlockRef(block, entry));
74 set_status("Stopped");
77 bool Train::free_block(Block *block)
79 for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
82 while(i!=rsv_blocks.end())
85 i=rsv_blocks.erase(i);
93 void Train::tick(const Time::TimeStamp &t)
95 if(try_reserve && t>try_reserve)
97 if(reserve_more() || !rsv_blocks.empty())
99 loco.set_speed(target_speed);
100 set_status("Traveling");
101 try_reserve=Time::TimeStamp();
104 try_reserve=t+2*Time::sec;
108 void Train::sensor_event(bool state, Sensor *sensor)
110 unsigned addr=sensor->get_address();
114 list<BlockRef>::iterator i;
115 for(i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
116 if(i->block->get_sensor_id() && i->block->get_sensor_id()!=addr)
119 if(i!=rsv_blocks.begin())
121 cur_blocks.splice(cur_blocks.end(), rsv_blocks, rsv_blocks.begin(), i);
122 cout<<"Train "<<name<<" advanced, "<<cur_blocks.size()<<" cur_blocks, "<<rsv_blocks.size()<<" rsv_blocks\n";
125 if(target_speed && rsv_blocks.empty() && !reserve_more())
128 try_reserve=Time::now()+2*Time::sec;
129 set_status("Blocked");
134 cout<<"Train "<<name<<" finding blocks to free\n";
135 list<BlockRef>::iterator i;
136 for(i=cur_blocks.begin(); i!=cur_blocks.end(); ++i)
138 if(i->block->get_sensor_id()==addr)
141 for(list<BlockRef>::iterator j=cur_blocks.begin(); j!=i; ++j)
142 j->block->reserve(0);
143 cout<<" "<<distance(cur_blocks.begin(), i)<<" blocks freed, ";
144 cur_blocks.erase(cur_blocks.begin(), i);
145 cout<<cur_blocks.size()<<" cur_blocks\n";
154 bool Train::reserve_more()
157 if(!rsv_blocks.empty())
158 last=&rsv_blocks.back();
159 else if(!cur_blocks.empty())
160 last=&cur_blocks.back();
164 cout<<"Train "<<name<<" reserving more blocks\n";
167 unsigned size=rsv_blocks.size();
170 int exit=last->block->traverse(last->entry);
173 Block *link=last->block->get_link(exit);
174 if(link && link->reserve(this))
176 rsv_blocks.push_back(BlockRef(link, link->get_endpoint_by_link(*last->block)));
177 last=&rsv_blocks.back();
188 cout<<" "<<rsv_blocks.size()<<" rsv_blocks\n";
193 void Train::set_status(const string &s)
196 signal_status_changed.emit(s);
199 } // namespace Marklin