1 #include <msp/time/units.h>
2 #include <msp/time/utils.h>
4 #include "trafficmanager.h"
14 Train::Train(TrafficManager &tm, Locomotive &l):
19 trfc_mgr.add_train(this);
21 const map<unsigned, Sensor *> &sensors=trfc_mgr.get_control().get_sensors();
22 for(map<unsigned, Sensor *>::const_iterator i=sensors.begin(); i!=sensors.end(); ++i)
23 i->second->signal_state_changed.connect(sigc::bind(sigc::mem_fun(this, &Train::sensor_event), i->second));
26 void Train::set_name(const string &n)
30 signal_name_changed.emit(name);
33 void Train::set_speed(unsigned speed)
38 for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
42 else if(rsv_blocks.empty() && !reserve_more())
44 loco.set_speed(speed);
47 void Train::place(Block *block, unsigned entry)
49 for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end();)
52 i=rsv_blocks.erase(i);
55 for(list<BlockRef>::iterator i=cur_blocks.begin(); i!=cur_blocks.end();)
58 i=cur_blocks.erase(i);
61 if(!block->reserve(this))
64 cur_blocks.push_back(BlockRef(block, entry));
67 bool Train::free_block(Block *block)
69 for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
72 while(i!=rsv_blocks.end())
75 i=rsv_blocks.erase(i);
83 void Train::tick(const Time::TimeStamp &t)
85 if(try_reserve && t>try_reserve)
89 loco.set_speed(target_speed);
90 try_reserve=Time::TimeStamp();
93 try_reserve=t+2*Time::sec;
97 void Train::sensor_event(bool state, Sensor *sensor)
102 unsigned addr=sensor->get_address();
106 list<BlockRef>::iterator i;
107 for(i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
108 if(i->block->get_sensor_id() && i->block->get_sensor_id()!=addr)
110 cur_blocks.splice(cur_blocks.end(), rsv_blocks, rsv_blocks.begin(), i);
112 cout<<"Train "<<this<<" advanced, "<<cur_blocks.size()<<" cur_blocks, "<<rsv_blocks.size()<<" rsv_blocks\n";
114 if(rsv_blocks.empty() && !reserve_more())
117 try_reserve=Time::now()+2*Time::sec;
122 cout<<"Train "<<this<<" finding blocks to free\n";
123 list<BlockRef>::iterator i;
124 for(i=cur_blocks.begin(); i!=cur_blocks.end(); ++i)
126 if(i->block->get_sensor_id()==addr)
129 for(list<BlockRef>::iterator j=cur_blocks.begin(); j!=i; ++j)
130 j->block->reserve(0);
131 cout<<" "<<distance(cur_blocks.begin(), i)<<" blocks freed, ";
132 cur_blocks.erase(cur_blocks.begin(), i);
133 cout<<cur_blocks.size()<<" cur_blocks\n";
141 bool Train::reserve_more()
144 if(!rsv_blocks.empty())
145 last=&rsv_blocks.back();
146 else if(!cur_blocks.empty())
147 last=&cur_blocks.back();
151 cout<<"Train "<<this<<" reserving more blocks\n";
154 unsigned size=rsv_blocks.size();
157 int exit=last->block->traverse(last->entry);
160 Block *link=last->block->get_link(exit);
161 if(link && link->reserve(this))
163 rsv_blocks.push_back(BlockRef(link, link->get_endpoint_by_link(*last->block)));
164 last=&rsv_blocks.back();
175 cout<<" "<<rsv_blocks.size()<<" rsv_blocks\n";
180 } // namespace Marklin