X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibr2c2%2Ftrain.cpp;h=ba1a861b9e24ec75f14a91049d8d3a76b54fc29f;hb=e77b01f9fed6d5f653dbd0123f0f1f61a13c3dfa;hp=16077ef8e4878823fe406e6098911e2ba6ee0e4b;hpb=251270c97a5e5eb8630bc1662a406255dedae90e;p=r2c2.git diff --git a/source/libr2c2/train.cpp b/source/libr2c2/train.cpp index 16077ef..ba1a861 100644 --- a/source/libr2c2/train.cpp +++ b/source/libr2c2/train.cpp @@ -5,6 +5,7 @@ Copyright © 2006-2011 Mikkosoft Productions, Mikko Rasa Distributed under the GPL */ +#include #include #include #include @@ -55,15 +56,13 @@ Train::Train(Layout &l, const VehicleType &t, unsigned a, const string &p): pending_block(0), reserving(false), advancing(false), - controller(new AIControl(*this, new SimpleController)), - timetable(0), + controller(new SimpleController), active(false), current_speed_step(0), speed_changing(false), reverse(false), functions(0), end_of_route(false), - status("Unplaced"), travel_dist(0), pure_speed(false), speed_quantizer(0), @@ -86,7 +85,7 @@ Train::Train(Layout &l, const VehicleType &t, unsigned a, const string &p): layout.get_driver().signal_loco_function.connect(sigc::mem_fun(this, &Train::loco_func_event)); layout.signal_block_reserved.connect(sigc::mem_fun(this, &Train::block_reserved)); - layout.get_driver().signal_sensor.connect(sigc::mem_fun(this, &Train::sensor_event)); + layout.signal_block_state_changed.connect(sigc::mem_fun(this, &Train::block_state_changed)); layout.get_driver().signal_halt.connect(sigc::mem_fun(this, &Train::halt_event)); @@ -101,7 +100,6 @@ Train::Train(Layout &l, const VehicleType &t, unsigned a, const string &p): Train::~Train() { delete controller; - delete timetable; for(vector::iterator i=vehicles.begin(); i!=vehicles.end(); ++i) delete *i; layout.remove_train(*this); @@ -181,10 +179,7 @@ void Train::set_active(bool a) reserve_more(); } else - { stop_timeout = Time::now()+2*Time::sec; - set_status("Stopped"); - } } void Train::set_function(unsigned func, bool state) @@ -204,15 +199,45 @@ float Train::get_speed() const return controller->get_speed(); } +float Train::get_quantized_speed() const +{ + if(speed_quantizer) + return speed_quantizer->quantize_speed(controller->get_speed()); + else + return controller->get_speed(); +} + bool Train::get_function(unsigned func) const { return (functions>>func)&1; } -void Train::set_timetable(Timetable *tt) +void Train::add_ai(TrainAI &ai) { - delete timetable; - timetable = tt; + ais.push_back(&ai); + ai.signal_event.connect(sigc::bind<0>(signal_ai_event, sigc::ref(ai))); +} + +void Train::remove_ai(TrainAI &ai) +{ + list::iterator i = find(ais.begin(), ais.end(), &ai); + if(i!=ais.end()) + ais.erase(i); +} + +TrainAI *Train::get_tagged_ai(const string &tag) const +{ + for(list::const_iterator i=ais.begin(); i!=ais.end(); ++i) + if((*i)->get_tag()==tag) + return *i; + + return 0; +} + +void Train::ai_message(const TrainAI::Message &msg) +{ + for(list::iterator i=ais.begin(); i!=ais.end(); ++i) + (*i)->message(msg); } bool Train::set_route(const Route *r) @@ -412,10 +437,7 @@ void Train::place(Block &block, unsigned entry) accurate_position = false; if(!block.reserve(this)) - { - set_status("Unplaced"); return; - } blocks.push_back(BlockIter(&block, entry)); if(reverse) @@ -442,8 +464,6 @@ void Train::unplace() for(vector::iterator i=vehicles.begin(); i!=vehicles.end(); ++i) (*i)->unplace(); - - set_status("Unplaced"); } bool Train::free_block(Block &block) @@ -559,10 +579,11 @@ void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt) Driver &driver = layout.get_driver(); - if(timetable) - timetable->tick(t); + for(list::iterator i=ais.begin(); i!=ais.end(); ++i) + (*i)->tick(t, dt); controller->tick(dt); float speed = controller->get_speed(); + bool moving = speed>0; if(controller->get_reverse()!=reverse) { @@ -584,17 +605,12 @@ void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt) driver.set_loco_speed(address, speed_step); pure_speed = false; - - if(speed_step) - set_status(format("Traveling %d kmh", get_travel_speed())); - else - set_status("Waiting"); } speed = speed_quantizer->get_speed(current_speed_step); } - if(speed) + if(moving) { if(!active) set_active(true); @@ -679,12 +695,14 @@ void Train::save(list &st) const st.push_back((DataFile::Statement("route"), i->route->get_name())); } - if(timetable) - { - DataFile::Statement ss("timetable"); - timetable->save(ss.sub); - st.push_back(ss); - } + // XXX Need more generic way of saving AI state + for(list::const_iterator i=ais.begin(); i!=ais.end(); ++i) + if(Timetable *timetable = dynamic_cast(*i)) + { + DataFile::Statement ss("timetable"); + timetable->save(ss.sub); + st.push_back(ss); + } } void Train::control_changed(const Controller::Control &ctrl) @@ -717,9 +735,9 @@ void Train::loco_func_event(unsigned addr, unsigned func, bool state) } } -void Train::sensor_event(unsigned addr, bool state) +void Train::block_state_changed(Block &block, Block::State state) { - if(state) + if(state==Block::MAYBE_ACTIVE) { // Find the first sensor block from our reserved blocks that isn't this sensor BlockList::iterator end; @@ -727,7 +745,7 @@ void Train::sensor_event(unsigned addr, bool state) for(end=cur_blocks_end; end!=blocks.end(); ++end) if((*end)->get_sensor_id()) { - if((*end)->get_sensor_id()!=addr) + if(&**end!=&block) { if(result==0) result = 2; @@ -745,19 +763,15 @@ void Train::sensor_event(unsigned addr, bool state) // Compute speed and update related state float travel_time_secs = (Time::now()-last_entry_time)/Time::sec; - if(pure_speed) - { - if(speed_quantizer && current_speed_step>0) - speed_quantizer->learn(current_speed_step, travel_dist/travel_time_secs, travel_time_secs); - set_status(format("Traveling %d kmh", get_travel_speed())); - } + if(pure_speed && speed_quantizer && current_speed_step>0 && travel_time_secs>=2) + speed_quantizer->learn(current_speed_step, travel_dist/travel_time_secs, travel_time_secs); travel_dist = 0; for(BlockList::iterator j=cur_blocks_end; j!=end; ++j) { travel_dist += (*j)->get_path_length(j->entry()); - if((*j)->get_sensor_id()==addr && !advancing) + if(&**j==&block && !advancing) { TrackIter track = j->track_iter(); if(reverse) @@ -800,7 +814,7 @@ void Train::sensor_event(unsigned addr, bool state) else if(result==3) layout.emergency("Sensor for "+name+" triggered out of order"); } - else + else if(state==Block::INACTIVE) { const Vehicle &veh = *(reverse ? vehicles.front() : vehicles.back()); @@ -1150,23 +1164,6 @@ float Train::get_reserved_distance_until(const Block *until_block, bool back) co return result; } -float Train::get_travel_speed() const -{ - float speed = 0; - if(speed_quantizer) - speed = speed_quantizer->get_speed(current_speed_step); - else - speed = controller->get_speed(); - float scale = layout.get_catalogue().get_scale(); - return static_cast(round(speed/scale*3.6/5))*5; -} - -void Train::set_status(const string &s) -{ - status = s; - signal_status_changed.emit(s); -} - void Train::release_blocks() { release_blocks(blocks.begin(), blocks.end()); @@ -1313,8 +1310,6 @@ void Train::Loader::finish() TrackIter track = obj.blocks.front().track_iter(); float offset = 2*obj.layout.get_catalogue().get_scale(); obj.vehicles.back()->place(*track, track.entry(), offset, Vehicle::BACK_BUFFER); - - obj.set_status("Stopped"); } } @@ -1379,11 +1374,8 @@ void Train::Loader::route(const string &n) void Train::Loader::timetable() { - if(obj.timetable) - throw InvalidState("A timetable has already been loaded"); - - obj.timetable = new Timetable(obj); - load_sub(*obj.timetable); + Timetable *ttbl = new Timetable(obj); + load_sub(*ttbl); } void Train::Loader::vehicle(ArticleNumber art_nr)