From 06c100aacb559fbbe7380e15981c4772092c269b Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 15 Jul 2007 10:59:20 +0000 Subject: [PATCH] Add Track::get_endpoint_position to avoid duplicating calculations Fix Block::traverse so it won't hang Fix memory leaks reported by valgrind Add signal_speed_changed for locomotive Bugfixes for block reservation of trains Color blocks that are occupied by a train Remove some unnecessary stuff from Engineer Add simulation mode for sensors Finish train placing Add speed display to TrainPanel --- source/designer/designer.cpp | 4 +- source/engineer/engineer.cpp | 219 +++++++++++++-------------- source/engineer/engineer.h | 17 +-- source/engineer/mainpanel.cpp | 6 +- source/engineer/trainpanel.cpp | 16 +- source/engineer/trainpanel.h | 2 + source/libmarklin/block.cpp | 4 +- source/libmarklin/block.h | 5 +- source/libmarklin/control.cpp | 6 + source/libmarklin/locomotive.cpp | 4 +- source/libmarklin/locomotive.h | 3 + source/libmarklin/track.cpp | 29 ++-- source/libmarklin/track.h | 1 + source/libmarklin/trafficmanager.cpp | 8 + source/libmarklin/trafficmanager.h | 5 + source/libmarklin/train.cpp | 22 ++- source/libmarklin/train.h | 7 +- 17 files changed, 206 insertions(+), 152 deletions(-) diff --git a/source/designer/designer.cpp b/source/designer/designer.cpp index eb5a0ef..d0bc940 100644 --- a/source/designer/designer.cpp +++ b/source/designer/designer.cpp @@ -36,9 +36,7 @@ Designer::Designer(int argc, char **argv): rotate(0), pitch(0) { - cout<<"blah?\n"; catalogue.load("tracks.dat"); - cout< #include #include +#include +#include +#include #include #include #include "engineer.h" @@ -23,7 +26,10 @@ Engineer::Engineer(int argc, char **argv): layout(catalogue), layout_3d(layout), no_lighting(false), - placing_train(0) + placing_train(0), + placing_block(0), + placing_entry(0), + simulate(false) { string res; bool debug=false; @@ -36,6 +42,7 @@ Engineer::Engineer(int argc, char **argv): getopt.add_option('g', "debug", debug, GetOpt::NO_ARG); getopt.add_option('d', "device", device, GetOpt::REQUIRED_ARG); getopt.add_option('q', "quality", quality, GetOpt::REQUIRED_ARG); + getopt.add_option('s', "simulate", simulate, GetOpt::NO_ARG); getopt.add_option( "no-lighting", no_lighting, GetOpt::NO_ARG); getopt(argc, argv); @@ -64,29 +71,17 @@ Engineer::Engineer(int argc, char **argv): throw UsageError("No layout given"); layout.load(args.front()); + control.signal_sensor_event.connect(sigc::mem_fun(this, &Engineer::sensor_event)); + trfc_mgr=new TrafficManager(control, layout); + trfc_mgr->signal_block_reserved.connect(sigc::mem_fun(this, &Engineer::block_reserved)); view_all(); - - /*const TrackSeq &tracks=layout.get_tracks(); - - for(TrackSeq::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) - { - if(unsigned trnt_id=(*i)->get_turnout_id()) - { - Turnout *trnt=new Turnout(control, trnt_id); - trnt->signal_route_changed.connect(sigc::mem_fun(this, &Engineer::turnout_route_changed)); - } - if(unsigned sens_id=(*i)->get_sensor_id()) - { - Sensor *sens=new Sensor(control, sens_id); - sens->signal_state_changed.connect(sigc::bind(sigc::mem_fun(this, &Engineer::sensor_state_changed), sens_id)); - } - }*/ } Engineer::~Engineer() { + delete trfc_mgr; } void Engineer::add_train(unsigned addr) @@ -96,6 +91,7 @@ void Engineer::add_train(unsigned addr) Locomotive *loco=new Locomotive(control, addr); Train *train=new Train(*trfc_mgr, *loco); + train->set_name(format("Train %d", trfc_mgr->get_trains().size())); TrainPanel *tpanel=new TrainPanel(*this, ui_res, *train); int y=main_panel->get_geometry().y; @@ -105,6 +101,8 @@ void Engineer::add_train(unsigned addr) train_panels.push_back(tpanel); placing_train=train; + placing_block=0; + status_text="Select train location"; } int Engineer::main() @@ -133,26 +131,15 @@ int Engineer::main() glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - font=new GL::Font(); - if(screen_w>=1024) - { - font_size=20; - Parser::load(*font, "dejavu-20.font"); - } - else - { - font_size=12; - Parser::load(*font, "dejavu-12.font"); - } - Parser::load(ui_res, "engineer.res"); main_panel=new MainPanel(*this, ui_res); main_panel->set_position(0, screen_h-main_panel->get_geometry().h); Application::main(); - delete font; delete main_panel; + for(TrainPanelSeq::iterator i=train_panels.begin(); i!=train_panels.end(); ++i) + delete *i; SDL_Quit(); @@ -230,6 +217,27 @@ void Engineer::tick() (*i)->render_route(-1); } + if(placing_train && placing_block) + { + float rot=placing_entry->track->get_rotation()+placing_entry->track_ep->rot; + Point pos=placing_entry->track->get_endpoint_position(*placing_entry->track_ep); + GL::push_matrix(); + GL::translate(pos.x, pos.y, pos.z+0.03); + GL::rotate(rot*180/M_PI+180, 0, 0, 1); + GL::Texture::unbind(); + glColor4f(1, 1, 1, 1); + glBegin(GL_TRIANGLE_FAN); + glVertex2f(0.08, 0); + glVertex2f(0.05, 0.03); + glVertex2f(0.05, 0.01); + glVertex2f(0, 0.01); + glVertex2f(0, -0.01); + glVertex2f(0.05, -0.01); + glVertex2f(0.05, -0.03); + glEnd(); + GL::pop_matrix(); + } + glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, screen_w, 0, screen_h, 0, 1); @@ -244,11 +252,12 @@ void Engineer::tick() for(TrainPanelSeq::iterator i=train_panels.begin(); i!=train_panels.end(); ++i) (*i)->render(); - glLoadIdentity(); - glTranslatef(340, 10, 0); - glScalef(20, 20, 20); + const GL::Font &font=ui_res.get_font("dejavu-12"); + GL::load_identity(); + GL::translate(340, 10, 0); + GL::scale_uniform(font.get_default_size()); glColor4f(1, 1, 1, 1); - font->draw_string(status_text); + font.draw_string(status_text); SDL_GL_SwapBuffers(); } @@ -271,18 +280,42 @@ void Engineer::button_press(int x, int y, unsigned btn) return; } - Track3D *track=pick_track(x, y); - if(track) + if(placing_train) { - if(placing_train) + if(btn==1 && placing_block) { - Block *block=trfc_man->get_block_by_track(&track->get_track()); + set_block_color(*placing_block, Color(1, 1, 1)); + + placing_train->place(placing_block, placing_entry); + placing_train=0; } - else + else if(btn==3) + { + const Block::EndpointSeq &endpoints=placing_block->get_endpoints(); + Block::EndpointSeq::const_iterator i; + for(i=endpoints.begin(); i!=endpoints.end(); ++i) + if(&*i==placing_entry) + break; + ++i; + if(i==endpoints.end()) + i=endpoints.begin(); + placing_entry=&*i; + } + } + else + { + Track3D *track=pick_track(x, y); + if(track) { Turnout *turnout=control.get_turnout(track->get_track().get_turnout_id()); if(turnout) turnout->set_route(1-turnout->get_route()); + else if(simulate) + { + Sensor *sensor=control.get_sensor(track->get_track().get_sensor_id()); + if(sensor) + control.signal_sensor_event.emit(track->get_track().get_sensor_id(), !sensor->get_state()); + } } } } @@ -317,13 +350,25 @@ void Engineer::pointer_motion(int x, int y) } Track3D *track=pick_track(x, y); - if(track && track->get_track().get_turnout_id()) + if(track && placing_train) + { + Block *block=trfc_mgr->get_block_by_track(&track->get_track()); + if(block!=placing_block) + { + if(placing_block) + set_block_color(*placing_block, Color(1, 1, 1)); + placing_block=block; + placing_entry=&block->get_endpoints().front(); + set_block_color(*placing_block, Color(0.5, 1, 0.7)); + } + } + else if(track && track->get_track().get_turnout_id()) { ostringstream ss; ss<<"Turnout "<get_track().get_turnout_id(); status_text=ss.str(); } - else + else if(!placing_train) status_text=""; } @@ -371,23 +416,39 @@ void Engineer::view_all() cam_pos.z=max(best_height*1.05/0.82843, 0.15); } -void Engineer::turnout_route_changed(unsigned) +void Engineer::set_block_color(const Block &block, const Color &color) { + const TrackSet &tracks=block.get_tracks(); + for(TrackSet::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) + layout_3d.get_track(*i)->set_color(color); } -void Engineer::sensor_state_changed(bool state, unsigned addr) +void Engineer::sensor_event(unsigned addr, bool state) { + cout<<"sensor_event "<get_track().get_sensor_id()==addr) { if(state) - (*i)->set_color(Color(1, 0, 0)); + (*i)->set_color(Color(1, 0.5, 0.3)); else (*i)->set_color(Color(1, 1, 1)); } } +void Engineer::block_reserved(const Block &block, const Train *train) +{ + if(Sensor *sensor=control.get_sensor(block.get_sensor_id())) + if(sensor->get_state()) + return; + + if(train) + set_block_color(block, Color(1, 1, 0.3)); + else + set_block_color(block, Color(1, 1, 1)); +} + void Engineer::project_3d() { glMatrixMode(GL_PROJECTION); @@ -410,76 +471,6 @@ Track3D *Engineer::pick_track(int x, int y) glTranslatef(-cam_pos.x, -cam_pos.y, -cam_pos.z); return layout_3d.pick_track(xx, yy, size); - - /*unsigned select_buf[1024]; - glSelectBuffer(1024, select_buf); - glRenderMode(GL_SELECT); - - //XXX Hardcoded values - float xn=((float)(x-800)/960)*0.082843; - float yn=((float)(y-480)/960)*0.082843; - float size=(float)4/960*0.082843; - - project_3d(); - glLoadIdentity(); - - double clip[4]; - clip[0]=0.1; - clip[1]=0; - clip[2]=xn-size; - clip[3]=0; - glClipPlane(GL_CLIP_PLANE0, clip); - glEnable(GL_CLIP_PLANE0); - - clip[0]=-0.1; - clip[2]=-(xn+size); - glClipPlane(GL_CLIP_PLANE1, clip); - glEnable(GL_CLIP_PLANE1); - - clip[0]=0; - clip[1]=0.1; - clip[2]=yn-size; - glClipPlane(GL_CLIP_PLANE2, clip); - glEnable(GL_CLIP_PLANE2); - - clip[1]=-0.1; - clip[2]=-(yn+size); - glClipPlane(GL_CLIP_PLANE3, clip); - glEnable(GL_CLIP_PLANE3); - - glRotatef(-cam_rot*180/M_PI, 0, 0, 1); - glTranslatef(-cam_pos.x, -cam_pos.y, -cam_pos.z); - - layout_3d.render(); - - glDisable(GL_CLIP_PLANE0); - glDisable(GL_CLIP_PLANE1); - glDisable(GL_CLIP_PLANE2); - glDisable(GL_CLIP_PLANE3); - - unsigned n_records=glRenderMode(GL_RENDER); - if(n_records) - { - Track *track=0; - unsigned i=0; - unsigned track_depth=numeric_limits::max(); - for(unsigned j=0; j Engineer::reg; diff --git a/source/engineer/engineer.h b/source/engineer/engineer.h index 112e52f..ac5ce2c 100644 --- a/source/engineer/engineer.h +++ b/source/engineer/engineer.h @@ -7,6 +7,7 @@ #include "libmarklin/catalogue.h" #include "libmarklin/control.h" #include "libmarklin/trafficmanager.h" +#include "libmarklin/train.h" #include "3d/layout.h" class MainPanel; @@ -19,10 +20,6 @@ public: ~Engineer(); Marklin::Control &get_control() { return control; } - unsigned get_screen_width() const { return screen_w; } - unsigned get_screen_height() const { return screen_h; } - unsigned get_font_size() const { return font_size; } - Msp::GL::Font &get_font() { return *font; } void add_train(unsigned); int main(); void quit() { exit(0); } @@ -31,9 +28,7 @@ private: unsigned screen_w; unsigned screen_h; - unsigned font_size; bool fullscreen; - Msp::GL::Font *font; Marklin::Catalogue catalogue; Marklin::Layout layout; Marklin::Layout3D layout_3d; @@ -46,7 +41,10 @@ private: std::string status_text; bool no_lighting; Marklin::TrafficManager *trfc_mgr; - Train *placing_train; + Marklin::Train *placing_train; + Marklin::Block *placing_block; + const Marklin::Block::Endpoint *placing_entry; + bool simulate; void tick(); void key_press(unsigned, unsigned); @@ -54,8 +52,9 @@ private: void button_release(int, int, unsigned); void pointer_motion(int, int); void view_all(); - void turnout_route_changed(unsigned); - void sensor_state_changed(bool, unsigned); + void set_block_color(const Marklin::Block &, const Marklin::Color &); + void sensor_event(unsigned, bool); + void block_reserved(const Marklin::Block &, const Marklin::Train *); void project_3d(); Marklin::Track3D *pick_track(int, int); diff --git a/source/engineer/mainpanel.cpp b/source/engineer/mainpanel.cpp index 7e68c03..c471b96 100644 --- a/source/engineer/mainpanel.cpp +++ b/source/engineer/mainpanel.cpp @@ -13,7 +13,7 @@ MainPanel::MainPanel(Engineer &e, GLtk::Resources &r): GLtk::Button *btn; add(*(btn=new GLtk::Button(res, "Off"))); - btn->set_geometry(GLtk::Geometry(10, 50, 40, 25)); + btn->set_geometry(GLtk::Geometry(10, 53, 40, 25)); btn->set_style("red"); btn->signal_clicked.connect(sigc::mem_fun(this, &MainPanel::power_off)); @@ -22,7 +22,7 @@ MainPanel::MainPanel(Engineer &e, GLtk::Resources &r): ind_off->set_style("red"); add(*(btn=new GLtk::Button(res, "On"))); - btn->set_geometry(GLtk::Geometry(50, 50, 40, 25)); + btn->set_geometry(GLtk::Geometry(50, 53, 40, 25)); btn->set_style("green"); btn->signal_clicked.connect(sigc::mem_fun(this, &MainPanel::power_on)); @@ -31,7 +31,7 @@ MainPanel::MainPanel(Engineer &e, GLtk::Resources &r): ind_on->set_style("green"); add(*(btn=new GLtk::Button(res, "Quit"))); - btn->set_geometry(GLtk::Geometry(150, 50, 40, 25)); + btn->set_geometry(GLtk::Geometry(150, 53, 40, 25)); btn->set_style("red"); btn->signal_clicked.connect(sigc::mem_fun(this, &MainPanel::quit)); diff --git a/source/engineer/trainpanel.cpp b/source/engineer/trainpanel.cpp index d9a8c77..d46bd9d 100644 --- a/source/engineer/trainpanel.cpp +++ b/source/engineer/trainpanel.cpp @@ -1,4 +1,6 @@ #include +#include +#include "libmarklin/locomotive.h" #include "trainpanel.h" using namespace Msp; @@ -11,9 +13,10 @@ TrainPanel::TrainPanel(Engineer &e, const GLtk::Resources &r, Train &t): { set_size(200, 100); - add(*(lbl_name=new GLtk::Label(res, "Train 1"))); + add(*(lbl_name=new GLtk::Label(res, train.get_name()))); lbl_name->set_style("digital"); lbl_name->set_geometry(GLtk::Geometry(10, geom.h-34, 140, 24)); + train.signal_name_changed.connect(sigc::mem_fun(lbl_name, &GLtk::Label::set_text)); GLtk::Button *btn; @@ -26,11 +29,18 @@ TrainPanel::TrainPanel(Engineer &e, const GLtk::Resources &r, Train &t): sld_speed->set_step(1); sld_speed->signal_value_changed.connect(sigc::mem_fun(this, &TrainPanel::speed_slider_changed)); - add(*(btn=new GLtk::Button(res, "Place"))); - btn->set_geometry(GLtk::Geometry(150, geom.h-75, 40, 24)); + add(*(lbl_speed=new GLtk::Label(res, " 0"))); + lbl_speed->set_style("digital"); + lbl_speed->set_geometry(GLtk::Geometry(10, geom.h-75, 36, 24)); + train.get_locomotive().signal_speed_changed.connect(sigc::mem_fun(this, &TrainPanel::loco_speed_changed)); } void TrainPanel::speed_slider_changed(double v) { train.set_speed(static_cast(v)); } + +void TrainPanel::loco_speed_changed(unsigned speed) +{ + lbl_speed->set_text(format("%2d", speed)); +} diff --git a/source/engineer/trainpanel.h b/source/engineer/trainpanel.h index 79b9d49..5abec3b 100644 --- a/source/engineer/trainpanel.h +++ b/source/engineer/trainpanel.h @@ -18,8 +18,10 @@ private: Msp::GLtk::Label *lbl_name; Msp::GLtk::HSlider *sld_speed; Marklin::Locomotive *loco; + Msp::GLtk::Label *lbl_speed; void speed_slider_changed(double); + void loco_speed_changed(unsigned); }; #endif diff --git a/source/libmarklin/block.cpp b/source/libmarklin/block.cpp index f96e295..b3a96e6 100644 --- a/source/libmarklin/block.cpp +++ b/source/libmarklin/block.cpp @@ -93,7 +93,7 @@ const Block::Endpoint *Block::traverse(const Endpoint *ep) const if(i->track==track && i->track_ep==other_ep) return &*i; - track_ep=track->get_endpoint_by_link(other_ep->link); + track_ep=other_ep->link->get_endpoint_by_link(track); track=other_ep->link; if(tracks.count(track)==0) @@ -122,6 +122,8 @@ bool Block::reserve(const Train *t) if(!t || !train) { train=t; + cout<<"Block "< #include @@ -27,6 +27,7 @@ public: Block(TrafficManager &, Track *); unsigned get_sensor_id() const { return sensor_id; } const TrackSet &get_tracks() const { return tracks; } + const EndpointSeq &get_endpoints() const { return endpoints; } const Endpoint *get_endpoint_by_link(const Block *) const; const Endpoint *traverse(const Endpoint *) const; void check_link(Block &); diff --git a/source/libmarklin/control.cpp b/source/libmarklin/control.cpp index d371777..0ce16f0 100644 --- a/source/libmarklin/control.cpp +++ b/source/libmarklin/control.cpp @@ -205,6 +205,12 @@ void Control::tick() Control::~Control() { + for(SensorMap::iterator i=sensors.begin(); i!=sensors.end(); ++i) + delete i->second; + for(TurnoutMap::iterator i=turnouts.begin(); i!=turnouts.end(); ++i) + delete i->second; + for(LocomotiveSeq::iterator i=locomotives.begin(); i!=locomotives.end(); ++i) + delete *i; close(serial_fd); } diff --git a/source/libmarklin/locomotive.cpp b/source/libmarklin/locomotive.cpp index ecacea1..6329196 100644 --- a/source/libmarklin/locomotive.cpp +++ b/source/libmarklin/locomotive.cpp @@ -27,6 +27,8 @@ void Locomotive::set_speed(unsigned spd) speed=min(spd, 14U); send_command(false); + + signal_speed_changed.emit(speed); } void Locomotive::set_reverse(bool rev) @@ -62,7 +64,7 @@ void Locomotive::refresh_status() cmd[0]=CMD_LOK_STATUS; cmd[1]=addr&0xFF; cmd[2]=(addr>>8)&0xFF; - control.command(string(cmd,3)).signal_done.connect(sigc::mem_fun(this,&Locomotive::status_reply)); + control.command(string(cmd, 3)).signal_done.connect(sigc::mem_fun(this, &Locomotive::status_reply)); } void Locomotive::send_command(bool setf) diff --git a/source/libmarklin/locomotive.h b/source/libmarklin/locomotive.h index 68e1330..7142701 100644 --- a/source/libmarklin/locomotive.h +++ b/source/libmarklin/locomotive.h @@ -3,6 +3,7 @@ #include #include +#include #include "constants.h" namespace Marklin { @@ -12,6 +13,8 @@ class Control; class Locomotive { public: + sigc::signal signal_speed_changed; + Locomotive(Control &, unsigned); void set_speed(unsigned); void set_reverse(bool); diff --git a/source/libmarklin/track.cpp b/source/libmarklin/track.cpp index aaf1b75..6f83e5b 100644 --- a/source/libmarklin/track.cpp +++ b/source/libmarklin/track.cpp @@ -59,6 +59,13 @@ const Track::Endpoint *Track::get_endpoint_by_link(Track *other) const return 0; } +Point Track::get_endpoint_position(const Endpoint &ep) const +{ + float c=cos(rot); + float s=sin(rot); + return Point(pos.x+c*ep.pos.x-s*ep.pos.y, pos.y+s*ep.pos.x+c*ep.pos.y, pos.z+ep.pos.z); +} + float Track::get_length() const { float len=parts.front().length; @@ -94,21 +101,19 @@ bool Track::snap_to(Track &other, bool link) float limit=(link && !flex) ? 1e-6 : 1e-4; for(EndpointSeq::iterator i=endpoints.begin(); i!=endpoints.end(); ++i) { - float x=pos.x+i->pos.x*cos(rot)-i->pos.y*sin(rot); - float y=pos.y+i->pos.y*cos(rot)+i->pos.x*sin(rot); + Point epp=get_endpoint_position(*i); for(EndpointSeq::iterator j=other.endpoints.begin(); j!=other.endpoints.end(); ++j) { if(j->link) continue; - float x2=other.pos.x+j->pos.x*cos(other.rot)-j->pos.y*sin(other.rot); - float y2=other.pos.y+j->pos.y*cos(other.rot)+j->pos.x*sin(other.rot); - float dx=x2-x; - float dy=y2-y; + Point epp2=other.get_endpoint_position(*j); + float dx=epp2.x-epp.x; + float dy=epp2.y-epp.y; if(dx*dx+dy*dyrot-i->rot+M_PI); - set_position(Point(x2-(i->pos.x*cos(rot)-i->pos.y*sin(rot)), y2-(i->pos.y*cos(rot)+i->pos.x*sin(rot)), other.pos.z+j->pos.z-i->pos.z)); + set_position(Point(epp2.x-(i->pos.x*cos(rot)-i->pos.y*sin(rot)), epp2.y-(i->pos.y*cos(rot)+i->pos.x*sin(rot)), other.pos.z+j->pos.z-i->pos.z)); if(link) { if(i->link) @@ -128,14 +133,12 @@ bool Track::snap(Point &pt, float &d) const { for(EndpointSeq::const_iterator i=endpoints.begin(); i!=endpoints.end(); ++i) { - float x=pos.x+i->pos.x*cos(rot)-i->pos.y*sin(rot); - float y=pos.y+i->pos.y*cos(rot)+i->pos.x*sin(rot); - float dx=pt.x-x; - float dy=pt.y-y; + Point epp=get_endpoint_position(*i); + float dx=pt.x-epp.x; + float dy=pt.y-epp.y; if(dx*dx+dy*dy<1e-4) { - pt.x=x; - pt.y=y; + pt=epp; d=rot+i->rot; return true; } diff --git a/source/libmarklin/track.h b/source/libmarklin/track.h index 9345f03..6bddd4d 100644 --- a/source/libmarklin/track.h +++ b/source/libmarklin/track.h @@ -75,6 +75,7 @@ public: const PartSeq &get_parts() const { return parts; } const EndpointSeq &get_endpoints() const { return endpoints; } const Endpoint *get_endpoint_by_link(Track *) const; + Point get_endpoint_position(const Endpoint &) const; const std::string &get_description() const { return description; } float get_slope() const { return slope; } bool get_flex() const { return flex; } diff --git a/source/libmarklin/trafficmanager.cpp b/source/libmarklin/trafficmanager.cpp index 31e8542..516f64f 100644 --- a/source/libmarklin/trafficmanager.cpp +++ b/source/libmarklin/trafficmanager.cpp @@ -46,6 +46,14 @@ TrafficManager::TrafficManager(Control &c, Layout &l): } } +TrafficManager::~TrafficManager() +{ + for(BlockSeq::iterator i=blocks.begin(); i!=blocks.end(); ++i) + delete *i; + for(TrainSeq::iterator i=trains.begin(); i!=trains.end(); ++i) + delete *i; +} + Block *TrafficManager::get_block_by_track(const Track *t) const { for(BlockSeq::const_iterator i=blocks.begin(); i!=blocks.end(); ++i) diff --git a/source/libmarklin/trafficmanager.h b/source/libmarklin/trafficmanager.h index 6e210bc..83b03e2 100644 --- a/source/libmarklin/trafficmanager.h +++ b/source/libmarklin/trafficmanager.h @@ -13,9 +13,14 @@ class Turnout; class TrafficManager { public: + sigc::signal signal_block_reserved; + TrafficManager(Control &, Layout &); + ~TrafficManager(); + Control &get_control() const { return control; } Block *get_block_by_track(const Track *) const; + const TrainSeq &get_trains() const { return trains; } void add_train(Train *); private: Control &control; diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index f69849d..fed1438 100644 --- a/source/libmarklin/train.cpp +++ b/source/libmarklin/train.cpp @@ -2,6 +2,9 @@ #include "trafficmanager.h" #include "train.h" +#include +using namespace std; + namespace Marklin { Train::Train(TrafficManager &tm, Locomotive &l): @@ -13,6 +16,13 @@ Train::Train(TrafficManager &tm, Locomotive &l): trfc_mgr.get_control().signal_sensor_event.connect(sigc::mem_fun(this, &Train::sensor_event)); } +void Train::set_name(const string &n) +{ + name=n; + + signal_name_changed.emit(name); +} + void Train::set_speed(unsigned speed) { target_speed=speed; @@ -59,13 +69,18 @@ bool Train::free_block(Block *block) void Train::sensor_event(unsigned addr, bool state) { + if(!loco.get_speed()) + return; + if(state) { BlockRefSeq::iterator i; for(i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i) if(i->block->get_sensor_id() && i->block->get_sensor_id()!=addr) break; - cur_blocks.splice(cur_blocks.begin(), rsv_blocks, rsv_blocks.begin(), i); + cur_blocks.splice(cur_blocks.end(), rsv_blocks, rsv_blocks.begin(), i); + + cout<<"Train advanced, "<block->get_sensor_id()==addr) break; if(i!=cur_blocks.end()) { + cout<<"found\n"; ++i; for(BlockRefSeq::iterator j=cur_blocks.begin(); j!=i; ++j) j->block->reserve(0); cur_blocks.erase(cur_blocks.begin(), i); + cout<block->traverse(last->entry); - if(exit->link->reserve(this)) + if(exit && exit->link->reserve(this)) { rsv_blocks.push_back(BlockRef(exit->link, exit->link->get_endpoint_by_link(last->block))); last=&rsv_blocks.back(); diff --git a/source/libmarklin/train.h b/source/libmarklin/train.h index 96f4870..23bd3cc 100644 --- a/source/libmarklin/train.h +++ b/source/libmarklin/train.h @@ -1,6 +1,7 @@ #ifndef LIBMARKLIN_TRAIN_H_ #define LIBMARKLIN_TRAIN_H_ +#include #include #include "block.h" @@ -12,9 +13,13 @@ class TrafficManager; class Train: public sigc::trackable { public: + sigc::signal signal_name_changed; + Train(TrafficManager &, Locomotive &); - const std::string &get_name() const { return name; } + void set_name(const std::string &); void set_speed(unsigned); + const std::string &get_name() const { return name; } + Locomotive &get_locomotive() const { return loco; } void place(Block *, const Block::Endpoint *); bool free_block(Block *); void tick(); -- 2.43.0