+void Engineer::train_added(Train &train)
+{
+ TrainPanel *tpanel = new TrainPanel(*this, ui_res, train);
+ root->add(*tpanel);
+ int y = main_panel->get_geometry().y;
+ for(list<TrainPanel *>::iterator i=train_panels.begin(); i!=train_panels.end(); ++i)
+ y -= (*i)->get_geometry().h;
+ tpanel->set_position(0, y-tpanel->get_geometry().h);
+ train_panels.push_back(tpanel);
+ tpanel->set_visible(true);
+
+ Vehicle3D &loco3d = layout_3d.get_vehicle(train.get_vehicle(0));
+ overlay->set_label(loco3d, train.get_name());
+ train.signal_name_changed.connect(sigc::bind<0>(sigc::mem_fun(overlay, &Overlay3D::set_label), sigc::ref(loco3d)));
+
+ GL::Color best_color;
+ float best_d_sq = 0;
+ for(unsigned i=0; i<10; ++i)
+ {
+ GL::Color color;
+ color.r = rand()*1.0/RAND_MAX;
+ color.g = rand()*1.0/RAND_MAX;
+ color.b = rand()*1.0/RAND_MAX;
+ color = color*(1/max(max(color.r, color.g), color.b));
+ float min_d_sq = 3;
+ for(map<Train *, GL::Color>::const_iterator j=train_colors.begin(); j!=train_colors.end(); ++j)
+ {
+ float dr = color.r-j->second.r;
+ float dg = color.g-j->second.g;
+ float db = color.b-j->second.b;
+ float d_sq = dr*dr+dg*dg+db*db;
+ if(d_sq<min_d_sq)
+ min_d_sq = d_sq;
+ }
+ if(min_d_sq>best_d_sq)
+ {
+ best_color = color;
+ best_d_sq = min_d_sq;
+ }
+ }
+ train_colors[&train] = best_color;
+}
+
+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<unsigned, Train *> &trains = layout.get_trains();
+ for(map<unsigned, Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
+ layout.get_driver().set_loco_speed(i->first, 0);
+ layout.get_driver().flush();
+ raise(sig);
+ }
+ else if(sig==SIGTERM || sig==SIGINT)
+ exit(0);
+}