]> git.tdb.fi Git - r2c2.git/commitdiff
Add Track::get_endpoint_position to avoid duplicating calculations
authorMikko Rasa <tdb@tdb.fi>
Sun, 15 Jul 2007 10:59:20 +0000 (10:59 +0000)
committerMikko Rasa <tdb@tdb.fi>
Sun, 15 Jul 2007 10:59:20 +0000 (10:59 +0000)
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

17 files changed:
source/designer/designer.cpp
source/engineer/engineer.cpp
source/engineer/engineer.h
source/engineer/mainpanel.cpp
source/engineer/trainpanel.cpp
source/engineer/trainpanel.h
source/libmarklin/block.cpp
source/libmarklin/block.h
source/libmarklin/control.cpp
source/libmarklin/locomotive.cpp
source/libmarklin/locomotive.h
source/libmarklin/track.cpp
source/libmarklin/track.h
source/libmarklin/trafficmanager.cpp
source/libmarklin/trafficmanager.h
source/libmarklin/train.cpp
source/libmarklin/train.h

index eb5a0efca455ecd40379ddd34e5c0ca3af2e6c68..d0bc940b4cea510e57083dd00e204c0d38f7aea6 100644 (file)
@@ -36,9 +36,7 @@ Designer::Designer(int argc, char **argv):
        rotate(0),
        pitch(0)
 {
-       cout<<"blah?\n";
        catalogue.load("tracks.dat");
-       cout<<catalogue.get_tracks().size()<<'\n';
 
        cat_layout=new Layout(catalogue);
        cat_layout_3d=new Layout3D(*cat_layout);
@@ -99,7 +97,7 @@ int Designer::main()
        glEnable(GL_CULL_FACE);
 
        font=new GL::Font();
-       Parser::load(*font, "dejavu.font");
+       Parser::load(*font, "dejavu-20.font");
 
        mode=SELECT;
 
index bb29591094fae7e8852f2438ada6eb39d8267fe6..ab95d02ff25a636d786a6960dfb61dc58cddeaa0 100644 (file)
@@ -4,6 +4,9 @@
 #include <GL/gl.h>
 #include <msp/core/error.h>
 #include <msp/core/getopt.h>
+#include <msp/gl/matrix.h>
+#include <msp/gl/transform.h>
+#include <msp/strings/formatter.h>
 #include <msp/strings/lexicalcast.h>
 #include <msp/strings/regex.h>
 #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 "<<track->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 "<<state<<" @ "<<addr<<'\n';
        const Track3DSeq &ltracks=layout_3d.get_tracks();
        for(Track3DSeq::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
                if((*i)->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<unsigned>::max();
-               for(unsigned j=0; j<n_records; ++j)
-               {
-                       unsigned ns_size=select_buf[i++];
-                       unsigned min_depth=select_buf[i++];
-                       ++i;  // Skip max_depth
-                       if(min_depth<track_depth)
-                       {
-                               track=(Track *)select_buf[i+ns_size-1];
-                               track_depth=min_depth;
-                       }
-                       i+=ns_size;
-               }
-
-               return track;
-       }
-
-       return 0;*/
 }
 
 Application::RegApp<Engineer> Engineer::reg;
index 112e52f3a0209277cdda571d158abc235e147c6c..ac5ce2c94d45d3b1fbef42162e075d71a5ccea9e 100644 (file)
@@ -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);
 
index 7e68c03d87ae7e6393d8b338510abedfe16851f9..c471b962d0c26ebf68fa0227fedd42ccecbfd0ec 100644 (file)
@@ -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));
 
index d9a8c7752bb8ff58467fc9110c8f1ba9001b7dd7..d46bd9d4756ca8c229eb92e7a3df64aadab87ae1 100644 (file)
@@ -1,4 +1,6 @@
 #include <msp/gltk/button.h>
+#include <msp/strings/formatter.h>
+#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<unsigned>(v));
 }
+
+void TrainPanel::loco_speed_changed(unsigned speed)
+{
+       lbl_speed->set_text(format("%2d", speed));
+}
index 79b9d490456b6ede1d71290bd5de517c6d166eec..5abec3b443e24941160ee525aa91a1f0b0bc0271 100644 (file)
@@ -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
index f96e295a13a75f1962bfd149ccd59dbac41a3796..b3a96e67f4f59850c58a599c92eced8dc70d96c4 100644 (file)
@@ -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 "<<this<<" reserved for train "<<train<<'\n';
+               trfc_mgr.signal_block_reserved.emit(*this, train);
                return true;
        }
        else
index df3ed4a525444271c931d4dd02a6c4e70dd5d63b..4a22aa97862bfc2019890aefc8090f83e7114ea9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef MARKLIN_3D_SECTION_H_
-#define MARKLIN_3D_SECTION_H_
+#ifndef MARKLIN_3D_BLOCK_H_
+#define MARKLIN_3D_BLOCK_H_
 
 #include <list>
 #include <set>
@@ -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 &);
index d371777fc5ca15d58478c001649732d038d33737..0ce16f088740524490e2f891b3d62561f588a309 100644 (file)
@@ -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);
 }
 
index ecacea19a833af43f918823523951740d9a0e69c..6329196710583014bc76ee80028daf476bb77ef7 100644 (file)
@@ -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)
index 68e1330efd3451fd9472acc746b179e1362a0670..7142701a28e3c5d9e6d5552db523ba00c469e18f 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <list>
 #include <string>
+#include <sigc++/signal.h>
 #include "constants.h"
 
 namespace Marklin {
@@ -12,6 +13,8 @@ class Control;
 class Locomotive
 {
 public:
+       sigc::signal<void, unsigned> signal_speed_changed;
+
        Locomotive(Control &, unsigned);
        void     set_speed(unsigned);
        void     set_reverse(bool);
index aaf1b75526b1564eb3b2aa6257ea930c41f9cc48..6f83e5b05238080c63a95fdbcd9d5182661f86f7 100644 (file)
@@ -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*dy<limit)
                        {
                                set_rotation(other.rot+j->rot-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;
                }
index 9345f0363ffca4f7be40880fc91db6d1717418bc..6bddd4dad01518676062db707caab0b173d19ff9 100644 (file)
@@ -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; }
index 31e854231c89ae8cad3b7fa69106690ebe0b1e87..516f64fd0b00741ea65ee2572cbec2e501d44afc 100644 (file)
@@ -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)
index 6e210bcf1f8a75430cfea680cd7f774bf8bd0b07..83b03e2ec8c4684af75ab4adf5ca49d2d80321cd 100644 (file)
@@ -13,9 +13,14 @@ class Turnout;
 class TrafficManager
 {
 public:
+       sigc::signal<void, const Block &, const Train *> 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;
index f69849db54a81cd65db4448d569ead98e4c241e8..fed1438b02cf064610c21c793b4b156842fce36b 100644 (file)
@@ -2,6 +2,9 @@
 #include "trafficmanager.h"
 #include "train.h"
 
+#include <iostream>
+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, "<<cur_blocks.size()<<" cur_blocks, "<<rsv_blocks.size()<<" rsv_blocks\n";
 
                reserve_more();
                if(rsv_blocks.empty())
@@ -73,16 +88,19 @@ void Train::sensor_event(unsigned addr, bool state)
        }
        else
        {
+               cout<<"Finding blocks to free\n";
                BlockRefSeq::iterator i;
                for(i=cur_blocks.begin(); i!=cur_blocks.end(); ++i)
                        if(i->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<<cur_blocks.size()<<" cur_blocks\n";
                }
 
                reserve_more();
@@ -104,7 +122,7 @@ bool Train::reserve_more()
        while(size<5)
        {
                const Block::Endpoint *exit=last->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();
index 96f487066fb7e6ef5affa1228d8502c2fe35e5fb..23bd3cc1b09405fedfae44d62af17e10a40a8f6b 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef LIBMARKLIN_TRAIN_H_
 #define LIBMARKLIN_TRAIN_H_
 
+#include <sigc++/signal.h>
 #include <sigc++/trackable.h>
 #include "block.h"
 
@@ -12,9 +13,13 @@ class TrafficManager;
 class Train: public sigc::trackable
 {
 public:
+       sigc::signal<void, const std::string &> 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();