]> git.tdb.fi Git - r2c2.git/blobdiff - source/libmarklin/train.cpp
Emit signal for control changes initiated by the control model itself
[r2c2.git] / source / libmarklin / train.cpp
index 8ddb66bee3c5047a7c287a6925220d3456a1af0b..307b1b7da0f2903cc526b348fcdc291af3970815 100644 (file)
@@ -16,6 +16,7 @@ Distributed under the GPL
 #include "locotype.h"
 #include "route.h"
 #include "simplephysics.h"
+#include "timetable.h"
 #include "tracktype.h"
 #include "train.h"
 #include "vehicle.h"
@@ -31,6 +32,7 @@ Train::Train(Layout &l, const LocoType &t, unsigned a):
        address(a),
        pending_block(0),
        control(new AIControl(*this, new SimplePhysics)),
+       timetable(0),
        active(false),
        current_speed(0),
        speed_changing(false),
@@ -55,6 +57,8 @@ Train::Train(Layout &l, const LocoType &t, unsigned a):
        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.get_driver().signal_turnout.connect(sigc::mem_fun(this, &Train::turnout_event));
+
+       control->signal_control_changed.connect(signal_control_changed);
 }
 
 Train::~Train()
@@ -88,7 +92,6 @@ const Vehicle &Train::get_vehicle(unsigned i) const
 void Train::set_control(const string &n, float v)
 {
        control->set_control(n, v);
-       signal_control_changed.emit(n, control->get_control(n).value);
 }
 
 void Train::set_active(bool a)
@@ -299,6 +302,8 @@ void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt)
                stop_timeout = Time::TimeStamp();
        }
 
+       if(timetable)
+               timetable->tick(t);
        control->tick(dt);
        float speed = control->get_speed();
        unsigned speed_notch = find_speed(abs(speed));
@@ -343,6 +348,8 @@ void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt)
                        vehicles[0]->advance(reverse ? -d : d);
                }
        }
+       else if(end_of_route)
+               set_route(0);
 }
 
 void Train::save(list<DataFile::Statement> &st) const
@@ -367,6 +374,13 @@ void Train::save(list<DataFile::Statement> &st) const
 
        if(route)
                st.push_back((DataFile::Statement("route"), route->get_name()));
+
+       if(timetable)
+       {
+               DataFile::Statement ss("timetable");
+               timetable->save(ss.sub);
+               st.push_back(ss);
+       }
 }
 
 void Train::loco_speed_event(unsigned addr, unsigned speed, bool)
@@ -461,10 +475,7 @@ void Train::sensor_event(unsigned addr, bool state)
                        {
                                unsigned nsens = reserve_more();
                                if(!nsens && end_of_route)
-                               {
                                        signal_arrived.emit();
-                                       set_route(0);
-                               }
                        }
                }
        }
@@ -525,15 +536,20 @@ unsigned Train::reserve_more()
                if(i->block->get_sensor_id())
                        ++nsens;
        
+       if(end_of_route)
+               return nsens;
+
        const Route *cur_route = 0;
        if(route)
        {
-               unsigned exit = last->block->traverse(last->entry);
-               Track *track = last->block->get_endpoints()[exit].track;
-               if(route->get_tracks().count(track))
-                       cur_route = route;
-               else if(next_route && next_route->get_tracks().count(track))
-                       cur_route = next_route;
+               const set<Track *> &tracks = last->block->get_tracks();
+               for(set<Track *>::const_iterator i=tracks.begin(); (cur_route!=route && i!=tracks.end()); ++i)
+               {
+                       if(route->get_tracks().count(*i))
+                               cur_route = route;
+                       else if(next_route && next_route->get_tracks().count(*i))
+                               cur_route = next_route;
+               }
        }
 
        bool got_more = false;
@@ -768,6 +784,7 @@ Train::Loader::Loader(Train &t):
        add("name",        &Loader::name);
        add("real_speed",  &Loader::real_speed);
        add("route",       &Loader::route);
+       add("timetable",   &Loader::timetable);
 }
 
 void Train::Loader::block(unsigned id)
@@ -812,4 +829,13 @@ void Train::Loader::route(const string &n)
        obj.set_route(&obj.layout.get_route(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);
+}
+
 } // namespace Marklin