]> git.tdb.fi Git - r2c2.git/blobdiff - source/libmarklin/train.cpp
Support trains with multiple vehicles
[r2c2.git] / source / libmarklin / train.cpp
index d5b2b226721c961fb88b96753434d665f1f0180d..fad68605e7c70952faf21ac6931616a7114a7f70 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));
@@ -331,7 +336,8 @@ void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt)
                if(!active)
                        set_active(true);
 
-               Track *track = vehicles[0]->get_track();
+               Vehicle &vehicle = *(reverse ? vehicles.back() : vehicles.front());
+               Track *track = vehicle.get_track();
 
                bool ok = false;
                for(list<BlockRef>::const_iterator i=cur_blocks.begin(); (!ok && i!=cur_blocks.end()); ++i)
@@ -340,7 +346,7 @@ void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt)
                if(ok)
                {
                        float d = get_real_speed(current_speed)*(dt/Time::sec);
-                       vehicles[0]->advance(reverse ? -d : d);
+                       vehicle.advance(reverse ? -d : d);
                }
        }
        else if(end_of_route)
@@ -369,6 +375,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)
@@ -772,6 +785,8 @@ Train::Loader::Loader(Train &t):
        add("name",        &Loader::name);
        add("real_speed",  &Loader::real_speed);
        add("route",       &Loader::route);
+       add("timetable",   &Loader::timetable);
+       add("vehicle",     &Loader::vehicle);
 }
 
 void Train::Loader::block(unsigned id)
@@ -816,4 +831,21 @@ 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);
+}
+
+void Train::Loader::vehicle(unsigned n)
+{
+       const VehicleType &vtype = obj.layout.get_catalogue().get_vehicle(n);
+       Vehicle *veh = new Vehicle(obj.layout, vtype);
+       obj.vehicles.back()->attach_back(*veh);
+       obj.vehicles.push_back(veh);
+}
+
 } // namespace Marklin