]> git.tdb.fi Git - r2c2.git/commitdiff
Major code refactoring:
authorMikko Rasa <tdb@tdb.fi>
Fri, 30 May 2008 09:54:26 +0000 (09:54 +0000)
committerMikko Rasa <tdb@tdb.fi>
Fri, 30 May 2008 09:54:26 +0000 (09:54 +0000)
- Remove container typedefs
- Separate TrackType from Track
- Use indices instead of pointers for endpoints
- Make certain functions return references and throw on error
Compatibility fixes with msp libraries

45 files changed:
Build
source/3d/layout.cpp
source/3d/layout.h
source/3d/track.cpp
source/3d/track.h
source/designer/designer.cpp
source/designer/designer.h
source/designer/manipulator.cpp
source/designer/manipulator.h
source/designer/measure.cpp
source/designer/selection.cpp
source/designer/selection.h
source/engineer/engineer.cpp
source/engineer/engineer.h
source/engineer/trainpanel.cpp
source/engineer/trainpanel.h
source/engineer/trainproperties.cpp
source/engineer/trainproperties.h
source/libmarklin/block.cpp
source/libmarklin/block.h
source/libmarklin/catalogue.cpp
source/libmarklin/catalogue.h
source/libmarklin/control.cpp
source/libmarklin/control.h
source/libmarklin/endpoint.h [new file with mode: 0644]
source/libmarklin/layout.cpp
source/libmarklin/layout.h
source/libmarklin/locomotive.cpp
source/libmarklin/locomotive.h
source/libmarklin/route.h
source/libmarklin/sensor.cpp
source/libmarklin/sensor.h
source/libmarklin/track.cpp
source/libmarklin/track.h
source/libmarklin/trackpart.cpp [new file with mode: 0644]
source/libmarklin/trackpart.h [new file with mode: 0644]
source/libmarklin/tracktype.cpp [new file with mode: 0644]
source/libmarklin/tracktype.h [new file with mode: 0644]
source/libmarklin/trafficmanager.cpp
source/libmarklin/trafficmanager.h
source/libmarklin/train.cpp
source/libmarklin/train.h
source/libmarklin/turnout.cpp
source/libmarklin/turnout.h
source/shoppinglist/main.cpp

diff --git a/Build b/Build
index df11fe0df6c3c7a2119b0c4c744e75bee1f6243b..4d5196158eb925f51bc4705a104d91a9cb9b6ab6 100644 (file)
--- a/Build
+++ b/Build
@@ -6,13 +6,13 @@ package "märklin"
        program "shoppinglist"
        {
                source "source/shoppinglist";
-               require "mspparser";
+               require "mspdatafile";
        };
 
        library "marklin"
        {
                source "source/libmarklin";
-               require "mspparser";
+               require "mspdatafile";
        };
 
        library "marklin3d"
index b90f553fff3bd1002146a4bdc3611c04eaeb7f35..18457f095bf6aac4a0085e8400d94b5c3fdaceff 100644 (file)
@@ -3,7 +3,7 @@
 #include <msp/gl/rendermode.h>
 #include <msp/gl/select.h>
 #include <msp/gl/texture.h>
-#include <msp/parser/parser.h>
+#include <msp/datafile/parser.h>
 #include "layout.h"
 
 using namespace std;
@@ -113,15 +113,15 @@ Track3D *Layout3D::pick_track(float x, float y, float size)
        return track;
 }
 
-void Layout3D::track_added(Track *t)
+void Layout3D::track_added(Track &t)
 {
-       tracks.push_back(new Track3D(*t, quality));
+       tracks.push_back(new Track3D(t, quality));
 }
 
-void Layout3D::track_removed(Track *t)
+void Layout3D::track_removed(Track &t)
 {
        for(Track3DSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
-               if(&(*i)->get_track()==t)
+               if(&(*i)->get_track()==&t)
                {
                        delete *i;
                        tracks.erase(i);
index 09189ed82969df8b69d3bf1682b6387fb1119211..99706047815f6f454bfb0dc72b70b3fbbacd7856 100644 (file)
@@ -22,8 +22,8 @@ private:
        Track3DSeq tracks;
        unsigned   quality;
 
-       void track_added(Track *);
-       void track_removed(Track *);
+       void track_added(Track &);
+       void track_removed(Track &);
 };
 
 } // namespace Marklin
index e64f42ed3dde6394fde1749979f24e163f57ba5a..d9370844e8ae24cb0f061777dd1e00d0381fce0e 100644 (file)
@@ -1,6 +1,7 @@
 #include <cmath>
 #include <GL/gl.h>
 #include <msp/gl/misc.h>
+#include "libmarklin/tracktype.h"
 #include "track.h"
 
 using namespace std;
@@ -74,24 +75,24 @@ void Track3D::render_endpoints()
 {
        prepare_render();
 
-       const Point &pos=track.get_position();
-       const Track::EndpointSeq &endpoints=track.get_endpoints();
-       for(Track::EndpointSeq::const_iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
+       const vector<Endpoint> &endpoints=track.get_type().get_endpoints();
+       for(unsigned i=0; i<endpoints.size(); ++i)
        {
-               GL::set(GL_CULL_FACE, i->link);
-               if(i->link)
+               const Endpoint &ep=endpoints[i];
+               GL::set(GL_CULL_FACE, track.get_link(i));
+               if(track.get_link(i))
                        glColor4f(0.5, 0, 1, 0.5);
                else
                        glColor4f(1, 0, 0.5, 0.5);
 
-               float c=cos(i->rot);
-               float s=sin(i->rot);
+               float c=cos(ep.dir);
+               float s=sin(ep.dir);
 
                glBegin(GL_QUADS);
-               glVertex3f(i->pos.x-s*0.025, i->pos.y+c*0.025, 0);
-               glVertex3f(i->pos.x+s*0.025, i->pos.y-c*0.025, 0);
-               glVertex3f(i->pos.x+s*0.025, i->pos.y-c*0.025, pos.z+i->pos.z+0.02);
-               glVertex3f(i->pos.x-s*0.025, i->pos.y+c*0.025, pos.z+i->pos.z+0.02);
+               glVertex3f(ep.x-s*0.025, ep.y+c*0.025, 0);
+               glVertex3f(ep.x+s*0.025, ep.y-c*0.025, 0);
+               glVertex3f(ep.x+s*0.025, ep.y-c*0.025, 0.02);
+               glVertex3f(ep.x-s*0.025, ep.y+c*0.025, 0.02);
                glEnd();
        }
 
@@ -132,15 +133,15 @@ void Track3D::build_object()
        base_seq.clear();
        rail_seq.clear();
        route_seq.clear();
-       route_seq.resize(track.get_n_routes());
+       route_seq.resize(track.get_type().get_n_routes());
 
-       const Track::PartSeq &parts=track.get_parts();
+       const vector<TrackPart> &parts=track.get_type().get_parts();
        unsigned index=0;
-       for(Track::PartSeq::const_iterator i=parts.begin(); i!=parts.end(); ++i)
+       for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
                build_part(*i, *builder, index);
 }
 
-void Track3D::build_part(const Track::Part &part, GL::VertexArrayBuilder &va_builder, unsigned &base_index)
+void Track3D::build_part(const TrackPart &part, GL::VertexArrayBuilder &va_builder, unsigned &base_index)
 {
        static vector<Point> profile;
        if(profile.empty())
index f38593ec08e2ee3e169e534c7243d19f2c02770f..a9154b7c6bbb628fb486d7d934601224a03a37ce 100644 (file)
@@ -3,7 +3,9 @@
 
 #include <list>
 #include <msp/gl/vertexarray.h>
+#include <msp/gl/vertexarraybuilder.h>
 #include "libmarklin/track.h"
+#include "libmarklin/trackpart.h"
 #include "misc.h"
 
 namespace Marklin {
@@ -31,7 +33,7 @@ private:
 
        void prepare_render();
        void build_object();
-       void build_part(const Track::Part &, Msp::GL::VertexArrayBuilder &, unsigned &);
+       void build_part(const TrackPart &, Msp::GL::VertexArrayBuilder &, unsigned &);
 };
 typedef std::list<Track3D *> Track3DSeq;
 
index d0bc940b4cea510e57083dd00e204c0d38f7aea6..9edf816afcdef1ec7a557b42a9617c586777f3a4 100644 (file)
@@ -5,12 +5,14 @@
 #include <SDL.h>
 #include <msp/gl/rendermode.h>
 #include <msp/gl/select.h>
+#include <msp/gl/texture2d.h>
 #include <msp/strings/codec.h>
 #include <msp/strings/lexicalcast.h>
 #include <msp/strings/utf8.h>
 #include <msp/strings/utils.h>
 #include <msp/time/units.h>
 #include <msp/time/utils.h>
+#include "libmarklin/tracktype.h"
 #include "designer.h"
 #include "input.h"
 #include "manipulator.h"
@@ -41,14 +43,14 @@ Designer::Designer(int argc, char **argv):
        cat_layout=new Layout(catalogue);
        cat_layout_3d=new Layout3D(*cat_layout);
 
-       const Catalogue::TrackMap &ctracks=catalogue.get_tracks();
+       const map<unsigned, TrackType *> &ctracks=catalogue.get_tracks();
        unsigned n=0;
-       for(Catalogue::TrackMap::const_iterator i=ctracks.begin(); i!=ctracks.end(); ++i, ++n)
+       for(map<unsigned, TrackType *>::const_iterator i=ctracks.begin(); i!=ctracks.end(); ++i, ++n)
        {
-               Track *track=i->second->copy();
+               Track *track=new Track(*i->second);
                track->set_position(Point((n%11)*0.1-0.5, 0.2-n/11*0.3, 0));
                track->set_rotation(M_PI/2);
-               cat_layout->add_track(track);
+               cat_layout->add_track(*track);
        }
 
        manipulator=new Manipulator(*this);
@@ -96,14 +98,19 @@ int Designer::main()
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glEnable(GL_CULL_FACE);
 
+       GL::Texture2D *font_tex=new GL::Texture2D;
+       font_tex->set_min_filter(GL::LINEAR);
+       font_tex->load_image("dejavu-20.png");
        font=new GL::Font();
-       Parser::load(*font, "dejavu-20.font");
+       font->set_texture(*font_tex);
+       DataFile::load(*font, "dejavu-20.font");
 
        mode=SELECT;
 
        Application::main();
 
        delete font;
+       delete font_tex;
        delete input;
 
        SDL_Quit();
@@ -224,21 +231,22 @@ void Designer::tick()
                if(t3d)
                {
                        const Track &track=t3d->get_track();
+                       const TrackType &ttype=track.get_type();
                        ostringstream ss;
                        ss.precision(2);
-                       ss<<track.get_article_number()<<' '<<track.get_description();
+                       ss<<ttype.get_article_number()<<' '<<ttype.get_description();
                        if(mode!=CATALOGUE)
-                               ss<<" (slope "<<track.get_slope()/track.get_length()*100<<"%)";
+                               ss<<" (slope "<<track.get_slope()/ttype.get_total_length()*100<<"%)";
                        if(track.get_turnout_id())
                                ss<<" (turnout "<<track.get_turnout_id()<<')';
                        else if(track.get_sensor_id())
                                ss<<" (sensor "<<track.get_sensor_id()<<')';
-                       tooltip=decode<Utf8>(ss.str());
+                       tooltip=ss.str();
 
                        move_tooltip(pointer_x, pointer_y);
                }
                else
-                       tooltip=L"";
+                       tooltip="";
 
                tooltip_timeout=Time::TimeStamp();
        }
@@ -301,10 +309,10 @@ void Designer::key_press(unsigned key, unsigned mod, wchar_t ch)
                selection->select_more();
        else if(key==SDLK_l && (mod&KMOD_SHIFT))
        {
-               const TrackSeq &tracks=layout->get_tracks();
+               const set<Track *> &tracks=layout->get_tracks();
                float len=0;
-               for(TrackSeq::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
-                       len+=(*i)->get_total_length();
+               for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
+                       len+=(*i)->get_type().get_total_length();
                cout<<"Total length: "<<len<<"m\n";
        }
        else if(key==SDLK_l)
@@ -330,23 +338,23 @@ void Designer::key_press(unsigned key, unsigned mod, wchar_t ch)
        }
        else if(key==SDLK_x)
        {
-               Selection::TrackSet tracks=selection->get_tracks();
+               set<Track *> tracks=selection->get_tracks();
                selection->clear();
-               for(Selection::TrackSet::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+               for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                {
-                       layout->remove_track(*i);
+                       layout->remove_track(**i);
                        delete *i;
                }
        }
        else if(key==SDLK_f && (mod&KMOD_SHIFT))
        {
-               const Selection::TrackSet &tracks=selection->get_tracks();
-               const TrackSeq &ltracks=layout->get_tracks();
-               for(Selection::TrackSet::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
+               const set<Track *> &tracks=selection->get_tracks();
+               const set<Track *> &ltracks=layout->get_tracks();
+               for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
                {
                        (*i)->set_flex(!(*i)->get_flex());
                        (*i)->break_links();
-                       for(TrackSeq::const_iterator j=ltracks.begin(); j!=ltracks.end(); ++j)
+                       for(set<Track *>::const_iterator j=ltracks.begin(); j!=ltracks.end(); ++j)
                                if(*j!=*i)
                                        (*i)->snap_to(**j, true);
 
@@ -366,7 +374,7 @@ void Designer::key_press(unsigned key, unsigned mod, wchar_t ch)
        else if(key==SDLK_t)
        {
                Track *track=selection->get_track();
-               if(selection->size()==1 && track->get_n_routes()>1)
+               if(selection->size()==1 && track->get_type().get_n_routes()>1)
                {
                        ostringstream ss;
                        ss<<track->get_turnout_id();
@@ -379,7 +387,7 @@ void Designer::key_press(unsigned key, unsigned mod, wchar_t ch)
        else if(key==SDLK_s)
        {
                Track *track=selection->get_track();
-               if(selection->size()==1 && track->get_n_routes()==1)
+               if(selection->size()==1 && track->get_type().get_n_routes()==1)
                {
                        ostringstream ss;
                        ss<<track->get_sensor_id();
@@ -441,7 +449,7 @@ void Designer::button_press(int x, int y, float gx, float gy, unsigned btn)
                        {
                                Track *track=ctrack->get_track().copy();
                                track->set_position(Point(gx, gy, 0));
-                               layout->add_track(track);
+                               layout->add_track(*track);
 
                                selection->clear();
                                selection->add_track(track);
@@ -586,7 +594,7 @@ Track3D *Designer::pick_track(int x, int y)
 
 void Designer::manipulation_status(const string &status)
 {
-       tooltip=decode<Utf8>(status);
+       tooltip=status;
 }
 
 void Designer::manipulation_done(bool)
@@ -603,7 +611,7 @@ void Designer::measure_changed()
        ostringstream ss;
        ss.precision(3);
        ss<<"Par "<<pard<<"mm - Perp "<<perpd<<"mm - Total "<<d<<"mm - Angle "<<adiff<<"°";
-       tooltip=decode<Utf8>(ss.str());
+       tooltip=ss.str();
 }
 
 void Designer::measure_done()
index ece41a5dadb021fb96fc64587472f8763b1338eb..553b25c3e4faf91d35f554c68128fe53a2c832f4 100644 (file)
@@ -61,7 +61,7 @@ private:
        int            pointer_y;
        int            tooltip_x;
        int            tooltip_y;
-       std::wstring   tooltip;
+       std::string    tooltip;
        Msp::Time::TimeStamp tooltip_timeout;
        Msp::Time::TimeStamp last_tick;
 
index cbeb982198a81687f28b432a2a2a40e63640ea91..e7cceadcc1b286d63fdc8f2467ae11d25e395b65 100644 (file)
@@ -2,6 +2,7 @@
 #include <cmath>
 #include <GL/gl.h>
 #include "3d/layout.h"
+#include "libmarklin/tracktype.h"
 #include "designer.h"
 #include "manipulator.h"
 #include "selection.h"
@@ -66,19 +67,19 @@ void Manipulator::duplicate()
        if(mode)
                cancel();
 
-       TrackSeq new_tracks;
-       for(MTrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       list<Track *> new_tracks;
+       for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
                Track *track=i->track->copy();
-               designer.get_layout()->add_track(track);
+               designer.get_layout()->add_track(*track);
                new_tracks.push_back(track);
        }
 
        selection->clear();
-       for(TrackSeq::iterator i=new_tracks.begin(); i!=new_tracks.end(); ++i)
+       for(list<Track *>::iterator i=new_tracks.begin(); i!=new_tracks.end(); ++i)
        {
                selection->add_track(*i);
-               for(TrackSeq::iterator j=i; j!=new_tracks.end(); ++j)
+               for(list<Track *>::iterator j=i; j!=new_tracks.end(); ++j)
                        if(j!=i)
                                (*i)->snap_to(**j, true);
        }
@@ -92,18 +93,18 @@ void Manipulator::flatten()
        if(tracks.empty()) return;
 
        float z=0;
-       for(MTrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                z+=i->track->get_position().z+i->track->get_slope()/2;
        z/=tracks.size();
 
-       for(MTrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
                Point p=i->track->get_position();
                i->track->set_position(Point(p.x, p.y, z));
                i->track->set_slope(0);
        }
 
-       for(TrackSeq::iterator i=neighbors.begin(); i!=neighbors.end(); ++i)
+       for(set<Track *>::iterator i=neighbors.begin(); i!=neighbors.end(); ++i)
                (*i)->check_slope();
 
        update_wrap();
@@ -117,31 +118,31 @@ void Manipulator::even_slope(bool smooth)
        if(neighbors.size()!=2)
                return;
 
-       for(MTrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
-               if(i->track->get_endpoints().size()!=2)
+       for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+               if(i->track->get_type().get_endpoints().size()!=2)
                        return;
 
-       TrackSeq tracks2;
-       for(MTrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       list<Track *> tracks2;
+       for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                tracks2.push_back(i->track);
 
        float total_len=0;
 
-       TrackOrderSeq order;
-       Track *cur=neighbors.front();
+       list<TrackOrder> order;
+       Track *cur=*neighbors.begin();
        while(tracks2.size())
        {
                bool rev=false;
-               for(TrackSeq::iterator i=tracks2.begin(); i!=tracks2.end(); ++i)
+               for(list<Track *>::iterator i=tracks2.begin(); i!=tracks2.end(); ++i)
                {
-                       const Track::EndpointSeq &epl=(*i)->get_endpoints();
-                       if(epl.front().link==cur)
+                       const vector<Track *> &links=(*i)->get_links();
+                       if(links[0]==cur)
                        {
                                cur=*i;
                                tracks2.erase(i);
                                break;
                        }
-                       else if(epl.back().link==cur)
+                       else if(links[1]==cur)
                        {
                                cur=*i;
                                rev=true;
@@ -150,13 +151,15 @@ void Manipulator::even_slope(bool smooth)
                        }
                }
                order.push_back(TrackOrder(cur, rev));
-               total_len+=cur->get_length();
+               total_len+=cur->get_type().get_total_length();
        }
 
-       const Track::Endpoint *ep=neighbors.front()->get_endpoint_by_link(order.front().track);
-       float start_z=neighbors.front()->get_position().z+ep->pos.z;
-       ep=neighbors.back()->get_endpoint_by_link(order.back().track);
-       float end_z=neighbors.back()->get_position().z+ep->pos.z;
+       set<Track *>::iterator nb=neighbors.begin();
+       int epi=(*nb)->get_endpoint_by_link(*order.front().track);
+       float start_z=(*nb)->get_endpoint_position(epi).z;
+       ++nb;
+       epi=(*nb)->get_endpoint_by_link(*order.back().track);
+       float end_z=(*nb)->get_endpoint_position(epi).z;
 
        if(smooth)
        {
@@ -166,29 +169,29 @@ void Manipulator::even_slope(bool smooth)
                {
                        cur_slope+=0.025;
 
-                       float dz=order.front().track->get_length()*dir*cur_slope;
+                       float dz=order.front().track->get_type().get_total_length()*dir*cur_slope;
                        set_slope(order.front(), start_z, dz);
                        start_z+=dz;
-                       total_len-=order.front().track->get_length();
+                       total_len-=order.front().track->get_type().get_total_length();
                        order.erase(order.begin());
 
-                       dz=order.back().track->get_length()*dir*cur_slope;
+                       dz=order.back().track->get_type().get_total_length()*dir*cur_slope;
                        set_slope(order.back(), end_z-dz, dz);
                        end_z-=dz;
-                       total_len-=order.back().track->get_length();
+                       total_len-=order.back().track->get_type().get_total_length();
                        order.erase(--order.end());
                }
        }
 
        float cur_z=start_z;
-       for(TrackOrderSeq::iterator i=order.begin(); i!=order.end(); ++i)
+       for(list<TrackOrder>::iterator i=order.begin(); i!=order.end(); ++i)
        {
-               float dz=i->track->get_length()*(end_z-start_z)/total_len;
+               float dz=i->track->get_type().get_total_length()*(end_z-start_z)/total_len;
                set_slope(*i, cur_z, dz);
                cur_z+=dz;
        }
 
-       for(TrackSeq::iterator i=neighbors.begin(); i!=neighbors.end(); ++i)
+       for(set<Track *>::iterator i=neighbors.begin(); i!=neighbors.end(); ++i)
                (*i)->check_slope();
 
        update_wrap();
@@ -201,13 +204,13 @@ void Manipulator::cancel()
        mode=NONE;
 
        wrap_pos=center;
-       for(MTrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
                i->track->set_position(Point(center.x+i->pos.x, center.y+i->pos.y, center.z+i->pos.z));
                i->track->set_rotation(i->rot);
        }
 
-       for(TrackSeq::iterator i=neighbors.begin(); i!=neighbors.end(); ++i)
+       for(set<Track *>::iterator i=neighbors.begin(); i!=neighbors.end(); ++i)
                (*i)->check_slope();
 
        angle=0;
@@ -226,19 +229,19 @@ void Manipulator::button_press(int, int, float, float, unsigned btn)
                update_wrap();
                //snapped=0;
 
-               for(TrackSeq::iterator i=neighbors.begin(); i!=neighbors.end(); ++i)
-                       for(MTrackSeq::iterator j=tracks.begin(); j!=tracks.end(); ++j)
+               for(set<Track *>::iterator i=neighbors.begin(); i!=neighbors.end(); ++i)
+                       for(vector<MTrack>::iterator j=tracks.begin(); j!=tracks.end(); ++j)
                                j->track->break_link(**i);
 
-               const TrackSeq &ltracks=designer.get_layout()->get_tracks();
-               for(TrackSeq::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
+               const set<Track *> &ltracks=designer.get_layout()->get_tracks();
+               for(set<Track *>::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
                {
                        bool ok=true;
-                       for(MTrackSeq::iterator j=tracks.begin(); (j!=tracks.end() && ok); ++j)
+                       for(vector<MTrack>::iterator j=tracks.begin(); (j!=tracks.end() && ok); ++j)
                                ok=(j->track!=*i);
                        if(!ok) continue;
 
-                       for(MTrackSeq::iterator j=tracks.begin(); j!=tracks.end(); ++j)
+                       for(vector<MTrack>::iterator j=tracks.begin(); j!=tracks.end(); ++j)
                                j->track->snap_to(**i, true);
                }
 
@@ -258,22 +261,22 @@ void Manipulator::pointer_motion(int, int y, float gx, float gy)
                Point delta(gpointer.x-move_origin.x, gpointer.y-move_origin.y, 0);
 
                wrap_pos=Point(center.x+delta.x, center.y+delta.y, center.z);
-               for(MTrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+               for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                {
                        i->track->set_position(Point(wrap_pos.x+i->pos.x, wrap_pos.y+i->pos.y, wrap_pos.z+i->pos.z));
                        i->track->set_rotation(i->rot);
                }
 
-               const TrackSeq &ltracks=designer.get_layout()->get_tracks();
+               const set<Track *> &ltracks=designer.get_layout()->get_tracks();
                MTrack *snapped=0;
-               for(TrackSeq::const_iterator i=ltracks.begin(); (i!=ltracks.end() && !snapped); ++i)
+               for(set<Track *>::const_iterator i=ltracks.begin(); (i!=ltracks.end() && !snapped); ++i)
                {
                        bool ok=true;
-                       for(MTrackSeq::iterator j=tracks.begin(); (j!=tracks.end() && ok); ++j)
+                       for(vector<MTrack>::iterator j=tracks.begin(); (j!=tracks.end() && ok); ++j)
                                ok=(j->track!=*i);
                        if(!ok) continue;
 
-                       for(MTrackSeq::iterator j=tracks.begin(); (j!=tracks.end() && !snapped); ++j)
+                       for(vector<MTrack>::iterator j=tracks.begin(); (j!=tracks.end() && !snapped); ++j)
                                if(j->track->snap_to(**i, false))
                                        snapped=&*j;
                }
@@ -284,7 +287,7 @@ void Manipulator::pointer_motion(int, int y, float gx, float gy)
                        float c=cos(da);
                        float s=sin(da);
                        const Point &sp=snapped->track->get_position();
-                       for(MTrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+                       for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                        {
                                if(&*i==snapped)
                                        continue;
@@ -302,7 +305,7 @@ void Manipulator::pointer_motion(int, int y, float gx, float gy)
                rot_origin=a;
 
                wrap_rot=angle;
-               for(MTrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+               for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                {
                        float c=cos(angle);
                        float s=sin(angle);
@@ -320,10 +323,10 @@ void Manipulator::pointer_motion(int, int y, float gx, float gy)
                signal_status.emit(ss.str());
 
                wrap_pos.z=center.z+dz;
-               for(MTrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+               for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                        i->track->set_position(Point(center.x+i->pos.x, center.y+i->pos.y, center.z+i->pos.z+dz));
 
-               for(TrackSeq::iterator i=neighbors.begin(); i!=neighbors.end(); ++i)
+               for(set<Track *>::iterator i=neighbors.begin(); i!=neighbors.end(); ++i)
                        (*i)->check_slope();
        }
 }
@@ -365,7 +368,7 @@ void Manipulator::selection_changed()
        tracks.clear();
        if(selection)
        {
-               const Selection::TrackSet &stracks=selection->get_tracks();
+               const set<Track *> &stracks=selection->get_tracks();
                tracks.insert(tracks.end(), stracks.begin(), stracks.end());
        }
 
@@ -378,7 +381,7 @@ void Manipulator::update_wrap()
        wrap.clear();
        float min_x=0,max_x=0;
        float min_y=0,max_y=0;
-       for(MTrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
                Track3D *t3d=designer.get_layout_3d()->get_track(i->track);
 
@@ -422,7 +425,7 @@ void Manipulator::update_wrap()
        center=Point((min_x+max_x)/2, (min_y+max_y)/2, 0);
        wrap_pos=center;
        wrap_rot=0;
-       for(MTrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
                const Point &tp=i->track->get_position();
                i->pos=Point(tp.x-center.x, tp.y-center.y, tp.z);
@@ -437,22 +440,22 @@ void Manipulator::update_wrap()
 void Manipulator::update_neighbors()
 {
        neighbors.clear();
-       for(MTrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
-               const Track::EndpointSeq &epl=i->track->get_endpoints();
-               for(Track::EndpointSeq::const_iterator j=epl.begin(); j!=epl.end(); ++j)
+               const vector<Track *> &links=i->track->get_links();
+               for(vector<Track *>::const_iterator j=links.begin(); j!=links.end(); ++j)
                {
-                       if(!j->link)
+                       if(!*j)
                                continue;
-                       if(find(neighbors.begin(), neighbors.end(), j->link)!=neighbors.end())
+                       if(neighbors.count(*j))
                                continue;
 
                        bool ok=true;
-                       for(MTrackSeq::iterator k=tracks.begin(); (k!=tracks.end() && ok); ++k)
-                               ok=(k->track!=j->link);
+                       for(vector<MTrack>::iterator k=tracks.begin(); (k!=tracks.end() && ok); ++k)
+                               ok=(k->track!=*j);
 
                        if(ok)
-                               neighbors.push_back(j->link);
+                               neighbors.insert(*j);
                }
        }
 }
index 3a8882e8f97f686405651774aa478c7b1289a237..9e17384e4ee39b90c178d8e55c402e81bc9ec601 100644 (file)
@@ -42,7 +42,6 @@ private:
 
                MTrack(Marklin::Track *);
        };
-       typedef std::list<MTrack> MTrackSeq;
 
        struct TrackOrder
        {
@@ -51,7 +50,6 @@ private:
 
                TrackOrder(Marklin::Track *t, bool r): track(t), rev(r) { }
        };
-       typedef std::list<TrackOrder> TrackOrderSeq;
 
        struct TrackWrap
        {
@@ -63,7 +61,7 @@ private:
 
        Designer   &designer;
        Selection  *selection;
-       MTrackSeq  tracks;
+       std::vector<MTrack> tracks;
        Marklin::Point center;
 
        std::list<TrackWrap> wrap;
@@ -77,7 +75,7 @@ private:
        float          angle;
        float          rot_origin;
        int            elev_origin;
-       Marklin::TrackSeq neighbors;
+       std::set<Marklin::Track *> neighbors;
        sigc::connection selection_changed_conn;
 
        void selection_changed();
index 6f1d7bc8d5943bf73a00d4d94efe1bed7a8ef4bf..82fca978837d10052ddbe74eb370501784e06502 100644 (file)
@@ -4,6 +4,7 @@
 #include "3d/layout.h"
 #include "measure.h"
 
+using namespace std;
 using namespace Marklin;
 using namespace Msp;
 
@@ -19,8 +20,8 @@ void Measure::start()
 
 void Measure::snap_to_tracks(Point &pt, float &dir)
 {
-       const TrackSeq &ltracks=designer.get_layout()->get_tracks();
-       for(TrackSeq::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
+       const set<Track *> &ltracks=designer.get_layout()->get_tracks();
+       for(set<Track *>::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
                if((*i)->snap(pt, dir))
                        return;
 }
index a693c0a7ccfc4ac9d0dbd66fffb3ded71b44b386..ed71547b0f6a9a46c51279cc3f343cd298bc88a7 100644 (file)
@@ -41,17 +41,17 @@ void Selection::toggle_track(Track *t)
 
 void Selection::select_more()
 {
-       TrackSet new_tracks;
-       for(TrackSet::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       set<Track *> new_tracks;
+       for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
-               const Track::EndpointSeq &epl=(*i)->get_endpoints();
-               for(Track::EndpointSeq::const_iterator j=epl.begin(); j!=epl.end(); ++j)
-                       if(j->link)
-                               new_tracks.insert(j->link);
+               const vector<Track *> &links=(*i)->get_links();
+               for(vector<Track *>::const_iterator j=links.begin(); j!=links.end(); ++j)
+                       if(*j)
+                               new_tracks.insert(*j);
        }
 
        bool changed=false;
-       for(TrackSet::iterator i=new_tracks.begin(); i!=new_tracks.end(); ++i)
+       for(set<Track *>::iterator i=new_tracks.begin(); i!=new_tracks.end(); ++i)
                if(tracks.insert(*i).second)
                        changed=true;
 
@@ -62,25 +62,25 @@ void Selection::select_more()
 void Selection::select_linked()
 {
        bool changed=false;
-       TrackSeq queue(tracks.begin(), tracks.end());
+       list<Track *> queue(tracks.begin(), tracks.end());
        while(!queue.empty())
        {
                Track *track=queue.front();
                queue.erase(queue.begin());
 
-               const Track::EndpointSeq &epl=track->get_endpoints();
-               for(Track::EndpointSeq::const_iterator j=epl.begin(); j!=epl.end(); ++j)
-                       if(j->link && tracks.insert(j->link).second)
+               const vector<Track *> &links=track->get_links();
+               for(vector<Track *>::const_iterator j=links.begin(); j!=links.end(); ++j)
+                       if(*j && tracks.insert(*j).second)
                        {
-                               queue.push_back(j->link);
+                               queue.push_back(*j);
                                changed=true;
                        }
        }
-       for(TrackSet::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
-               const Track::EndpointSeq &epl=(*i)->get_endpoints();
-               for(Track::EndpointSeq::const_iterator j=epl.begin(); j!=epl.end(); ++j)
-                       if(j->link && tracks.insert(j->link).second)
+               const vector<Track *> &links=(*i)->get_links();
+               for(vector<Track *>::const_iterator j=links.begin(); j!=links.end(); ++j)
+                       if(*j && tracks.insert(*j).second)
                                changed=true;
        }
 
index 36e44354212b70f1d202ac5fed44f5f1c807bd5e..21c5de187f0667ff4c0d82ab30f1093c4ff153c5 100644 (file)
@@ -8,11 +8,9 @@
 class Selection
 {
 public:
-       typedef std::set<Marklin::Track *> TrackSet;
-
        sigc::signal<void> signal_changed;
 
-       const TrackSet &get_tracks() const { return tracks; }
+       const std::set<Marklin::Track *> &get_tracks() const { return tracks; }
        Marklin::Track *get_track() const;
        unsigned size() const { return tracks.size(); }
        void clear();
@@ -22,7 +20,7 @@ public:
        void select_more();
        void select_linked();
 private:
-       TrackSet tracks;
+       std::set<Marklin::Track *> tracks;
 };
 
 #endif
index ab95d02ff25a636d786a6960dfb61dc58cddeaa0..d57deb7e0e431865ee1318cc71000845885718b7 100644 (file)
@@ -2,7 +2,7 @@
 #include <limits>
 #include <SDL.h>
 #include <GL/gl.h>
-#include <msp/core/error.h>
+#include <msp/core/except.h>
 #include <msp/core/getopt.h>
 #include <msp/gl/matrix.h>
 #include <msp/gl/transform.h>
@@ -12,6 +12,7 @@
 #include "engineer.h"
 #include "mainpanel.h"
 #include "trainpanel.h"
+#include "trainproperties.h"
 
 using namespace std;
 using namespace Marklin;
@@ -29,7 +30,9 @@ Engineer::Engineer(int argc, char **argv):
        placing_train(0),
        placing_block(0),
        placing_entry(0),
-       simulate(false)
+       simulate(false),
+       train_prop(0),
+       train_prop_stale(false)
 {
        string res;
        bool   debug=false;
@@ -66,16 +69,18 @@ Engineer::Engineer(int argc, char **argv):
 
        catalogue.load("tracks.dat");
 
-       const list<string> &args=getopt.get_args();
+       const vector<string> &args=getopt.get_args();
        if(args.empty())
                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));
 
+       const map<unsigned, Sensor *> &sensors=control.get_sensors();
+       for(map<unsigned, Sensor *>::const_iterator i=sensors.begin(); i!=sensors.end(); ++i)
+               i->second->signal_state_changed.connect(sigc::bind(sigc::mem_fun(this, &Engineer::sensor_event), i->second));
+
        view_all();
 }
 
@@ -84,25 +89,40 @@ Engineer::~Engineer()
        delete trfc_mgr;
 }
 
-void Engineer::add_train(unsigned addr)
+Train *Engineer::add_train(unsigned addr)
 {
-       if(control.get_locomotive(addr))
-               return;
+       /*if(control.get_locomotive(addr))
+               return 0;*/
 
-       Locomotive *loco=new Locomotive(control, addr);
-       Train *train=new Train(*trfc_mgr, *loco);
-       train->set_name(format("Train %d", trfc_mgr->get_trains().size()));
+       if(addr==0)
+       {
+               train_prop=new TrainProperties(*this, ui_res, 0);
+               train_prop->signal_ok.connect(sigc::mem_fun(this, &Engineer::dismiss_train_prop));
+               train_prop_stale=false;
 
-       TrainPanel *tpanel=new TrainPanel(*this, ui_res, *train);
-       int y=main_panel->get_geometry().y;
-       for(TrainPanelSeq::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);
+               return 0;
+       }
+       else
+       {
+               Locomotive *loco=new Locomotive(control, addr);
+               Train *train=new Train(*trfc_mgr, *loco);
+               train->set_name(format("Train %d", trfc_mgr->get_trains().size()));
+
+               //train_prop=new TrainProperties(ui_res, *train);
 
-       placing_train=train;
-       placing_block=0;
-       status_text="Select train location";
+               TrainPanel *tpanel=new TrainPanel(*this, ui_res, *train);
+               int y=main_panel->get_geometry().y;
+               for(TrainPanelSeq::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);
+
+               placing_train=train;
+               placing_block=0;
+               status_text="Select train location";
+
+               return train;
+       }
 }
 
 int Engineer::main()
@@ -124,6 +144,8 @@ int Engineer::main()
        if(!screen)
                throw Exception("Couldn't create window");
 
+       SDL_EnableUNICODE(1);
+
        glEnableClientState(GL_VERTEX_ARRAY);
        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
        glEnable(GL_COLOR_MATERIAL);
@@ -131,7 +153,7 @@ int Engineer::main()
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
-       Parser::load(ui_res, "engineer.res");
+       DataFile::load(ui_res, "engineer.res");
        main_panel=new MainPanel(*this, ui_res);
        main_panel->set_position(0, screen_h-main_panel->get_geometry().h);
 
@@ -165,7 +187,7 @@ void Engineer::tick()
                        pointer_motion(event.motion.x, screen_h-1-event.motion.y);
                        break;
                case SDL_KEYDOWN:
-                       key_press(event.key.keysym.sym, event.key.keysym.mod);
+                       key_press(event.key.keysym.sym, event.key.keysym.mod, event.key.keysym.unicode);
                        break;
                case SDL_QUIT:
                        exit(0);
@@ -207,11 +229,8 @@ void Engineer::tick()
                Track &track=(*i)->get_track();
                if(track.get_turnout_id())
                {
-                       Turnout *trnt=control.get_turnout(track.get_turnout_id());
-                       if(trnt)
-                               (*i)->render_route(trnt->get_route());
-                       else
-                               (*i)->render_route(-1);
+                       Turnout &trnt=control.get_turnout(track.get_turnout_id());
+                       (*i)->render_route(trnt.get_route());
                }
                else
                        (*i)->render_route(-1);
@@ -219,8 +238,9 @@ void Engineer::tick()
 
        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);
+               const Marklin::Block::Endpoint &bep=placing_block->get_endpoints()[placing_entry];
+               float rot=bep.track->get_endpoint_direction(bep.track_ep);
+               Point pos=bep.track->get_endpoint_position(bep.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);
@@ -251,8 +271,16 @@ void Engineer::tick()
        main_panel->render();
        for(TrainPanelSeq::iterator i=train_panels.begin(); i!=train_panels.end(); ++i)
                (*i)->render();
+       if(train_prop)
+               train_prop->render();
 
-       const GL::Font &font=ui_res.get_font("dejavu-12");
+       if(train_prop_stale)
+       {
+               delete train_prop;
+               train_prop=0;
+       }
+
+       const GL::Font &font=ui_res.get_default_font();
        GL::load_identity();
        GL::translate(340, 10, 0);
        GL::scale_uniform(font.get_default_size());
@@ -262,15 +290,17 @@ void Engineer::tick()
        SDL_GL_SwapBuffers();
 }
 
-void Engineer::key_press(unsigned, unsigned)
+void Engineer::key_press(unsigned key, unsigned mod, wchar_t ch)
 {
+       if(train_prop)
+               train_prop->key_press(key, mod, ch);
 }
 
 void Engineer::button_press(int x, int y, unsigned btn)
 {
        if(main_panel->get_geometry().is_inside(x, y))
        {
-               main_panel->button_press(x, y, btn);
+               main_panel->button_press(x, y-main_panel->get_geometry().y, btn);
                return;
        }
        for(TrainPanelSeq::iterator i=train_panels.begin(); i!=train_panels.end(); ++i)
@@ -279,6 +309,11 @@ void Engineer::button_press(int x, int y, unsigned btn)
                        (*i)->button_press(x, y, btn);
                        return;
                }
+       if(train_prop && train_prop->get_geometry().is_inside(x, y))
+       {
+               train_prop->button_press(x, y, btn);
+               return;
+       }
 
        if(placing_train)
        {
@@ -291,15 +326,8 @@ void Engineer::button_press(int x, int y, unsigned btn)
                }
                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;
+                       const vector<Block::Endpoint> &endpoints=placing_block->get_endpoints();
+                       placing_entry=(placing_entry+1)%endpoints.size();
                }
        }
        else
@@ -307,14 +335,18 @@ void Engineer::button_press(int x, int y, unsigned btn)
                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());
+                       if(unsigned tid=track->get_track().get_turnout_id())
+                       {
+                               Turnout &turnout=control.get_turnout(tid);
+                               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());
+                               if(unsigned sid=track->get_track().get_sensor_id())
+                               {
+                                       Sensor &sensor=control.get_sensor(sid);
+                                       control.signal_sensor_event.emit(sid, !sensor.get_state());
+                               }
                        }
                }
        }
@@ -324,7 +356,7 @@ void Engineer::button_release(int x, int y, unsigned btn)
 {
        if(main_panel->get_geometry().is_inside(x, y))
        {
-               main_panel->button_release(x, y, btn);
+               main_panel->button_release(x, y-main_panel->get_geometry().y, btn);
                return;
        }
        for(TrainPanelSeq::iterator i=train_panels.begin(); i!=train_panels.end(); ++i)
@@ -333,6 +365,11 @@ void Engineer::button_release(int x, int y, unsigned btn)
                        (*i)->button_release(x, y, btn);
                        return;
                }
+       if(train_prop && train_prop->get_geometry().is_inside(x, y))
+       {
+               train_prop->button_release(x, y, btn);
+               return;
+       }
 }
 
 void Engineer::pointer_motion(int x, int y)
@@ -348,6 +385,11 @@ void Engineer::pointer_motion(int x, int y)
                        (*i)->pointer_motion(x, y);
                        return;
                }
+       if(train_prop && train_prop->get_geometry().is_inside(x, y))
+       {
+               train_prop->pointer_motion(x, y);
+               return;
+       }
 
        Track3D *track=pick_track(x, y);
        if(track && placing_train)
@@ -358,7 +400,7 @@ void Engineer::pointer_motion(int x, int y)
                        if(placing_block)
                                set_block_color(*placing_block, Color(1, 1, 1));
                        placing_block=block;
-                       placing_entry=&block->get_endpoints().front();
+                       placing_entry=0;
                        set_block_color(*placing_block, Color(0.5, 1, 0.7));
                }
        }
@@ -418,17 +460,16 @@ void Engineer::view_all()
 
 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)
+       const set<Track *> &tracks=block.get_tracks();
+       for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
                layout_3d.get_track(*i)->set_color(color);
 }
 
-void Engineer::sensor_event(unsigned addr, bool state)
+void Engineer::sensor_event(bool state, Sensor *sensor)
 {
-       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)
+       const list<Track3D *> &ltracks=layout_3d.get_tracks();
+       for(list<Track3D *>::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
+               if((*i)->get_track().get_sensor_id()==sensor->get_address())
                {
                        if(state)
                                (*i)->set_color(Color(1, 0.5, 0.3));
@@ -439,9 +480,13 @@ void Engineer::sensor_event(unsigned addr, bool state)
 
 void Engineer::block_reserved(const Block &block, const Train *train)
 {
-       if(Sensor *sensor=control.get_sensor(block.get_sensor_id()))
-               if(sensor->get_state())
+       if(unsigned sid=block.get_sensor_id())
+       {
+               Sensor &sensor=control.get_sensor(sid);
+               cout<<block.get_sensor_id()<<' '<<&sensor<<' '<<sensor.get_state()<<'\n';
+               if(sensor.get_state())
                        return;
+       }
 
        if(train)
                set_block_color(block, Color(1, 1, 0.3));
@@ -473,4 +518,9 @@ Track3D *Engineer::pick_track(int x, int y)
        return layout_3d.pick_track(xx, yy, size);
 }
 
+void Engineer::dismiss_train_prop()
+{
+       train_prop_stale=true;
+}
+
 Application::RegApp<Engineer> Engineer::reg;
index ac5ce2c94d45d3b1fbef42162e075d71a5ccea9e..dc48e70dadac3fe6729fc665318fa8da433a6a91 100644 (file)
@@ -12,6 +12,7 @@
 
 class MainPanel;
 class TrainPanel;
+class TrainProperties;
 
 class Engineer: public Msp::Application
 {
@@ -20,7 +21,7 @@ public:
        ~Engineer();
 
        Marklin::Control &get_control()    { return control; }
-       void     add_train(unsigned);
+       Marklin::Train   *add_train(unsigned);
        int      main();
        void     quit() { exit(0); }
 private:
@@ -43,20 +44,23 @@ private:
        Marklin::TrafficManager *trfc_mgr;
        Marklin::Train     *placing_train;
        Marklin::Block     *placing_block;
-       const Marklin::Block::Endpoint *placing_entry;
+       unsigned           placing_entry;
        bool               simulate;
+       TrainProperties    *train_prop;
+       bool               train_prop_stale;
 
        void tick();
-       void key_press(unsigned, unsigned);
+       void key_press(unsigned, unsigned, wchar_t);
        void button_press(int, int, unsigned);
        void button_release(int, int, unsigned);
        void pointer_motion(int, int);
        void view_all();
        void set_block_color(const Marklin::Block &, const Marklin::Color &);
-       void sensor_event(unsigned, bool);
+       void sensor_event(bool, Marklin::Sensor *);
        void block_reserved(const Marklin::Block &, const Marklin::Train *);
        void project_3d();
        Marklin::Track3D *pick_track(int, int);
+       void dismiss_train_prop();
 
        static Msp::Application::RegApp<Engineer> reg;
 };
index d46bd9d4756ca8c229eb92e7a3df64aadab87ae1..be27cd4013512319ed62148544a4215ad3a3d3da 100644 (file)
@@ -13,16 +13,15 @@ TrainPanel::TrainPanel(Engineer &e, const GLtk::Resources &r, Train &t):
 {
        set_size(200, 100);
 
+       add(*(lbl_addr=new GLtk::Label(res, lexical_cast(train.get_locomotive().get_address(), "%2d"))));
+       lbl_addr->set_style("digital");
+       lbl_addr->set_geometry(GLtk::Geometry(10, geom.h-34, 35, 34));
+
        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));
+       lbl_name->set_geometry(GLtk::Geometry(45, geom.h-34, geom.w-55, 24));
        train.signal_name_changed.connect(sigc::mem_fun(lbl_name, &GLtk::Label::set_text));
 
-       GLtk::Button *btn;
-
-       add(*(btn=new GLtk::Button(res, "Name")));
-       btn->set_geometry(GLtk::Geometry(150, geom.h-34, 40, 24));
-
        add(*(sld_speed=new GLtk::HSlider(res)));
        sld_speed->set_geometry(GLtk::Geometry(10, geom.h-49, 180, 10));
        sld_speed->set_range(0, 14);
@@ -31,8 +30,13 @@ TrainPanel::TrainPanel(Engineer &e, const GLtk::Resources &r, Train &t):
 
        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));
+       lbl_speed->set_geometry(GLtk::Geometry(10, geom.h-75, 35, 24));
        train.get_locomotive().signal_speed_changed.connect(sigc::mem_fun(this, &TrainPanel::loco_speed_changed));
+
+       GLtk::Button *btn;
+
+       add(*(btn=new GLtk::Button(res, "Edit")));
+       btn->set_geometry(GLtk::Geometry(geom.w-50, 10, 40, 24));
 }
 
 void TrainPanel::speed_slider_changed(double v)
index 5abec3b443e24941160ee525aa91a1f0b0bc0271..d21e5618694c8fc69d86c69fc71d4b64cb76f5d9 100644 (file)
@@ -15,6 +15,7 @@ public:
 private:
        Engineer &engineer;
        Marklin::Train &train;
+       Msp::GLtk::Label *lbl_addr;
        Msp::GLtk::Label *lbl_name;
        Msp::GLtk::HSlider *sld_speed;
        Marklin::Locomotive *loco;
index 1aebea029eb2506e070e87c650f5d0f345422f27..9b46ce41af96c6551d0bf59f29aa69278adf08c7 100644 (file)
@@ -1,26 +1,45 @@
 #include <msp/gltk/button.h>
+#include <msp/strings/lexicalcast.h>
+#include "engineer.h"
 #include "trainproperties.h"
 
 using namespace Msp;
 using namespace Marklin;
 
-TrainProperties::TrainProperties(GLtk::Resources &r, Train &t):
+TrainProperties::TrainProperties(Engineer &e, GLtk::Resources &r, Train *t):
        Panel(r),
+       engineer(e),
        train(t)
 {
        set_size(200, 75);
 
-       add(*(ent_name=new GLtk::Entry(res, train.get_name())));
-       ent_name->set_geometry(GLtk::Geometry(5, geom.h-25, geom.w-10, 20));
+       add(*(ent_addr=new GLtk::Entry(res)));
+       ent_addr->set_geometry(GLtk::Geometry(10, geom.h-25, 40, 20));
 
-       add(*(ent_name=new GLtk::Entry(res, train.get_name())));
-       ent_name->set_geometry(GLtk::Geometry(5, geom.h-50, geom.w-10, 20));
+       add(*(ent_name=new GLtk::Entry(res, "Train")));
+       ent_name->set_geometry(GLtk::Geometry(10, geom.h-50, geom.w-20, 20));
 
        GLtk::Button *btn;
 
        add(*(btn=new GLtk::Button(res, "OK")));
-       btn->set_geometry(GLtk::Geometry(geom.w-45, 5, 40, 25));
+       btn->set_style("green");
+       btn->set_geometry(GLtk::Geometry(geom.w-40, 10, 30, 25));
+       btn->signal_clicked.connect(sigc::mem_fun(this, &TrainProperties::ok_clicked));
 
        add(*(btn=new GLtk::Button(res, "Cncl")));
-       btn->set_geometry(GLtk::Geometry(geom.w-90, 5, 40, 25));
+       btn->set_style("red");
+       btn->set_geometry(GLtk::Geometry(geom.w-80, 10, 30, 25));
+}
+
+void TrainProperties::ok_clicked()
+{
+       if(train)
+       {
+       }
+       else
+       {
+               train=engineer.add_train(lexical_cast<unsigned>(ent_addr->get_text()));
+               train->set_name(ent_name->get_text());
+       }
+       signal_ok.emit();
 }
index 89b6e94eb7311d427ec22fb60300435eba845828..b63bc3d00848770c6a32db86644e1bbac74d7aed 100644 (file)
@@ -5,14 +5,21 @@
 #include <msp/gltk/panel.h>
 #include <libmarklin/train.h>
 
+class Engineer;
+
 class TrainProperties: public Msp::GLtk::Panel
 {
 public:
-       TrainProperties(Msp::GLtk::Resources &, Marklin::Train &);
+       sigc::signal<void> signal_ok;
+
+       TrainProperties(Engineer &, Msp::GLtk::Resources &, Marklin::Train *);
 private:
-       Marklin::Train &train;
-       Msp::GLtk::Entry *ent_id;
+       Engineer &engineer;
+       Marklin::Train *train;
+       Msp::GLtk::Entry *ent_addr;
        Msp::GLtk::Entry *ent_name;
+
+       void ok_clicked();
 };
 
 #endif
index b3a96e67f4f59850c58a599c92eced8dc70d96c4..3bd251f3afd03189edad88502b1a7b28f50ec4b3 100644 (file)
@@ -1,5 +1,6 @@
 #include "control.h"
 #include "block.h"
+#include "tracktype.h"
 #include "trafficmanager.h"
 #include "turnout.h"
 
@@ -10,69 +11,62 @@ using namespace std;
 
 namespace Marklin {
 
-Block::Block(TrafficManager &tm, Track *start):
+Block::Block(TrafficManager &tm, Track &start):
        trfc_mgr(tm),
        id(next_id++),
        sensor_id(0),
        train(0)
 {
-       tracks.insert(start);
+       tracks.insert(&start);
 
-       if(start->get_sensor_id())
-       {
-               sensor_id=start->get_sensor_id();
-               const Track::EndpointSeq &eps=start->get_endpoints();
-               for(Track::EndpointSeq::const_iterator i=eps.begin(); i!=eps.end(); ++i)
-                       endpoints.push_back(Endpoint(start, &*i));
-       }
-       else
-       {
-               TrackSeq queue;
-               queue.push_back(start);
+       list<Track *> queue;
+       queue.push_back(&start);
 
-               while(!queue.empty())
-               {
-                       Track *track=queue.front();
-                       queue.erase(queue.begin());
+       while(!queue.empty())
+       {
+               Track *track=queue.front();
+               queue.erase(queue.begin());
 
-                       const Track::EndpointSeq &eps=track->get_endpoints();
-                       for(Track::EndpointSeq::const_iterator i=eps.begin(); i!=eps.end(); ++i)
-                               if(i->link && tracks.count(i->link)==0)
+               const vector<Track *> &links=track->get_links();
+               for(unsigned i=0; i<links.size(); ++i)
+                       if(links[i] && !tracks.count(links[i]))
+                       {
+                               if(links[i]->get_sensor_id()==start.get_sensor_id())
                                {
-                                       if(!i->link->get_sensor_id())
-                                       {
-                                               queue.push_back(i->link);
-                                               tracks.insert(i->link);
-                                       }
-                                       else
-                                               endpoints.push_back(Endpoint(track, &*i));
+                                       queue.push_back(links[i]);
+                                       tracks.insert(links[i]);
                                }
-               }
+                               else
+                                       endpoints.push_back(Endpoint(track, i));
+                       }
        }
 
-       unsigned n=0;
-       for(EndpointSeq::iterator i=endpoints.begin(); i!=endpoints.end(); ++i, ++n)
+       for(unsigned i=0; i<endpoints.size(); ++i)
        {
-               unsigned route=1<<n;
-               i->routes|=route;
+               unsigned route=1<<i;
+               endpoints[i].routes|=route;
                set<Track *> visited;
-               find_routes(i->track, i->track_ep, route, visited);
+               find_routes(*endpoints[i].track, endpoints[i].track_ep, route, visited);
        }
 }
 
-const Block::Endpoint *Block::get_endpoint_by_link(const Block *other) const
+int Block::get_endpoint_by_link(const Block &other) const
 {
-       for(EndpointSeq::const_iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
-               if(i->link==other)
-                       return &*i;
+       for(unsigned i=0; i<endpoints.size(); ++i)
+               if(endpoints[i].link==&other)
+                       return i;
 
-       return 0;
+       return -1;
 }
 
-const Block::Endpoint *Block::traverse(const Endpoint *ep) const
+int Block::traverse(unsigned epi) const
 {
-       Track *track=ep->track;
-       const Track::Endpoint *track_ep=ep->track_ep;
+       if(epi>=endpoints.size())
+               throw InvalidParameterValue("Endpoint index out of range");
+
+       const Endpoint &ep=endpoints[epi];
+       Track *track=ep.track;
+       unsigned track_ep=ep.track_ep;
 
        while(1)
        {
@@ -80,36 +74,36 @@ const Block::Endpoint *Block::traverse(const Endpoint *ep) const
                unsigned tid=track->get_turnout_id();
                if(tid)
                {
-                       Turnout *turnout=trfc_mgr.get_control().get_turnout(tid);
-                       if(turnout)
-                               cur_route=turnout->get_route();
+                       Turnout &turnout=trfc_mgr.get_control().get_turnout(tid);
+                       cur_route=turnout.get_route();
                }
 
-               const Track::Endpoint *other_ep=track->traverse(track_ep, cur_route);
-               if(!other_ep)
+               int other_ep=track->traverse(track_ep, cur_route);
+               if(other_ep<0)
                        return 0;
 
-               for(EndpointSeq::const_iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
-                       if(i->track==track && i->track_ep==other_ep)
-                               return &*i;
+               for(unsigned i=0; i<endpoints.size(); ++i)
+                       if(endpoints[i].track==track && endpoints[i].track_ep==static_cast<unsigned>(other_ep))
+                               return i;
 
-               track_ep=other_ep->link->get_endpoint_by_link(track);
-               track=other_ep->link;
+               Track *next=track->get_link(other_ep);
+               track_ep=next->get_endpoint_by_link(*track);
+               track=next;
 
                if(tracks.count(track)==0)
-                       return 0;
+                       return -1;
        }
 }
 
 void Block::check_link(Block &other)
 {
-       for(EndpointSeq::iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
+       for(vector<Endpoint>::iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
        {
                if(i->link)
                        continue;
 
-               for(EndpointSeq::iterator j=other.endpoints.begin(); j!=other.endpoints.end(); ++j)
-                       if(j->track==i->track_ep->link && j->track_ep->link==i->track && !j->link)
+               for(vector<Endpoint>::iterator j=other.endpoints.begin(); j!=other.endpoints.end(); ++j)
+                       if(j->track==i->track->get_link(i->track_ep) && j->track->get_link(j->track_ep)==i->track && !j->link)
                        {
                                i->link=&other;
                                j->link=this;
@@ -117,6 +111,13 @@ void Block::check_link(Block &other)
        }
 }
 
+Block *Block::get_link(unsigned epi) const
+{
+       if(epi>=endpoints.size())
+               throw InvalidParameterValue("Endpoint index out of range");
+       return endpoints[epi].link;
+}
+
 bool Block::reserve(const Train *t)
 {
        if(!t || !train)
@@ -136,7 +137,7 @@ void Block::print_debug()
        if((*tracks.begin())->get_sensor_id())
                cout<<", sensor="<<(*tracks.begin())->get_sensor_id();
        cout<<'\n';
-       for(EndpointSeq::iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
+       for(vector<Endpoint>::iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
        {
                cout<<"  Endpoint, link=";
                if(i->link)
@@ -147,24 +148,25 @@ void Block::print_debug()
        }
 }
 
-void Block::find_routes(Track *track, const Track::Endpoint *track_ep, unsigned route, std::set<Marklin::Track *> &visited)
+void Block::find_routes(Track &track, unsigned track_ep, unsigned route, set<Track *> &visited)
 {
-       visited.insert(track);
+       visited.insert(&track);
 
-       const Track::EndpointSeq &eps=track->get_endpoints();
-       for(Track::EndpointSeq::const_iterator i=eps.begin(); i!=eps.end(); ++i)
+       const vector<Marklin::Endpoint> &eps=track.get_type().get_endpoints();
+       for(unsigned i=0; i<eps.size(); ++i)
        {
-               if(&*i==track_ep) continue;
-               if(!i->link) continue;
-               if(!(i->routes&track_ep->routes)) continue;
-               if(visited.count(i->link)) continue;
-
-               if(tracks.count(i->link))
-                       find_routes(i->link, i->link->get_endpoint_by_link(track), route, visited);
+               if(i==track_ep) continue;
+               Track *link=track.get_link(i);
+               if(link) continue;
+               if(visited.count(link)) continue;
+               if(!(eps[i].routes&eps[track_ep].routes)) continue;
+
+               if(tracks.count(link))
+                       find_routes(*link, link->get_endpoint_by_link(track), route, visited);
                else
                {
-                       for(EndpointSeq::iterator j=endpoints.begin(); j!=endpoints.end(); ++j)
-                               if(j->track==track && j->track_ep==&*i)
+                       for(vector<Endpoint>::iterator j=endpoints.begin(); j!=endpoints.end(); ++j)
+                               if(j->track==&track && j->track_ep==i)
                                        j->routes|=route;
                }
        }
@@ -175,7 +177,7 @@ void Block::find_routes(Track *track, const Track::Endpoint *track_ep, unsigned
 unsigned Block::next_id=1;
 
 
-Block::Endpoint::Endpoint(Track *t, const Track::Endpoint *e):
+Block::Endpoint::Endpoint(Track *t, unsigned e):
        track(t),
        track_ep(e),
        link(0),
index 4a22aa97862bfc2019890aefc8090f83e7114ea9..f18ba8d6f49d52a53844045078aa17f5dd766a96 100644 (file)
@@ -15,33 +15,35 @@ class Block
 public:
        struct Endpoint
        {
-               Track *track;
-               const Track::Endpoint *track_ep;
-               Block  *link;
+               Track    *track;
+               unsigned track_ep;
+               Block    *link;
                unsigned routes;
 
-               Endpoint(Track *, const Track::Endpoint *);
+               Endpoint(Track *, unsigned);
        };
-       typedef std::list<Endpoint> EndpointSeq;
 
-       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 &);
-       bool reserve(const Train *);
-       void print_debug();
 private:
        TrafficManager &trfc_mgr;
        unsigned       id;
        unsigned       sensor_id;
-       TrackSet       tracks;
-       EndpointSeq    endpoints;
+       std::set<Track *>     tracks;
+       std::vector<Endpoint> endpoints;
        const Train    *train;
 
-       void find_routes(Track *, const Track::Endpoint *, unsigned, TrackSet &);
+public:
+       Block(TrafficManager &, Track &);
+       unsigned get_sensor_id() const { return sensor_id; }
+       const std::set<Track *> &get_tracks() const { return tracks; }
+       const std::vector<Endpoint> &get_endpoints() const { return endpoints; }
+       int get_endpoint_by_link(const Block &) const;
+       int traverse(unsigned) const;
+       void check_link(Block &);
+       Block *get_link(unsigned) const;
+       bool reserve(const Train *);
+       void print_debug();
+private:
+       void find_routes(Track &, unsigned, unsigned, std::set<Track *> &);
 
        static unsigned next_id;
 };
index 3c8e279bcf354a957f05a418c2592538b3f97f67..00c27738cfb118a06040d626fe90064e036435cd 100644 (file)
@@ -1,39 +1,37 @@
-#include <fstream>
-#include <msp/parser/parser.h>
+#include <msp/core/refptr.h>
+#include <msp/datafile/parser.h>
 #include "catalogue.h"
-#include "track.h"
+#include "tracktype.h"
 
 using namespace std;
 using namespace Msp;
 
 namespace Marklin {
 
-Track *Catalogue::get_track(unsigned art_nr)
+Catalogue::~Catalogue()
 {
-       TrackMap::const_iterator i=tracks.find(art_nr);
+       for(map<unsigned, TrackType *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+               delete i->second;
+}
 
-       if(i!=tracks.end())
-               return i->second;
+TrackType &Catalogue::get_track(unsigned art_nr)
+{
+       map<unsigned, TrackType *>::const_iterator i=tracks.find(art_nr);
+       if(i==tracks.end())
+               throw KeyError("Unknown track type");
 
-       return 0;
+       return *i->second;
 }
 
 void Catalogue::load(const string &fn)
 {
-       ifstream in(fn.c_str());
-       if(!in)
-               throw Exception("File not found");
+       IO::File in(fn.c_str());
 
-       Parser::Parser parser(in, fn);
+       DataFile::Parser parser(in, fn);
        Loader loader(*this);
        loader.load(parser);
 }
 
-Catalogue::~Catalogue()
-{
-       for(TrackMap::iterator i=tracks.begin(); i!=tracks.end(); ++i)
-               delete i->second;
-}
 
 Catalogue::Loader::Loader(Catalogue &c):
        cat(c)
@@ -43,21 +41,14 @@ Catalogue::Loader::Loader(Catalogue &c):
 
 void Catalogue::Loader::track(unsigned art_no)
 {
-       TrackMap::iterator i=cat.tracks.find(art_no);
+       map<unsigned, TrackType *>::iterator i=cat.tracks.find(art_no);
        if(i!=cat.tracks.end())
                throw Exception("Duplicate track number");
 
-       Track *trk=new Track(art_no);
-       try
-       {
-               load_sub(*trk);
-       }
-       catch(const Msp::Exception &)
-       {
-               delete trk;
-               throw;
-       }
-       cat.tracks.insert(TrackMap::value_type(trk->get_article_number(), trk));
+       RefPtr<TrackType> trk=new TrackType(art_no);
+       load_sub(*trk);
+       unsigned art_nr=trk->get_article_number();
+       cat.tracks.insert(map<unsigned, TrackType *>::value_type(art_nr, trk.release()));
 }
 
 } // namespace Marklin
index 1a328bba1a70431b7486b55e3b78762a4049d8b0..6277158df699246952fe29e5286c6bd3bb02f60f 100644 (file)
@@ -2,16 +2,16 @@
 #define LIBMARKLIN_CATALOGUE_H_
 
 #include <map>
-#include <msp/parser/loader.h>
+#include <msp/datafile/loader.h>
 
 namespace Marklin {
 
-class Track;
+class TrackType;
 
 class Catalogue
 {
 public:
-       class Loader: public Msp::Parser::Loader
+       class Loader: public Msp::DataFile::Loader
        {
        public:
                Loader(Catalogue &);
@@ -20,14 +20,15 @@ public:
 
                void track(unsigned);
        };
-       typedef std::map<unsigned, Track *> TrackMap;
+private:
+       std::map<unsigned, TrackType *> tracks;
 
-       Track *get_track(unsigned);
-       const TrackMap &get_tracks() const { return tracks; }
-       void  load(const std::string &);
+public:
        ~Catalogue();
-private:
-       TrackMap tracks;
+
+       TrackType &get_track(unsigned);
+       const std::map<unsigned, TrackType *> &get_tracks() const { return tracks; }
+       void  load(const std::string &);
 };
 
 } // namespace Marklin
index 0ce16f088740524490e2f891b3d62561f588a309..02b8f0f16949a2aab1c5f49013de37e32bf10415 100644 (file)
@@ -2,7 +2,7 @@
 #include <termios.h>
 #include <sys/poll.h>
 #include <iostream>
-#include <msp/core/error.h>
+#include <msp/core/except.h>
 #include <msp/time/units.h>
 #include <msp/time/utils.h>
 #include "command.h"
@@ -30,32 +30,6 @@ void Control::set_power(bool p)
                command(string(1, CMD_POWER_OFF));
 }
 
-Turnout *Control::get_turnout(unsigned id) const
-{
-       TurnoutMap::const_iterator i=turnouts.find(id);
-       if(i!=turnouts.end())
-               return i->second;
-       
-       return 0;
-}
-
-Locomotive *Control::get_locomotive(unsigned id) const
-{
-       for(LocomotiveSeq::const_iterator i=locomotives.begin(); i!=locomotives.end(); ++i)
-               if((*i)->get_address()==id)
-                       return *i;
-       return 0;
-}
-
-Sensor *Control::get_sensor(unsigned id) const
-{
-       SensorMap::const_iterator i=sensors.find(id);
-       if(i!=sensors.end())
-               return i->second;
-       
-       return 0;
-}
-
 void Control::open(const string &dev)
 {
        serial_fd=::open(dev.c_str(), O_RDWR);
@@ -114,31 +88,56 @@ Command &Control::command(const string &cmd)
        return queue.back();
 }
 
-void Control::add_turnout(Turnout *t)
+void Control::add_turnout(Turnout &t)
 {
-       if(turnouts.count(t->get_address())==0)
-               turnouts.insert(TurnoutMap::value_type(t->get_address(), t));
+       turnouts[t.get_address()]=&t;
 }
 
-void Control::add_locomotive(Locomotive *l)
+Turnout &Control::get_turnout(unsigned id) const
 {
-       if(find(locomotives.begin(), locomotives.end(), l)==locomotives.end())
-               locomotives.push_back(l);
+       map<unsigned, Turnout *>::const_iterator i=turnouts.find(id);
+       if(i==turnouts.end())
+               throw KeyError("Unknown turnout");
+
+       return *i->second;
 }
 
-void Control::add_sensor(Sensor *s)
+void Control::add_locomotive(Locomotive &l)
 {
-       if(sensors.count(s->get_address())==0)
-       {
-               sensors.insert(SensorMap::value_type(s->get_address(), s));
-               poll_sensors=true;
-       }
+       locomotives[l.get_address()]=&l;
+}
+
+Locomotive &Control::get_locomotive(unsigned id) const
+{
+       map<unsigned, Locomotive *>::const_iterator i=locomotives.find(id);
+       if(i==locomotives.end())
+               throw KeyError("Unknown locomotive");
+
+       return *i->second;
+}
+
+void Control::add_sensor(Sensor &s)
+{
+       sensors[s.get_address()]=&s;
+       poll_sensors=true;
+}
+
+Sensor &Control::get_sensor(unsigned id) const
+{
+       map<unsigned, Sensor *>::const_iterator i=sensors.find(id);
+       if(i==sensors.end())
+               throw KeyError("Unknown sensor");
+
+       return *i->second;
 }
 
 void Control::tick()
 {
        const Time::TimeStamp t=Time::now();
 
+       for(map<unsigned, Sensor *>::const_iterator i=sensors.begin(); i!=sensors.end(); ++i)
+               i->second->tick();
+
        if(t>next_event_query)
        {
                next_event_query=t+300*Time::msec;
@@ -203,14 +202,19 @@ void Control::tick()
        }
 }
 
+Time::Timer::Slot &Control::set_timer(const Time::TimeDelta &dt)
+{
+       return timer.add(dt);
+}
+
 Control::~Control()
 {
-       for(SensorMap::iterator i=sensors.begin(); i!=sensors.end(); ++i)
+       for(map<unsigned, Sensor *>::iterator i=sensors.begin(); i!=sensors.end(); ++i)
+               delete i->second;
+       for(map<unsigned, Turnout *>::iterator i=turnouts.begin(); i!=turnouts.end(); ++i)
                delete i->second;
-       for(TurnoutMap::iterator i=turnouts.begin(); i!=turnouts.end(); ++i)
+       for(map<unsigned, Locomotive *>::iterator i=locomotives.begin(); i!=locomotives.end(); ++i)
                delete i->second;
-       for(LocomotiveSeq::iterator i=locomotives.begin(); i!=locomotives.end(); ++i)
-               delete *i;
        close(serial_fd);
 }
 
index 62d64f9a8063c645ae5ccc20bdcb804acc185f87..4729695d7dbeb10d00e40f13578877a9f8493f61 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <list>
 #include <string>
+#include <msp/time/timer.h>
 #include <msp/time/timestamp.h>
 #include "constants.h"
 #include "sensor.h"
@@ -15,38 +16,42 @@ class Command;
 
 class Control
 {
+private:
+       int  serial_fd;
+       bool p50_enabled;
+       bool power;
+       std::list<Command> queue;
+       std::map<unsigned, Turnout *> turnouts;
+       std::map<unsigned, Locomotive *> locomotives;
+       std::map<unsigned, Sensor *> sensors;
+       Msp::Time::TimeStamp next_event_query;
+       bool poll_sensors;
+       bool debug;
+       Msp::Time::Timer timer;
+
 public:
        sigc::signal<void, unsigned, bool> signal_turnout_event;
        sigc::signal<void, unsigned, bool> signal_sensor_event;
 
        Control();
        void       set_power(bool);
-       void       set_debug(bool d) { debug=d; }
        bool       get_power() const { return power; }
-       const TurnoutMap &get_turnouts() const { return turnouts; }
-       Turnout    *get_turnout(unsigned) const;
-       Locomotive *get_locomotive(unsigned) const;
-       Sensor     *get_sensor(unsigned) const;
+       void       set_debug(bool d) { debug=d; }
+       //const TurnoutMap &get_turnouts() const { return turnouts; }
+       const std::map<unsigned, Sensor *> &get_sensors() const { return sensors; }
        unsigned   get_queue_length() const { return queue.size(); }
        void       open(const std::string &);
        Command    &command(const std::string &);
-       void       add_turnout(Turnout *);
-       void       add_locomotive(Locomotive *);
-       void       add_sensor(Sensor *);
+       void       add_turnout(Turnout &);
+       Turnout    &get_turnout(unsigned) const;
+       void       add_locomotive(Locomotive &);
+       Locomotive &get_locomotive(unsigned) const;
+       void       add_sensor(Sensor &);
+       Sensor     &get_sensor(unsigned) const;
        void       tick();
+       Msp::Time::Timer::Slot &set_timer(const Msp::Time::TimeDelta &);
        ~Control();
 private:
-       int  serial_fd;
-       bool p50_enabled;
-       bool power;
-       std::list<Command> queue;
-       TurnoutMap turnouts;
-       LocomotiveSeq locomotives;
-       SensorMap sensors;
-       Msp::Time::TimeStamp next_event_query;
-       bool poll_sensors;
-       bool debug;
-
        void read_all(int, char *, int);
        std::string read_reply(Cmd);
        void event_query_done(Error, const std::string &);
diff --git a/source/libmarklin/endpoint.h b/source/libmarklin/endpoint.h
new file mode 100644 (file)
index 0000000..6a46831
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef MARKLIN_ENDPOINT_H_
+#define MARKLIN_ENDPOINT_H_
+
+namespace Marklin {
+
+struct Endpoint
+{
+       float  x, y;
+       float  dir;  // Direction outwards from the endpoint
+       unsigned routes;
+
+       Endpoint(): x(0), y(0), dir(0), routes(0) { }
+       Endpoint(float x_, float y_, float d, unsigned r): x(x_), y(y_), dir(d), routes(r) { }
+};
+
+} // namespace Marklin
+
+#endif
index 1fe06c7e4f5aed39948ae18e6ca9a46482545474..28d2eeb862ad85862e8cd45baab8291061d9261a 100644 (file)
@@ -1,8 +1,9 @@
-#include <algorithm>
 #include <fstream>
-#include <msp/parser/parser.h>
+#include <msp/core/refptr.h>
+#include <msp/datafile/parser.h>
 #include "catalogue.h"
 #include "layout.h"
+#include "tracktype.h"
 
 using namespace std;
 using namespace Msp;
@@ -13,50 +14,45 @@ Layout::Layout(Catalogue &c):
        catalogue(c)
 { }
 
-void Layout::add_track(Track *t)
+void Layout::add_track(Track &t)
 {
-       if(find(tracks.begin(), tracks.end(), t)==tracks.end())
-       {
-               tracks.push_back(t);
+       if(tracks.insert(&t).second)
                signal_track_added.emit(t);
-       }
 }
 
-void Layout::remove_track(Track *t)
+void Layout::remove_track(Track &t)
 {
-       TrackSeq::iterator i=remove_if(tracks.begin(), tracks.end(), bind1st(equal_to<Track *>(), t));
-       if(i!=tracks.end())
+       if(tracks.count(&t))
        {
-               tracks.erase(i, tracks.end());
+               tracks.erase(&t);
                signal_track_removed.emit(t);
        }
 }
 
 void Layout::check_links()
 {
-       for(TrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                (*i)->break_links();
 
-       for(TrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
-               for(TrackSeq::iterator j=i; j!=tracks.end(); ++j)
+       for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+               for(set<Track *>::iterator j=i; j!=tracks.end(); ++j)
                        if(j!=i)
                                (*i)->snap_to(**j, true);
 }
 
 void Layout::load(const string &fn)
 {
-       ifstream in(fn.c_str());
-       if(!in)
-               throw Exception("Couldn't open file");
+       IO::File in(fn);
+       IO::Buffered inb(in);
 
        filename=fn;
-       Parser::Parser parser(in, fn);
+       DataFile::Parser parser(inb, fn);
        Loader loader(*this);
        loader.load(parser);
 
        check_links();
 
-       for(TrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                (*i)->check_slope();
 }
 
@@ -69,9 +65,9 @@ int Layout::save(const string &fn)
 
        if(base.size())
                out<<"base \""<<base<<"\";\n";
-       for(TrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
-               out<<"track "<<(*i)->get_article_number()<<"\n{\n";
+               out<<"track "<<(*i)->get_type().get_article_number()<<"\n{\n";
                const Point &p=(*i)->get_position();
                out<<"\tposition "<<p.x<<' '<<p.y<<' '<<p.z<<";\n";
                out<<"\trotation "<<(*i)->get_rotation()<<";\n";
@@ -96,7 +92,7 @@ int Layout::save(const string &fn)
 
 Layout::~Layout()
 {
-       for(TrackSeq::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                delete *i;
 }
 
@@ -113,22 +109,11 @@ Layout::Loader::Loader(Layout &l):
 
 void Layout::Loader::track(unsigned art_nr)
 {
-       Track *tmpl=layout.catalogue.get_track(art_nr);
-       if(!tmpl)
-               throw Exception("Unknown track");
+       TrackType &type=layout.catalogue.get_track(art_nr);
 
-       Track *trk=tmpl->copy();
-       try
-       {
-               load_sub(*trk);
-       }
-       catch(Msp::Exception &e)
-       {
-               delete trk;
-               throw;
-       }
-       layout.tracks.push_back(trk);
-       layout.signal_track_added.emit(trk);
+       RefPtr<Track> trk=new Track(type);
+       load_sub(*trk);
+       layout.add_track(*trk.release());
 }
 
 } // namespace Marklin
index c292af6ed29167d47e2c7068cf3c939757d48187..d1844dee66bd5f387ff79fc7f2e1664c03536898 100644 (file)
@@ -2,7 +2,7 @@
 #define LIBMARKLIN_LAYOUT_H_
 
 #include <sigc++/sigc++.h>
-#include <msp/parser/loader.h>
+#include <msp/datafile/loader.h>
 #include "route.h"
 #include "track.h"
 
@@ -13,7 +13,7 @@ class Catalogue;
 class Layout
 {
 public:
-       class Loader: public Msp::Parser::Loader
+       class Loader: public Msp::DataFile::Loader
        {
        public:
                Loader(Layout &);
@@ -24,13 +24,13 @@ public:
                void track(unsigned);
        };
 
-       sigc::signal<void, Track *> signal_track_added;
-       sigc::signal<void, Track *> signal_track_removed;
+       sigc::signal<void, Track &> signal_track_added;
+       sigc::signal<void, Track &> signal_track_removed;
 
        Layout(Catalogue &);
-       const TrackSeq &get_tracks() const { return tracks; }
-       void  add_track(Track *);
-       void  remove_track(Track *);
+       const std::set<Track *> &get_tracks() const { return tracks; }
+       void  add_track(Track &);
+       void  remove_track(Track &);
        void  check_links();
        void  load(const std::string &);
        int   save(const std::string &);
@@ -39,8 +39,8 @@ private:
        Catalogue   &catalogue;
        std::string filename;
        std::string base;
-       TrackSeq    tracks;
-       RouteSeq    routes;
+       std::set<Track *> tracks;
+       //RouteSeq    routes;
 };
 
 } // namespace Marklin
index 6329196710583014bc76ee80028daf476bb77ef7..fe236a515f0fa783dbbb0f1e92022c9b86eb0ebb 100644 (file)
@@ -17,7 +17,7 @@ Locomotive::Locomotive(Control &c, unsigned a):
        reverse(false),
        funcs(0)
 {
-       control.add_locomotive(this);
+       control.add_locomotive(*this);
 
        refresh_status();
 }
@@ -38,7 +38,7 @@ void Locomotive::set_reverse(bool rev)
 
        if(speed)
        {
-               (new Time::Timer((500+speed*150)*Time::msec))->signal_timeout.connect(sigc::mem_fun(this, &Locomotive::reverse_timeout));
+               control.set_timer((500+speed*150)*Time::msec).signal_timeout.connect(sigc::mem_fun(this, &Locomotive::reverse_timeout));
                set_speed(0);
        }
        else
index 7142701a28e3c5d9e6d5552db523ba00c469e18f..4188df5e809dd3cbf756dbfc4b070700a900c8d3 100644 (file)
@@ -35,7 +35,6 @@ private:
        void     status_reply(Error, const std::string &);
        bool     reverse_timeout();
 };
-typedef std::list<Locomotive *> LocomotiveSeq;
 
 } // namespace Marklin
 
index f5b760265b5b30159fe44e2103ffe7691af81850..3fa82023117053e53dd275a613e240b5512b9d6b 100644 (file)
@@ -2,26 +2,29 @@
 #define LIBMARKLIN_ROUTE_H_
 
 #include <list>
+#include <map>
+#include <set>
 #include <string>
-#include "track.h"
 
 namespace Marklin {
 
+class Track;
+class Turnout;
+
 class Route
 {
 public:
        typedef std::map<unsigned, unsigned> TurnoutMap;
 
        Route();
-       const TurnoutMap &get_turnouts() const { return turnouts; }
+       const std::map<unsigned, Turnout *> &get_turnouts() const { return turnouts; }
        void add_track(Track *);
        ~Route();
 private:
        std::string name;
-       TrackSeq    tracks;
-       TurnoutMap  turnouts;
+       std::set<Track *> tracks;
+       std::map<unsigned, Turnout *> turnouts;
 };
-typedef std::list<Route *> RouteSeq;
 
 } // namespace Marklin
 
index f6913ba1b05a3173069a4cc63b5ba7f94537d097..6c213651e668c69929181dff42818c3ca22fbd66 100644 (file)
@@ -1,6 +1,10 @@
+#include <msp/time/utils.h>
+#include <msp/time/units.h>
 #include "control.h"
 #include "sensor.h"
 
+using namespace Msp;
+
 namespace Marklin {
 
 Sensor::Sensor(Control &c, unsigned a):
@@ -8,16 +12,42 @@ Sensor::Sensor(Control &c, unsigned a):
        addr(a),
        state(false)
 {
-       control.add_sensor(this);
+       control.add_sensor(*this);
        control.signal_sensor_event.connect(sigc::mem_fun(this, &Sensor::sensor_event));
 }
 
 void Sensor::sensor_event(unsigned a, bool s)
 {
-       if(a==addr && s!=state)
+       if(a==addr)
+       {
+               if(s)
+               {
+                       off_timeout=Time::TimeStamp();
+                       if(s!=state)
+                       {
+                               state=s;
+                               signal_state_changed.emit(state);
+                       }
+               }
+               else
+                       off_timeout=Time::now()+Time::sec;
+       }
+}
+
+void Sensor::tick()
+{
+       if(off_timeout)
        {
-               state=s;
-               signal_state_changed.emit(state);
+               const Time::TimeStamp t=Time::now();
+               if(t>off_timeout)
+               {
+                       off_timeout=Time::TimeStamp();
+                       if(state)
+                       {
+                               state=false;
+                               signal_state_changed.emit(state);
+                       }
+               }
        }
 }
 
index e5e1b43eea2dde6be8ebb2e295c7e71ad00c889f..d3db6367a2b7b40ed9d0a232906c2f23561b4513 100644 (file)
@@ -3,7 +3,8 @@
 
 #include <list>
 #include <map>
-#include <sigc++/sigc++.h>
+#include <sigc++/signal.h>
+#include <msp/time/timestamp.h>
 
 namespace Marklin {
 
@@ -17,15 +18,15 @@ public:
        Sensor(Control &, unsigned);
        unsigned get_address() const { return addr; }
        bool     get_state() const   { return state; }
+       void     tick();
 private:
        Control  &control;
        unsigned addr;
        bool     state;
+       Msp::Time::TimeStamp off_timeout;
 
        void sensor_event(unsigned, bool);
 };
-typedef std::list<Sensor *> SensorSeq;
-typedef std::map<unsigned, Sensor *> SensorMap;
 
 } // namespace Marklin
 
index 6f83e5b05238080c63a95fdbcd9d5182661f86f7..230b268fc22576bb3fdea0dbcb7c03c94ac1b515 100644 (file)
@@ -1,5 +1,6 @@
 #include <cmath>
 #include "track.h"
+#include "tracktype.h"
 
 using namespace std;
 using namespace Msp;
@@ -8,24 +9,19 @@ using namespace Msp;
 
 namespace Marklin {
 
-Track::Track(unsigned a):
-       art_nr(a),
+Track::Track(const TrackType &t):
+       type(t),
        rot(0),
        slope(0),
        flex(false),
        turnout_id(0),
-       sensor_id(0)
+       sensor_id(0),
+       links(t.get_endpoints().size())
 { }
 
 Track::~Track()
 {
-       for(EndpointSeq::iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
-               if(i->link)
-               {
-                       Track *trk=i->link;
-                       i->link=0;
-                       trk->break_link(*this);
-               }
+       break_links();
 }
 
 void Track::set_position(const Point &p)
@@ -44,83 +40,94 @@ void Track::set_rotation(float r)
 
 void Track::set_slope(float s)
 {
-       if(endpoints.size()!=2) return;
+       if(links.size()!=2) return;
 
        slope=s;
-       endpoints.back().pos.z=slope;
 }
 
-const Track::Endpoint *Track::get_endpoint_by_link(Track *other) const
+void Track::set_flex(bool f)
 {
-       for(EndpointSeq::const_iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
-               if(i->link==other)
-                       return &*i;
+       flex=f;
+}
 
-       return 0;
+void Track::set_turnout_id(unsigned i)
+{
+       turnout_id=i;
 }
 
-Point Track::get_endpoint_position(const Endpoint &ep) const
+void Track::set_sensor_id(unsigned i)
 {
-       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);
+       sensor_id=i;
 }
 
-float Track::get_length() const
+int Track::get_endpoint_by_link(const Track &other) const
 {
-       float len=parts.front().length;
-       if(parts.front().radius)
-               len*=parts.front().radius;
-       return len;
+       for(unsigned i=0; i<links.size(); ++i)
+               if(links[i]==&other)
+                       return i;
+
+       return -1;
 }
 
-float Track::get_total_length() const
+Point Track::get_endpoint_position(unsigned epi) const
 {
-       float len=0;
-       for(PartSeq::const_iterator i=parts.begin(); i!=parts.end(); ++i)
-       {
-               float l=i->length;
-               if(i->radius)
-                       l*=i->radius;
-               len+=l;
-       }
-       return len;
+       const vector<Endpoint> &eps=type.get_endpoints();
+       if(epi>=eps.size())
+               throw InvalidParameterValue("Endpoint index out of range");
+
+       const Endpoint &ep=eps[epi];
+
+       float c=cos(rot);
+       float s=sin(rot);
+
+       Point p(pos.x+c*ep.x-s*ep.y, pos.y+s*ep.x+c*ep.y, pos.z);
+       if(eps.size()==2 && epi==1)
+               p.z+=slope;
+       return p;
 }
 
-unsigned Track::get_n_routes() const
+float Track::get_endpoint_direction(unsigned epi) const
 {
-       unsigned n=1;
-       for(PartSeq::const_iterator i=parts.begin(); i!=parts.end(); ++i)
-               if(i->route>=n)
-                       n=i->route+1;
-       return n;
+       const vector<Endpoint> &eps=type.get_endpoints();
+       if(epi>=eps.size())
+               throw InvalidParameterValue("Endpoint index out of range");
+
+       const Endpoint &ep=eps[epi];
+
+       return rot+ep.dir;
 }
 
 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)
+       const vector<Endpoint> &eps=type.get_endpoints();
+       const vector<Endpoint> &other_eps=other.get_type().get_endpoints();
+
+       for(unsigned i=0; i<eps.size(); ++i)
        {
-               Point epp=get_endpoint_position(*i);
-               for(EndpointSeq::iterator j=other.endpoints.begin(); j!=other.endpoints.end(); ++j)
+               Point epp=get_endpoint_position(i);
+
+               for(unsigned j=0; j<other_eps.size(); ++j)
                {
-                       if(j->link)
+                       if(other.get_link(j))
                                continue;
 
-                       Point epp2=other.get_endpoint_position(*j);
+                       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(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));
+                               set_rotation(other.rot+other_eps[j].dir-eps[i].dir+M_PI);
+                               set_position(Point(epp2.x-(eps[i].x*cos(rot)-eps[i].y*sin(rot)), epp2.y-(eps[i].y*cos(rot)+eps[i].x*sin(rot)), epp2.z));
+
                                if(link)
                                {
-                                       if(i->link)
-                                               break_link(*i->link);
-                                       i->link=&other;
-                                       j->link=this;
+                                       if(links[i])
+                                               break_link(*links[i]);
+                                       links[i]=&other;
+                                       other.links[j]=this;
                                }
+
                                return true;
                        }
                }
@@ -131,15 +138,17 @@ bool Track::snap_to(Track &other, bool link)
 
 bool Track::snap(Point &pt, float &d) const
 {
-       for(EndpointSeq::const_iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
+       const vector<Endpoint> &eps=type.get_endpoints();
+
+       for(unsigned i=0; i<eps.size(); ++i)
        {
-               Point epp=get_endpoint_position(*i);
+               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=epp;
-                       d=rot+i->rot;
+                       d=rot+eps[i].dir;
                        return true;
                }
        }
@@ -149,10 +158,10 @@ bool Track::snap(Point &pt, float &d) const
 
 void Track::break_link(Track &trk)
 {
-       for(EndpointSeq::iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
-               if(i->link==&trk)
+       for(vector<Track *>::iterator i=links.begin(); i!=links.end(); ++i)
+               if(*i==&trk)
                {
-                       i->link=0;
+                       *i=0;
                        trk.break_link(*this);
                        return;
                }
@@ -160,122 +169,87 @@ void Track::break_link(Track &trk)
 
 void Track::break_links()
 {
-       for(EndpointSeq::iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
-               if(i->link)
+       for(vector<Track *>::iterator i=links.begin(); i!=links.end(); ++i)
+               if(Track *trk=*i)
                {
-                       Track *trk=i->link;
-                       i->link=0;
+                       *i=0;
                        trk->break_link(*this);
                }
 }
 
+Track *Track::get_link(unsigned i) const
+{
+       if(i>links.size())
+               throw InvalidParameterValue("Link index out of range");
+
+       return links[i];
+}
+
 void Track::check_slope()
 {
-       if(endpoints.size()!=2)
+       if(links.size()!=2)
                return;
 
-       Track *link1=endpoints.front().link;
-       Track *link2=endpoints.back().link;
-       if(link1 && link2)
+       if(links[0] && links[1])
        {
-               const Endpoint *ep1=link1->get_endpoint_by_link(this);
-               const Endpoint *ep2=link2->get_endpoint_by_link(this);
-               pos.z=link1->pos.z+ep1->pos.z;
-               slope=(link2->pos.z+ep2->pos.z)-pos.z;
+               Point epp0=links[0]->get_endpoint_position(links[0]->get_endpoint_by_link(*this));
+               Point epp1=links[1]->get_endpoint_position(links[1]->get_endpoint_by_link(*this));
+               pos.z=epp0.z;
+               slope=epp1.z-pos.z;
        }
        else
        {
                slope=0;
-               if(link1)
+               if(links[0])
                {
-                       const Endpoint *ep=link1->get_endpoint_by_link(this);
-                       pos.z=link1->pos.z+ep->pos.z;
+                       Point epp=links[0]->get_endpoint_position(links[0]->get_endpoint_by_link(*this));
+                       pos.z=epp.z;
                }
-               else if(link2)
+               else if(links[1])
                {
-                       const Endpoint *ep=link2->get_endpoint_by_link(this);
-                       pos.z=link2->pos.z+ep->pos.z;
+                       Point epp=links[1]->get_endpoint_position(links[1]->get_endpoint_by_link(*this));
+                       pos.z=epp.z;
                }
        }
-
-       endpoints.back().pos.z=slope;
 }
 
-const Track::Endpoint *Track::traverse(const Endpoint *ep, unsigned route) const
+int Track::traverse(unsigned i, unsigned route) const
 {
-       if(ep->routes&(1<<route))
+       const vector<Endpoint> &eps=type.get_endpoints();
+       if(i>=eps.size())
+               throw InvalidParameterValue("Endpoint index out of range");
+
+       const Endpoint &ep=eps[i];
+       
+       if(ep.routes&(1<<route))
        {
                // Find the other endpoint for this route
-               for(EndpointSeq::const_iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
-                       if((i->routes&(1<<route)) && &*i!=ep)
-                               return &*i;
+               for(unsigned j=0; j<eps.size(); ++j)
+                       if((eps[j].routes&(1<<route)) && j!=i)
+                               return j;
        }
        else
        {
                // Find an endpoint that's connected to this one and has the requested route
-               for(EndpointSeq::const_iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
-                       if((i->routes&(1<<route)) && (i->routes&ep->routes))
-                               return &*i;
+               for(unsigned j=0; j<eps.size(); ++j)
+                       if((eps[j].routes&(1<<route)) && (eps[j].routes&ep.routes))
+                               return j;
        }
 
-       return 0;
+       return -1;
 }
 
 Track *Track::copy() const
 {
-       Track *trk=new Track(*this);
-       for(EndpointSeq::iterator i=trk->endpoints.begin(); i!=trk->endpoints.end(); ++i)
-               i->link=0;
-       trk->turnout_id=0;
-       trk->sensor_id=0;
+       Track *trk=new Track(type);
+       trk->set_position(pos);
+       trk->set_rotation(rot);
+       trk->set_slope(slope);
+       trk->set_flex(flex);
 
        return trk;
 }
 
-/*** private ***/
-
-void Track::collect_endpoints()
-{
-       endpoints.clear();
-
-       for(PartSeq::iterator i=parts.begin(); i!=parts.end(); ++i)
-               i->collect_endpoints(endpoints);
-       endpoints.back().pos.z=slope;
-
-       for(EndpointSeq::iterator i=endpoints.begin(); i!=endpoints.end();)
-       {
-               bool rm=false;
-               for(EndpointSeq::iterator j=i; j!=endpoints.end();)
-               {
-                       if(j==i)
-                       {
-                               ++j;
-                               continue;
-                       }
-                       float dx=i->pos.x-j->pos.x;
-                       float dy=i->pos.y-j->pos.y;
-                       if(dx*dx+dy*dy<0.0001)
-                       {
-                               float da=i->rot-j->rot;
-                               if(da<-M_PI)
-                                       da+=M_PI*2;
-                               if(da>M_PI)
-                                       da-=M_PI*2;
-                               if(da<-3 || da>3)
-                                       rm=true;
-                               i->routes|=j->routes;
-                               j=endpoints.erase(j);
-                       }
-                       else
-                               ++j;
-               }
-               if(rm)
-                       i=endpoints.erase(i);
-               else
-                       ++i;
-       }
-}
-
 /*******************
 ** Track::Loader
 */
@@ -283,8 +257,6 @@ void Track::collect_endpoints()
 Track::Loader::Loader(Track &t):
        track(t)
 {
-       add("description", &Track::description);
-       add("part",        &Loader::part);
        add("position",    &Loader::position);
        add("rotation",    &Track::rot);
        add("slope",       &Track::slope);
@@ -293,85 +265,9 @@ Track::Loader::Loader(Track &t):
        add("flex",        &Track::flex);
 }
 
-Track::Loader::~Loader()
-{
-       track.collect_endpoints();
-}
-
-void Track::Loader::part()
-{
-       Part p;
-       load_sub(p);
-       track.parts.push_back(p);
-}
-
 void Track::Loader::position(float x, float y, float z)
 {
        track.pos=Point(x, y, z);
 }
 
-/*******************
-** Track::Part
-*/
-
-Track::Part::Part():
-       x(0),
-       y(0),
-       dir(0),
-       length(0),
-       radius(0),
-       route(0),
-       dead_end(false)
-{ }
-
-void Track::Part::collect_endpoints(EndpointSeq &epl)
-{
-       epl.push_back(Endpoint(Point(x, y, 0), dir+M_PI, 1<<route));
-       if(dead_end)
-               return;
-       else if(radius)
-       {
-               float a=(radius<0)?-length:length;
-               float c=cos(a);
-               float s=sin(a);
-               float rx=radius*sin(dir);
-               float ry=-radius*cos(dir);
-               epl.push_back(Endpoint(Point(x+c*rx-s*ry-rx, y+c*ry+s*rx-ry, 0), dir+a, 1<<route));
-       }
-       else
-               epl.push_back(Endpoint(Point(x+cos(dir)*length, y+sin(dir)*length, 0), dir, 1<<route));
-}
-
-Track::Part::Loader::Loader(Part &p):
-       part(p)
-{
-       add("start",    &Loader::start);
-       add("length",   &Part::length);
-       add("radius",   &Part::radius);
-       add("route",    &Part::route);
-       add("dead_end", &Part::dead_end);
-}
-
-Track::Part::Loader::~Loader()
-{
-       if(part.radius)
-       {
-               part.length*=M_PI/180;
-               part.radius/=1000;
-       }
-       else
-               part.length/=1000;
-
-       part.x/=1000;
-       part.y/=1000;
-       part.dir*=M_PI/180;
-}
-
-void Track::Part::Loader::start(float x, float y, float d)
-{
-       part.x=x;
-       part.y=y;
-       part.dir=d;
-}
-
 } // namespace Marklin
index 6bddd4dad01518676062db707caab0b173d19ff9..13a98bf51b268d4772dff9d1c7111df54fbea967 100644 (file)
@@ -3,93 +3,66 @@
 
 #include <list>
 #include <set>
-#include <msp/parser/loader.h>
+#include <msp/datafile/loader.h>
 #include "geometry.h"
 
 namespace Marklin {
 
+class TrackType;
+
 class Track
 {
 public:
-       class Loader: public Msp::Parser::Loader
+       class Loader: public Msp::DataFile::Loader
        {
+       private:
+               Track &track;
+
        public:
                Loader(Track &);
                Track &get_object() { return track; }
-               ~Loader();
        private:
-               Track &track;
-
-               void part();
                void position(float, float, float);
        };
 
-       struct Endpoint
-       {
-               Point  pos;
-               float  rot;
-               Track *link;
-               unsigned routes;
-
-               Endpoint(const Point &p, float r, unsigned o): pos(p), rot(r), link(0), routes(o) { }
-       };
-       typedef std::list<Endpoint> EndpointSeq;
-
-       struct Part
-       {
-               class Loader: public Msp::Parser::Loader
-               {
-               public:
-                       Loader(Part &);
-                       Part &get_object() { return part; }
-                       ~Loader();
-               private:
-                       Part &part;
-
-                       void start(float, float, float);
-               };
-
-               float    x,y;
-               float    dir;
-               float    length;
-               float    radius;
-               unsigned route;
-               bool     dead_end;
-
-               Part();
-               void collect_endpoints(EndpointSeq &);
-       };
-       typedef std::list<Part> PartSeq;
+private:
+       const TrackType &type;
+       Point        pos;
+       float        rot;
+       float        slope;
+       bool         flex;
+       unsigned     turnout_id;
+       unsigned     sensor_id;
+       std::vector<Track *> links;
 
-       Track(unsigned);
+public:
+       Track(const TrackType &);
        ~Track();
-       void               set_position(const Point &);
-       void               set_rotation(float);
-       void               set_slope(float);
-       void               set_flex(bool f)           { flex=f; }
-       void               set_turnout_id(unsigned i) { turnout_id=i; }
-       void               set_sensor_id(unsigned i)  { sensor_id=i; }
-       const Point        &get_position() const      { return pos; }
-       float              get_rotation() const       { return rot; }
-       unsigned           get_article_number() const { return art_nr; }
-       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; }
-       float              get_length() const;
-       float              get_total_length() const;
-       unsigned           get_turnout_id() const     { return turnout_id; }
-       unsigned           get_sensor_id() const      { return sensor_id; }
-       unsigned           get_n_routes() const;
-       bool               snap_to(Track &, bool);
-       bool               snap(Point &, float &) const;
-       void               break_link(Track &);
-       void               break_links();
-       void               check_slope();
-       const Endpoint     *traverse(const Endpoint *, unsigned) const;
+
+       const TrackType &get_type() const { return type; }
+       void            set_position(const Point &);
+       const Point     &get_position() const      { return pos; }
+       void            set_rotation(float);
+       float           get_rotation() const       { return rot; }
+       void            set_slope(float);
+       float           get_slope() const          { return slope; }
+       void            set_flex(bool);
+       bool            get_flex() const           { return flex; }
+       void            set_turnout_id(unsigned);
+       unsigned        get_turnout_id() const     { return turnout_id; }
+       void            set_sensor_id(unsigned);
+       unsigned        get_sensor_id() const      { return sensor_id; }
+       int             get_endpoint_by_link(const Track &) const;
+       Point           get_endpoint_position(unsigned) const;
+       float           get_endpoint_direction(unsigned) const;
+       bool            snap_to(Track &, bool);
+       bool            snap(Point &, float &) const;
+       void            break_link(Track &);
+       void            break_links();
+       const std::vector<Track *> &get_links() const { return links; }
+       Track           *get_link(unsigned) const;
+       void            check_slope();
+       int             traverse(unsigned, unsigned) const;
 
        /**
        Creates a copy of the track.  The new track will be almost identical, but
@@ -97,25 +70,11 @@ public:
        */
        Track *copy() const;
 private:
-       unsigned     art_nr;
-       std::string  description;
-       PartSeq      parts;
-       EndpointSeq  endpoints;
-       Point        pos;
-       float        rot;
-       float        slope;
-       bool         flex;
-       unsigned     turnout_id;
-       unsigned     sensor_id;
 
        // Direct copying not allowed due to links.  See the copy() function.
-       //Track(const Track &);
+       Track(const Track &);
        Track &operator=(const Track &);
-
-       void  collect_endpoints();
 };
-typedef std::list<Track *> TrackSeq;
-typedef std::set<Track *> TrackSet;
 
 } // namespace Marklin
 
diff --git a/source/libmarklin/trackpart.cpp b/source/libmarklin/trackpart.cpp
new file mode 100644 (file)
index 0000000..90bc30c
--- /dev/null
@@ -0,0 +1,70 @@
+#include <cmath>
+#include "trackpart.h"
+
+using namespace std;
+
+namespace Marklin {
+
+TrackPart::TrackPart():
+       x(0),
+       y(0),
+       dir(0),
+       length(0),
+       radius(0),
+       route(0),
+       dead_end(false)
+{ }
+
+void TrackPart::collect_endpoints(vector<Endpoint> &eps)
+{
+       eps.push_back(Endpoint(x, y, dir+M_PI, 1<<route));
+
+       if(dead_end)
+               ;
+       else if(radius)
+       {
+               float a=((radius<0) ? -length : length);
+               float c=cos(a);
+               float s=sin(a);
+               float rx=radius*sin(dir);
+               float ry=-radius*cos(dir);
+               eps.push_back(Endpoint(x+c*rx-s*ry-rx, y+c*ry+s*rx-ry, dir+a, 1<<route));
+       }
+       else
+               eps.push_back(Endpoint(x+cos(dir)*length, y+sin(dir)*length, dir, 1<<route));
+}
+
+
+TrackPart::Loader::Loader(TrackPart &p):
+       part(p)
+{
+       add("start",    &Loader::start);
+       add("length",   &TrackPart::length);
+       add("radius",   &TrackPart::radius);
+       add("route",    &TrackPart::route);
+       add("dead_end", &TrackPart::dead_end);
+}
+
+void TrackPart::Loader::finish()
+{
+       if(part.radius)
+       {
+               part.length*=M_PI/180;
+               part.radius/=1000;
+       }
+       else
+               part.length/=1000;
+
+       part.x/=1000;
+       part.y/=1000;
+       part.dir*=M_PI/180;
+}
+
+void TrackPart::Loader::start(float x, float y, float d)
+{
+       part.x=x;
+       part.y=y;
+       part.dir=d;
+}
+
+} // namespace Marklin
diff --git a/source/libmarklin/trackpart.h b/source/libmarklin/trackpart.h
new file mode 100644 (file)
index 0000000..092e586
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef MARKLIN_TRACKPART_H_
+#define MARKLIN_TRACKPART_H_
+
+#include <msp/datafile/loader.h>
+#include "endpoint.h"
+
+namespace Marklin {
+
+struct TrackPart
+{
+       class Loader: public Msp::DataFile::Loader
+       {
+       private:
+               TrackPart &part;
+
+       public:
+               Loader(TrackPart &);
+               TrackPart &get_object() { return part; }
+       private:
+               virtual void finish();
+
+               void start(float, float, float);
+       };
+
+       float    x, y;
+       float    dir;
+       float    length;
+       float    radius;
+       unsigned route;
+       bool     dead_end;
+
+       TrackPart();
+       void collect_endpoints(std::vector<Endpoint> &);
+};
+
+} // namespace Marklin
+
+#endif
diff --git a/source/libmarklin/tracktype.cpp b/source/libmarklin/tracktype.cpp
new file mode 100644 (file)
index 0000000..70d0316
--- /dev/null
@@ -0,0 +1,91 @@
+#include <cmath>
+#include "tracktype.h"
+
+using namespace std;
+
+namespace Marklin {
+
+TrackType::TrackType(unsigned a):
+       art_nr(a)
+{ }
+
+float TrackType::get_total_length() const
+{
+       float len=0;
+       for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
+       {
+               float l=i->length;
+               if(i->radius)
+                       l*=i->radius;
+               len+=l;
+       }
+       return len;
+}
+
+unsigned TrackType::get_n_routes() const
+{
+       unsigned n=1;
+       for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
+               if(i->route>=n)
+                       n=i->route+1;
+       return n;
+}
+
+void TrackType::collect_endpoints()
+{
+       endpoints.clear();
+
+       for(vector<TrackPart>::iterator i=parts.begin(); i!=parts.end(); ++i)
+               i->collect_endpoints(endpoints);
+
+       for(vector<Endpoint>::iterator i=endpoints.begin(); i!=endpoints.end();)
+       {
+               bool rm=false;
+               for(vector<Endpoint>::iterator j=i+1; j!=endpoints.end();)
+               {
+                       float dx=i->x-j->x;
+                       float dy=i->y-j->y;
+                       if(dx*dx+dy*dy<0.0001)
+                       {
+                               float da=i->dir-j->dir;
+                               if(da<-M_PI)
+                                       da+=M_PI*2;
+                               if(da>M_PI)
+                                       da-=M_PI*2;
+                               if(da<-3.1 || da>3.1)
+                                       rm=true;
+                               i->routes|=j->routes;
+                               j=endpoints.erase(j);
+                       }
+                       else
+                               ++j;
+               }
+
+               if(rm)
+                       i=endpoints.erase(i);
+               else
+                       ++i;
+       }
+}
+
+
+TrackType::Loader::Loader(TrackType &t):
+       ttype(t)
+{
+       add("description", &TrackType::description);
+       add("part",        &Loader::part);
+}
+
+void TrackType::Loader::finish()
+{
+       ttype.collect_endpoints();
+}
+
+void TrackType::Loader::part()
+{
+       TrackPart p;
+       load_sub(p);
+       ttype.parts.push_back(p);
+}
+
+} // namespace Marklin
diff --git a/source/libmarklin/tracktype.h b/source/libmarklin/tracktype.h
new file mode 100644 (file)
index 0000000..9822fb2
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef LIBMARKLIN_TRACKTYPE_H_
+#define LIBMARKLIN_TRACKTYPE_H_
+
+#include <msp/datafile/loader.h>
+#include "endpoint.h"
+#include "trackpart.h"
+
+namespace Marklin {
+
+class TrackType
+{
+public:
+       class Loader: public Msp::DataFile::Loader
+       {
+       private:
+               TrackType &ttype;
+
+       public:
+               Loader(TrackType &);
+               TrackType &get_object() { return ttype; }
+       private:
+               virtual void finish();
+
+               void part();
+               void position(float, float, float);
+       };
+
+private:
+       unsigned     art_nr;
+       std::string  description;
+       std::vector<TrackPart> parts;
+       std::vector<Endpoint> endpoints;
+
+public:
+       TrackType(unsigned);
+
+       unsigned get_article_number() const { return art_nr; }
+       const std::string &get_description() const { return description; }
+       float get_total_length() const;
+       unsigned get_n_routes() const;
+       const std::vector<TrackPart> &get_parts() const { return parts; }
+       const std::vector<Endpoint>  &get_endpoints() const { return endpoints; }
+
+private:
+       void  collect_endpoints();
+};
+
+} // namespace Marklin
+
+#endif
index 516f64fd0b00741ea65ee2572cbec2e501d44afc..cc2089b32780fdcc210bea450265ef606b69ee55 100644 (file)
@@ -11,27 +11,19 @@ TrafficManager::TrafficManager(Control &c, Layout &l):
        control(c),
        layout(l)
 {
-       const TrackSeq &tracks=layout.get_tracks();
+       const set<Track *> &tracks=layout.get_tracks();
 
-       TrackSet used_tracks;
-       for(TrackSeq::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       set<Track *> used_tracks;
+       for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
                if(unsigned tid=(*i)->get_turnout_id())
-               {
-                       Turnout *t=control.get_turnout(tid);
-                       if(!t)
-                               t=new Turnout(control, tid);
-                       //t->signal_route_changed.connect(sigc::mem_fun(*i, &Track::set_current_route));
-               }
+                       new Turnout(control, tid);
                if(unsigned sid=(*i)->get_sensor_id())
-               {
-                       Sensor *s=control.get_sensor(sid);
-                       if(!s)
-                               s=new Sensor(control, sid);
-               }
+                       new Sensor(control, sid);
+
                if(used_tracks.count(*i)==0)
                {
-                       Block *block=new Block(*this, *i);
+                       Block *block=new Block(*this, **i);
                        blocks.push_back(block);
                        used_tracks.insert(block->get_tracks().begin(), block->get_tracks().end());
                }
@@ -58,7 +50,7 @@ Block *TrafficManager::get_block_by_track(const Track *t) const
 {
        for(BlockSeq::const_iterator i=blocks.begin(); i!=blocks.end(); ++i)
        {
-               const TrackSet &tracks=(*i)->get_tracks();
+               const set<Track *> &tracks=(*i)->get_tracks();
                if(tracks.count(const_cast<Track *>(t)))
                        return *i;
        }
index 83b03e2ec8c4684af75ab4adf5ca49d2d80321cd..9db94448a72ac9068a4d5c7a64eedf551403174f 100644 (file)
@@ -25,8 +25,8 @@ public:
 private:
        Control &control;
        Layout &layout;
-       BlockSeq blocks;
-       TrainSeq trains;
+       std::list<Block *> blocks;
+       std::list<Train *> trains;
 
        void turnout_route_changed(unsigned, Turnout *);
 };
index fed1438b02cf064610c21c793b4b156842fce36b..c2e278cba2870c2543090b906fffdb505ff10f07 100644 (file)
@@ -13,7 +13,10 @@ Train::Train(TrafficManager &tm, Locomotive &l):
        target_speed(0)
 {
        trfc_mgr.add_train(this);
-       trfc_mgr.get_control().signal_sensor_event.connect(sigc::mem_fun(this, &Train::sensor_event));
+
+       const map<unsigned, Sensor *> &sensors=trfc_mgr.get_control().get_sensors();
+       for(map<unsigned, Sensor *>::const_iterator i=sensors.begin(); i!=sensors.end(); ++i)
+               i->second->signal_state_changed.connect(sigc::bind(sigc::mem_fun(this, &Train::sensor_event), i->second));
 }
 
 void Train::set_name(const string &n)
@@ -31,15 +34,15 @@ void Train::set_speed(unsigned speed)
        loco.set_speed(speed);
 }
 
-void Train::place(Block *block, const Block::Endpoint *entry)
+void Train::place(Block *block, unsigned entry)
 {
-       for(BlockRefSeq::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end();)
+       for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end();)
        {
                i->block->reserve(0);
                i=rsv_blocks.erase(i);
        }
 
-       for(BlockRefSeq::iterator i=cur_blocks.begin(); i!=cur_blocks.end();)
+       for(list<BlockRef>::iterator i=cur_blocks.begin(); i!=cur_blocks.end();)
        {
                i->block->reserve(0);
                i=cur_blocks.erase(i);
@@ -53,7 +56,7 @@ void Train::place(Block *block, const Block::Endpoint *entry)
 
 bool Train::free_block(Block *block)
 {
-       for(BlockRefSeq::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
+       for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
                if(i->block==block)
                {
                        while(i!=rsv_blocks.end())
@@ -67,14 +70,16 @@ bool Train::free_block(Block *block)
        return false;
 }
 
-void Train::sensor_event(unsigned addr, bool state)
+void Train::sensor_event(bool state, Sensor *sensor)
 {
        if(!loco.get_speed())
                return;
 
+       unsigned addr=sensor->get_address();
+
        if(state)
        {
-               BlockRefSeq::iterator i;
+               list<BlockRef>::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;
@@ -89,7 +94,7 @@ void Train::sensor_event(unsigned addr, bool state)
        else
        {
                cout<<"Finding blocks to free\n";
-               BlockRefSeq::iterator i;
+               list<BlockRef>::iterator i;
                for(i=cur_blocks.begin(); i!=cur_blocks.end(); ++i)
                        if(i->block->get_sensor_id()==addr)
                                break;
@@ -97,7 +102,7 @@ void Train::sensor_event(unsigned addr, bool state)
                {
                        cout<<"found\n";
                        ++i;
-                       for(BlockRefSeq::iterator j=cur_blocks.begin(); j!=i; ++j)
+                       for(list<BlockRef>::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";
@@ -119,15 +124,19 @@ bool Train::reserve_more()
 
        bool result=false;
        unsigned size=rsv_blocks.size();
-       while(size<5)
+       while(size<3)
        {
-               const Block::Endpoint *exit=last->block->traverse(last->entry);
-               if(exit && exit->link->reserve(this))
+               int exit=last->block->traverse(last->entry);
+               if(exit>=0) 
                {
-                       rsv_blocks.push_back(BlockRef(exit->link, exit->link->get_endpoint_by_link(last->block)));
-                       last=&rsv_blocks.back();
-                       ++size;
-                       result=true;
+                       Block *link=last->block->get_link(exit);
+                       if(link)
+                       {
+                               rsv_blocks.push_back(BlockRef(link, link->get_endpoint_by_link(*last->block)));
+                               last=&rsv_blocks.back();
+                               ++size;
+                               result=true;
+                       }
                }
                else
                        break;
index 23bd3cc1b09405fedfae44d62af17e10a40a8f6b..21f1382c8c7ba5704797cfae4cf9b248dd1afd62 100644 (file)
@@ -8,39 +8,40 @@
 namespace Marklin {
 
 class Locomotive;
+class Sensor;
 class TrafficManager;
 
 class Train: public sigc::trackable
 {
-public:
-       sigc::signal<void, const std::string &> signal_name_changed;
-
-       Train(TrafficManager &, Locomotive &);
-       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();
 private:
        struct BlockRef
        {
                Block *block;
-               const Block::Endpoint *entry;
+               unsigned entry;
 
-               BlockRef(Block *s, const Block::Endpoint *e): block(s), entry(e) { }
+               BlockRef(Block *s, unsigned e): block(s), entry(e) { }
        };
-       typedef std::list<BlockRef> BlockRefSeq;
 
        TrafficManager &trfc_mgr;
        std::string name;
        Locomotive &loco;
-       BlockRefSeq cur_blocks;
-       BlockRefSeq rsv_blocks;
+       std::list<BlockRef> cur_blocks;
+       std::list<BlockRef> rsv_blocks;
        unsigned target_speed;
 
-       void sensor_event(unsigned, bool);
+public:
+       sigc::signal<void, const std::string &> signal_name_changed;
+
+       Train(TrafficManager &, Locomotive &);
+       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 *, unsigned);
+       bool free_block(Block *);
+       void tick();
+private:
+       void sensor_event(bool, Sensor *);
        bool reserve_more();
 };
 typedef std::list<Train *> TrainSeq;
index eca9ae2f90ee6eca92a7f60c4346ca57a024af3a..a6e3f2d171739734e3a412cfb6ac9ec4436689a3 100644 (file)
@@ -15,7 +15,7 @@ Turnout::Turnout(Control &c, unsigned a):
        addr(a),
        route(0)
 {
-       control.add_turnout(this);
+       control.add_turnout(*this);
 
        control.signal_turnout_event.connect(sigc::mem_fun(this, &Turnout::turnout_event));
 
@@ -31,7 +31,7 @@ void Turnout::set_route(unsigned r)
        route=r;
 
        command(true);
-       (new Time::Timer(200*Time::msec))->signal_timeout.connect(sigc::mem_fun(this, &Turnout::switch_timeout));
+       control.set_timer(200*Time::msec).signal_timeout.connect(sigc::mem_fun(this, &Turnout::switch_timeout));
 
        signal_route_changed.emit(route);
 }
index edf1c03bc384ee95f83ed4fc521eac6cd9bd8f2c..801772b711d73f14781542971ad9104829ae6a91 100644 (file)
@@ -30,8 +30,6 @@ private:
        bool switch_timeout();
        void turnout_event(unsigned, bool);
 };
-typedef std::list<Turnout *> TurnoutSeq;
-typedef std::map<unsigned, Turnout *> TurnoutMap;
 
 } // namespace Marklin
 
index a87e2f8cab7a817db5d78ed36b6ae0bade96fe00..5f88780a7c02e937ca4fcfe4bc7cc36fcfa84f54 100644 (file)
@@ -1,9 +1,8 @@
-#include <fstream>
 #include <iostream>
 #include <map>
 #include <msp/core/getopt.h>
-#include <msp/parser/loader.h>
-#include <msp/parser/parser.h>
+#include <msp/datafile/loader.h>
+#include <msp/datafile/parser.h>
 
 using namespace std;
 using namespace Msp;
@@ -14,7 +13,7 @@ public:
        ShoppingList(int, char **);
        void print(ostream &);
 private:
-       class InventoryLoader: public Parser::Loader
+       class InventoryLoader: public DataFile::Loader
        {
        public:
                InventoryLoader(ShoppingList &);
@@ -24,7 +23,7 @@ private:
                void track(unsigned, unsigned);
        };
 
-       class LayoutLoader: public Parser::Loader
+       class LayoutLoader: public DataFile::Loader
        {
        public:
                LayoutLoader(ShoppingList &);
@@ -63,16 +62,16 @@ ShoppingList::ShoppingList(int argc, char **argv)
 
 void ShoppingList::load_inventory(const string &fn)
 {
-       ifstream in(fn.c_str());
-       Parser::Parser parser(in, fn);
+       IO::File in(fn);
+       DataFile::Parser parser(in, fn);
        InventoryLoader il(*this);
        il.load(parser);
 }
 
 void ShoppingList::load_layout(const string &fn)
 {
-       ifstream in(fn.c_str());
-       Parser::Parser parser(in, fn);
+       IO::File in(fn);
+       DataFile::Parser parser(in, fn);
        LayoutLoader ll(*this);
        ll.load(parser);
 }