From: Mikko Rasa Date: Sun, 27 Dec 2009 07:51:03 +0000 (+0000) Subject: Stop all trains when Engineer exits X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=e60fdcb9617f539b4d578d06ec46eb955c5e0624;hp=212bc6eb3ab2dbad39725984ac715c64f8de29ff;p=r2c2.git Stop all trains when Engineer exits Handle some abnormal termination conditions as well --- diff --git a/source/engineer/engineer.cpp b/source/engineer/engineer.cpp index 308e5b2..6a35a06 100644 --- a/source/engineer/engineer.cpp +++ b/source/engineer/engineer.cpp @@ -7,6 +7,7 @@ Distributed under the GPL #include #include +#include #include #include #include @@ -17,6 +18,7 @@ Distributed under the GPL #include #include #include +#include #include #include #include @@ -105,10 +107,24 @@ Engineer::Engineer(int argc, char **argv): i->second->signal_state_changed.connect(sigc::bind(sigc::mem_fun(this, &Engineer::sensor_event), i->second)); view_all(); + + catch_signal(SIGINT); + catch_signal(SIGTERM); + catch_signal(SIGSEGV); + catch_signal(SIGILL); + catch_signal(SIGFPE); + catch_signal(SIGABRT); } Engineer::~Engineer() { + const list &trains = trfc_mgr->get_trains(); + for(list::const_iterator i=trains.begin(); i!=trains.end(); ++i) + (*i)->set_speed(0); + + while(control.get_queue_length()) + control.tick(); + if(!simulate) trfc_mgr->save("engineer.state"); delete trfc_mgr; @@ -501,4 +517,20 @@ void Engineer::train_added(Train &train) place_train(train); } +void Engineer::sighandler(int sig) +{ + if(sig==SIGSEGV || sig==SIGILL || sig==SIGFPE || sig==SIGABRT) + { + signal(sig, SIG_DFL); + IO::print(IO::cerr, "Fatal signal received, terminating\n"); + const map &locos = control.get_locomotives(); + for(map::const_iterator i=locos.begin(); i!=locos.end(); ++i) + i->second->set_speed(0); + control.flush(); + raise(sig); + } + else if(sig==SIGTERM || sig==SIGINT) + exit(0); +} + Application::RegApp Engineer::reg; diff --git a/source/engineer/engineer.h b/source/engineer/engineer.h index 8e8e021..31952ba 100644 --- a/source/engineer/engineer.h +++ b/source/engineer/engineer.h @@ -83,6 +83,7 @@ private: void project_3d(); Marklin::Track3D *pick_track(int, int); void train_added(Marklin::Train &); + virtual void sighandler(int); static Msp::Application::RegApp reg; }; diff --git a/source/engineer/mainpanel.h b/source/engineer/mainpanel.h index 56dd494..017617d 100644 --- a/source/engineer/mainpanel.h +++ b/source/engineer/mainpanel.h @@ -8,13 +8,14 @@ Distributed under the GPL #ifndef MAINPANEL_H_ #define MAINPANEL_H_ +#include #include #include #include class Engineer; -class MainPanel: public Msp::GLtk::Panel +class MainPanel: public Msp::GLtk::Panel, public sigc::trackable { private: Engineer &engineer; diff --git a/source/engineer/trainpanel.h b/source/engineer/trainpanel.h index a76d907..7b92985 100644 --- a/source/engineer/trainpanel.h +++ b/source/engineer/trainpanel.h @@ -8,6 +8,7 @@ Distributed under the GPL #ifndef TRAINPANEL_H_ #define TRAINPANEL_H_ +#include #include #include #include @@ -17,7 +18,7 @@ Distributed under the GPL class Engineer; -class TrainPanel: public Msp::GLtk::Panel +class TrainPanel: public Msp::GLtk::Panel, public sigc::trackable { private: Engineer &engineer; diff --git a/source/libmarklin/control.cpp b/source/libmarklin/control.cpp index fa1117c..ae26a17 100644 --- a/source/libmarklin/control.cpp +++ b/source/libmarklin/control.cpp @@ -123,6 +123,12 @@ Command &Control::command(Cmd cmd, const unsigned char *data, unsigned len) return queue.back(); } +void Control::flush() +{ + for(list::iterator i=queue.begin(); i!=queue.end(); ++i) + i->send(serial_fd); +} + void Control::add_turnout(Turnout &t) { turnouts[t.get_address()] = &t; diff --git a/source/libmarklin/control.h b/source/libmarklin/control.h index 61469a8..a041e95 100644 --- a/source/libmarklin/control.h +++ b/source/libmarklin/control.h @@ -53,12 +53,14 @@ public: Command &command(Cmd, unsigned char); Command &command(Cmd, const unsigned char *, unsigned); unsigned get_queue_length() const { return queue.size(); } + void flush(); void add_turnout(Turnout &); Turnout &get_turnout(unsigned) const; const std::map &get_turnouts() const { return turnouts; } void add_locomotive(Locomotive &); Locomotive &get_locomotive(unsigned) const; + const std::map &get_locomotives() const { return locomotives; } void add_sensor(Sensor &); Sensor &get_sensor(unsigned) const; const std::map &get_sensors() const { return sensors; }