From 52cbe8d99669f843f8f75c51128e2748584dd03a Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 30 May 2008 09:54:26 +0000 Subject: [PATCH] Major code refactoring: - 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 --- Build | 4 +- source/3d/layout.cpp | 10 +- source/3d/layout.h | 4 +- source/3d/track.cpp | 31 +-- source/3d/track.h | 4 +- source/designer/designer.cpp | 56 +++-- source/designer/designer.h | 2 +- source/designer/manipulator.cpp | 119 +++++----- source/designer/manipulator.h | 6 +- source/designer/measure.cpp | 5 +- source/designer/selection.cpp | 32 +-- source/designer/selection.h | 6 +- source/engineer/engineer.cpp | 166 +++++++++----- source/engineer/engineer.h | 12 +- source/engineer/trainpanel.cpp | 18 +- source/engineer/trainpanel.h | 1 + source/engineer/trainproperties.cpp | 33 ++- source/engineer/trainproperties.h | 13 +- source/libmarklin/block.cpp | 142 ++++++------ source/libmarklin/block.h | 36 +-- source/libmarklin/catalogue.cpp | 49 ++-- source/libmarklin/catalogue.h | 19 +- source/libmarklin/control.cpp | 90 ++++---- source/libmarklin/control.h | 43 ++-- source/libmarklin/endpoint.h | 18 ++ source/libmarklin/layout.cpp | 59 ++--- source/libmarklin/layout.h | 18 +- source/libmarklin/locomotive.cpp | 4 +- source/libmarklin/locomotive.h | 1 - source/libmarklin/route.h | 13 +- source/libmarklin/sensor.cpp | 38 +++- source/libmarklin/sensor.h | 7 +- source/libmarklin/track.cpp | 326 +++++++++------------------ source/libmarklin/track.h | 129 ++++------- source/libmarklin/trackpart.cpp | 70 ++++++ source/libmarklin/trackpart.h | 38 ++++ source/libmarklin/tracktype.cpp | 91 ++++++++ source/libmarklin/tracktype.h | 50 ++++ source/libmarklin/trafficmanager.cpp | 24 +- source/libmarklin/trafficmanager.h | 4 +- source/libmarklin/train.cpp | 41 ++-- source/libmarklin/train.h | 35 +-- source/libmarklin/turnout.cpp | 4 +- source/libmarklin/turnout.h | 2 - source/shoppinglist/main.cpp | 17 +- 45 files changed, 1065 insertions(+), 825 deletions(-) create mode 100644 source/libmarklin/endpoint.h create mode 100644 source/libmarklin/trackpart.cpp create mode 100644 source/libmarklin/trackpart.h create mode 100644 source/libmarklin/tracktype.cpp create mode 100644 source/libmarklin/tracktype.h diff --git a/Build b/Build index df11fe0..4d51961 100644 --- 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" diff --git a/source/3d/layout.cpp b/source/3d/layout.cpp index b90f553..18457f0 100644 --- a/source/3d/layout.cpp +++ b/source/3d/layout.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #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); diff --git a/source/3d/layout.h b/source/3d/layout.h index 09189ed..9970604 100644 --- a/source/3d/layout.h +++ b/source/3d/layout.h @@ -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 diff --git a/source/3d/track.cpp b/source/3d/track.cpp index e64f42e..d937084 100644 --- a/source/3d/track.cpp +++ b/source/3d/track.cpp @@ -1,6 +1,7 @@ #include #include #include +#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 &endpoints=track.get_type().get_endpoints(); + for(unsigned i=0; ilink); - 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 &parts=track.get_type().get_parts(); unsigned index=0; - for(Track::PartSeq::const_iterator i=parts.begin(); i!=parts.end(); ++i) + for(vector::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 profile; if(profile.empty()) diff --git a/source/3d/track.h b/source/3d/track.h index f38593e..a9154b7 100644 --- a/source/3d/track.h +++ b/source/3d/track.h @@ -3,7 +3,9 @@ #include #include +#include #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 Track3DSeq; diff --git a/source/designer/designer.cpp b/source/designer/designer.cpp index d0bc940..9edf816 100644 --- a/source/designer/designer.cpp +++ b/source/designer/designer.cpp @@ -5,12 +5,14 @@ #include #include #include +#include #include #include #include #include #include #include +#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 &ctracks=catalogue.get_tracks(); unsigned n=0; - for(Catalogue::TrackMap::const_iterator i=ctracks.begin(); i!=ctracks.end(); ++i, ++n) + for(map::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<(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 &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::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) + len+=(*i)->get_type().get_total_length(); cout<<"Total length: "<get_tracks(); + set tracks=selection->get_tracks(); selection->clear(); - for(Selection::TrackSet::iterator i=tracks.begin(); i!=tracks.end(); ++i) + for(set::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 <racks=layout->get_tracks(); - for(Selection::TrackSet::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) + const set &tracks=selection->get_tracks(); + const set <racks=layout->get_tracks(); + for(set::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::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<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<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(status); + tooltip=status; } void Designer::manipulation_done(bool) @@ -603,7 +611,7 @@ void Designer::measure_changed() ostringstream ss; ss.precision(3); ss<<"Par "<(ss.str()); + tooltip=ss.str(); } void Designer::measure_done() diff --git a/source/designer/designer.h b/source/designer/designer.h index ece41a5..553b25c 100644 --- a/source/designer/designer.h +++ b/source/designer/designer.h @@ -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; diff --git a/source/designer/manipulator.cpp b/source/designer/manipulator.cpp index cbeb982..e7ccead 100644 --- a/source/designer/manipulator.cpp +++ b/source/designer/manipulator.cpp @@ -2,6 +2,7 @@ #include #include #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 new_tracks; + for(vector::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::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::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::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::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::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::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 tracks2; + for(vector::iterator i=tracks.begin(); i!=tracks.end(); ++i) tracks2.push_back(i->track); float total_len=0; - TrackOrderSeq order; - Track *cur=neighbors.front(); + list order; + Track *cur=*neighbors.begin(); while(tracks2.size()) { bool rev=false; - for(TrackSeq::iterator i=tracks2.begin(); i!=tracks2.end(); ++i) + for(list::iterator i=tracks2.begin(); i!=tracks2.end(); ++i) { - const Track::EndpointSeq &epl=(*i)->get_endpoints(); - if(epl.front().link==cur) + const vector &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::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::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::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::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::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::iterator i=neighbors.begin(); i!=neighbors.end(); ++i) + for(vector::iterator j=tracks.begin(); j!=tracks.end(); ++j) j->track->break_link(**i); - const TrackSeq <racks=designer.get_layout()->get_tracks(); - for(TrackSeq::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i) + const set <racks=designer.get_layout()->get_tracks(); + for(set::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::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::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::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 <racks=designer.get_layout()->get_tracks(); + const set <racks=designer.get_layout()->get_tracks(); MTrack *snapped=0; - for(TrackSeq::const_iterator i=ltracks.begin(); (i!=ltracks.end() && !snapped); ++i) + for(set::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::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::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::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::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::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::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 &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::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::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::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 &links=i->track->get_links(); + for(vector::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::iterator k=tracks.begin(); (k!=tracks.end() && ok); ++k) + ok=(k->track!=*j); if(ok) - neighbors.push_back(j->link); + neighbors.insert(*j); } } } diff --git a/source/designer/manipulator.h b/source/designer/manipulator.h index 3a8882e..9e17384 100644 --- a/source/designer/manipulator.h +++ b/source/designer/manipulator.h @@ -42,7 +42,6 @@ private: MTrack(Marklin::Track *); }; - typedef std::list MTrackSeq; struct TrackOrder { @@ -51,7 +50,6 @@ private: TrackOrder(Marklin::Track *t, bool r): track(t), rev(r) { } }; - typedef std::list TrackOrderSeq; struct TrackWrap { @@ -63,7 +61,7 @@ private: Designer &designer; Selection *selection; - MTrackSeq tracks; + std::vector tracks; Marklin::Point center; std::list wrap; @@ -77,7 +75,7 @@ private: float angle; float rot_origin; int elev_origin; - Marklin::TrackSeq neighbors; + std::set neighbors; sigc::connection selection_changed_conn; void selection_changed(); diff --git a/source/designer/measure.cpp b/source/designer/measure.cpp index 6f1d7bc..82fca97 100644 --- a/source/designer/measure.cpp +++ b/source/designer/measure.cpp @@ -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 <racks=designer.get_layout()->get_tracks(); - for(TrackSeq::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i) + const set <racks=designer.get_layout()->get_tracks(); + for(set::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i) if((*i)->snap(pt, dir)) return; } diff --git a/source/designer/selection.cpp b/source/designer/selection.cpp index a693c0a..ed71547 100644 --- a/source/designer/selection.cpp +++ b/source/designer/selection.cpp @@ -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 new_tracks; + for(set::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 &links=(*i)->get_links(); + for(vector::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::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 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 &links=track->get_links(); + for(vector::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::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 &links=(*i)->get_links(); + for(vector::const_iterator j=links.begin(); j!=links.end(); ++j) + if(*j && tracks.insert(*j).second) changed=true; } diff --git a/source/designer/selection.h b/source/designer/selection.h index 36e4435..21c5de1 100644 --- a/source/designer/selection.h +++ b/source/designer/selection.h @@ -8,11 +8,9 @@ class Selection { public: - typedef std::set TrackSet; - sigc::signal signal_changed; - const TrackSet &get_tracks() const { return tracks; } + const std::set &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 tracks; }; #endif diff --git a/source/engineer/engineer.cpp b/source/engineer/engineer.cpp index ab95d02..d57deb7 100644 --- a/source/engineer/engineer.cpp +++ b/source/engineer/engineer.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include @@ -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 &args=getopt.get_args(); + const vector &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 &sensors=control.get_sensors(); + for(map::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 &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 &tracks=block.get_tracks(); + for(set::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 "<get_track().get_sensor_id()==addr) + const list <racks=layout_3d.get_tracks(); + for(list::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< Engineer::reg; diff --git a/source/engineer/engineer.h b/source/engineer/engineer.h index ac5ce2c..dc48e70 100644 --- a/source/engineer/engineer.h +++ b/source/engineer/engineer.h @@ -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 reg; }; diff --git a/source/engineer/trainpanel.cpp b/source/engineer/trainpanel.cpp index d46bd9d..be27cd4 100644 --- a/source/engineer/trainpanel.cpp +++ b/source/engineer/trainpanel.cpp @@ -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) diff --git a/source/engineer/trainpanel.h b/source/engineer/trainpanel.h index 5abec3b..d21e561 100644 --- a/source/engineer/trainpanel.h +++ b/source/engineer/trainpanel.h @@ -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; diff --git a/source/engineer/trainproperties.cpp b/source/engineer/trainproperties.cpp index 1aebea0..9b46ce4 100644 --- a/source/engineer/trainproperties.cpp +++ b/source/engineer/trainproperties.cpp @@ -1,26 +1,45 @@ #include +#include +#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(ent_addr->get_text())); + train->set_name(ent_name->get_text()); + } + signal_ok.emit(); } diff --git a/source/engineer/trainproperties.h b/source/engineer/trainproperties.h index 89b6e94..b63bc3d 100644 --- a/source/engineer/trainproperties.h +++ b/source/engineer/trainproperties.h @@ -5,14 +5,21 @@ #include #include +class Engineer; + class TrainProperties: public Msp::GLtk::Panel { public: - TrainProperties(Msp::GLtk::Resources &, Marklin::Train &); + sigc::signal 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 diff --git a/source/libmarklin/block.cpp b/source/libmarklin/block.cpp index b3a96e6..3bd251f 100644 --- a/source/libmarklin/block.cpp +++ b/source/libmarklin/block.cpp @@ -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 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 &links=track->get_links(); + for(unsigned i=0; iget_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; iroutes|=route; + unsigned route=1< 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; itrack; - 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(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::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::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::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 &visited) +void Block::find_routes(Track &track, unsigned track_ep, unsigned route, set &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 &eps=track.get_type().get_endpoints(); + for(unsigned i=0; ilink) 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::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), diff --git a/source/libmarklin/block.h b/source/libmarklin/block.h index 4a22aa9..f18ba8d 100644 --- a/source/libmarklin/block.h +++ b/source/libmarklin/block.h @@ -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 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 tracks; + std::vector 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 &get_tracks() const { return tracks; } + const std::vector &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 &); static unsigned next_id; }; diff --git a/source/libmarklin/catalogue.cpp b/source/libmarklin/catalogue.cpp index 3c8e279..00c2773 100644 --- a/source/libmarklin/catalogue.cpp +++ b/source/libmarklin/catalogue.cpp @@ -1,39 +1,37 @@ -#include -#include +#include +#include #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::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::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::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 trk=new TrackType(art_no); + load_sub(*trk); + unsigned art_nr=trk->get_article_number(); + cat.tracks.insert(map::value_type(art_nr, trk.release())); } } // namespace Marklin diff --git a/source/libmarklin/catalogue.h b/source/libmarklin/catalogue.h index 1a328bb..6277158 100644 --- a/source/libmarklin/catalogue.h +++ b/source/libmarklin/catalogue.h @@ -2,16 +2,16 @@ #define LIBMARKLIN_CATALOGUE_H_ #include -#include +#include 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 TrackMap; +private: + std::map 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 &get_tracks() const { return tracks; } + void load(const std::string &); }; } // namespace Marklin diff --git a/source/libmarklin/control.cpp b/source/libmarklin/control.cpp index 0ce16f0..02b8f0f 100644 --- a/source/libmarklin/control.cpp +++ b/source/libmarklin/control.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #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::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::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::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::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::iterator i=sensors.begin(); i!=sensors.end(); ++i) + delete i->second; + for(map::iterator i=turnouts.begin(); i!=turnouts.end(); ++i) delete i->second; - for(TurnoutMap::iterator i=turnouts.begin(); i!=turnouts.end(); ++i) + for(map::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); } diff --git a/source/libmarklin/control.h b/source/libmarklin/control.h index 62d64f9..4729695 100644 --- a/source/libmarklin/control.h +++ b/source/libmarklin/control.h @@ -3,6 +3,7 @@ #include #include +#include #include #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 queue; + std::map turnouts; + std::map locomotives; + std::map sensors; + Msp::Time::TimeStamp next_event_query; + bool poll_sensors; + bool debug; + Msp::Time::Timer timer; + public: sigc::signal signal_turnout_event; sigc::signal 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 &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 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 index 0000000..6a46831 --- /dev/null +++ b/source/libmarklin/endpoint.h @@ -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 diff --git a/source/libmarklin/layout.cpp b/source/libmarklin/layout.cpp index 1fe06c7..28d2eeb 100644 --- a/source/libmarklin/layout.cpp +++ b/source/libmarklin/layout.cpp @@ -1,8 +1,9 @@ -#include #include -#include +#include +#include #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(), 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::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::iterator i=tracks.begin(); i!=tracks.end(); ++i) + for(set::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::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 \""<::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 "<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::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 trk=new Track(type); + load_sub(*trk); + layout.add_track(*trk.release()); } } // namespace Marklin diff --git a/source/libmarklin/layout.h b/source/libmarklin/layout.h index c292af6..d1844de 100644 --- a/source/libmarklin/layout.h +++ b/source/libmarklin/layout.h @@ -2,7 +2,7 @@ #define LIBMARKLIN_LAYOUT_H_ #include -#include +#include #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 signal_track_added; - sigc::signal signal_track_removed; + sigc::signal signal_track_added; + sigc::signal signal_track_removed; Layout(Catalogue &); - const TrackSeq &get_tracks() const { return tracks; } - void add_track(Track *); - void remove_track(Track *); + const std::set &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 tracks; + //RouteSeq routes; }; } // namespace Marklin diff --git a/source/libmarklin/locomotive.cpp b/source/libmarklin/locomotive.cpp index 6329196..fe236a5 100644 --- a/source/libmarklin/locomotive.cpp +++ b/source/libmarklin/locomotive.cpp @@ -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 diff --git a/source/libmarklin/locomotive.h b/source/libmarklin/locomotive.h index 7142701..4188df5 100644 --- a/source/libmarklin/locomotive.h +++ b/source/libmarklin/locomotive.h @@ -35,7 +35,6 @@ private: void status_reply(Error, const std::string &); bool reverse_timeout(); }; -typedef std::list LocomotiveSeq; } // namespace Marklin diff --git a/source/libmarklin/route.h b/source/libmarklin/route.h index f5b7602..3fa8202 100644 --- a/source/libmarklin/route.h +++ b/source/libmarklin/route.h @@ -2,26 +2,29 @@ #define LIBMARKLIN_ROUTE_H_ #include +#include +#include #include -#include "track.h" namespace Marklin { +class Track; +class Turnout; + class Route { public: typedef std::map TurnoutMap; Route(); - const TurnoutMap &get_turnouts() const { return turnouts; } + const std::map &get_turnouts() const { return turnouts; } void add_track(Track *); ~Route(); private: std::string name; - TrackSeq tracks; - TurnoutMap turnouts; + std::set tracks; + std::map turnouts; }; -typedef std::list RouteSeq; } // namespace Marklin diff --git a/source/libmarklin/sensor.cpp b/source/libmarklin/sensor.cpp index f6913ba..6c21365 100644 --- a/source/libmarklin/sensor.cpp +++ b/source/libmarklin/sensor.cpp @@ -1,6 +1,10 @@ +#include +#include #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); + } + } } } diff --git a/source/libmarklin/sensor.h b/source/libmarklin/sensor.h index e5e1b43..d3db636 100644 --- a/source/libmarklin/sensor.h +++ b/source/libmarklin/sensor.h @@ -3,7 +3,8 @@ #include #include -#include +#include +#include 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 SensorSeq; -typedef std::map SensorMap; } // namespace Marklin diff --git a/source/libmarklin/track.cpp b/source/libmarklin/track.cpp index 6f83e5b..230b268 100644 --- a/source/libmarklin/track.cpp +++ b/source/libmarklin/track.cpp @@ -1,5 +1,6 @@ #include #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; ilength; - if(i->radius) - l*=i->radius; - len+=l; - } - return len; + const vector &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 &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 &eps=type.get_endpoints(); + const vector &other_eps=other.get_type().get_endpoints(); + + for(unsigned i=0; ilink) + 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*dyrot-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 &eps=type.get_endpoints(); + + for(unsigned i=0; irot; + 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::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::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< &eps=type.get_endpoints(); + if(i>=eps.size()) + throw InvalidParameterValue("Endpoint index out of range"); + + const Endpoint &ep=eps[i]; + + if(ep.routes&(1<routes&(1<routes&(1<routes&ep->routes)) - return &*i; + for(unsigned j=0; jendpoints.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< #include -#include +#include #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 EndpointSeq; - - struct Part - { - class Loader: public Msp::Parser::Loader - { - public: - Loader(Part &); - Part &get_object() { return part; } - ~Loader(); - private: - 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 PartSeq; +private: + const TrackType &type; + Point pos; + float rot; + float slope; + bool flex; + unsigned turnout_id; + unsigned sensor_id; + std::vector 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 &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 TrackSeq; -typedef std::set TrackSet; } // namespace Marklin diff --git a/source/libmarklin/trackpart.cpp b/source/libmarklin/trackpart.cpp new file mode 100644 index 0000000..90bc30c --- /dev/null +++ b/source/libmarklin/trackpart.cpp @@ -0,0 +1,70 @@ +#include +#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 &eps) +{ + eps.push_back(Endpoint(x, y, dir+M_PI, 1< +#include "endpoint.h" + +namespace Marklin { + +struct TrackPart +{ + class Loader: public Msp::DataFile::Loader + { + private: + TrackPart ∂ + + 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 &); +}; + +} // namespace Marklin + +#endif diff --git a/source/libmarklin/tracktype.cpp b/source/libmarklin/tracktype.cpp new file mode 100644 index 0000000..70d0316 --- /dev/null +++ b/source/libmarklin/tracktype.cpp @@ -0,0 +1,91 @@ +#include +#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::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::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::iterator i=parts.begin(); i!=parts.end(); ++i) + i->collect_endpoints(endpoints); + + for(vector::iterator i=endpoints.begin(); i!=endpoints.end();) + { + bool rm=false; + for(vector::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 index 0000000..9822fb2 --- /dev/null +++ b/source/libmarklin/tracktype.h @@ -0,0 +1,50 @@ +#ifndef LIBMARKLIN_TRACKTYPE_H_ +#define LIBMARKLIN_TRACKTYPE_H_ + +#include +#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 parts; + std::vector 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 &get_parts() const { return parts; } + const std::vector &get_endpoints() const { return endpoints; } + +private: + void collect_endpoints(); +}; + +} // namespace Marklin + +#endif diff --git a/source/libmarklin/trafficmanager.cpp b/source/libmarklin/trafficmanager.cpp index 516f64f..cc2089b 100644 --- a/source/libmarklin/trafficmanager.cpp +++ b/source/libmarklin/trafficmanager.cpp @@ -11,27 +11,19 @@ TrafficManager::TrafficManager(Control &c, Layout &l): control(c), layout(l) { - const TrackSeq &tracks=layout.get_tracks(); + const set &tracks=layout.get_tracks(); - TrackSet used_tracks; - for(TrackSeq::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) + set used_tracks; + for(set::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 &tracks=(*i)->get_tracks(); if(tracks.count(const_cast(t))) return *i; } diff --git a/source/libmarklin/trafficmanager.h b/source/libmarklin/trafficmanager.h index 83b03e2..9db9444 100644 --- a/source/libmarklin/trafficmanager.h +++ b/source/libmarklin/trafficmanager.h @@ -25,8 +25,8 @@ public: private: Control &control; Layout &layout; - BlockSeq blocks; - TrainSeq trains; + std::list blocks; + std::list trains; void turnout_route_changed(unsigned, Turnout *); }; diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index fed1438..c2e278c 100644 --- a/source/libmarklin/train.cpp +++ b/source/libmarklin/train.cpp @@ -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 &sensors=trfc_mgr.get_control().get_sensors(); + for(map::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::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::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::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::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::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::iterator j=cur_blocks.begin(); j!=i; ++j) j->block->reserve(0); cur_blocks.erase(cur_blocks.begin(), i); cout<block->traverse(last->entry); - if(exit && 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; diff --git a/source/libmarklin/train.h b/source/libmarklin/train.h index 23bd3cc..21f1382 100644 --- a/source/libmarklin/train.h +++ b/source/libmarklin/train.h @@ -8,39 +8,40 @@ namespace Marklin { class Locomotive; +class Sensor; class TrafficManager; class Train: public sigc::trackable { -public: - sigc::signal 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 BlockRefSeq; TrafficManager &trfc_mgr; std::string name; Locomotive &loco; - BlockRefSeq cur_blocks; - BlockRefSeq rsv_blocks; + std::list cur_blocks; + std::list rsv_blocks; unsigned target_speed; - void sensor_event(unsigned, bool); +public: + sigc::signal 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 TrainSeq; diff --git a/source/libmarklin/turnout.cpp b/source/libmarklin/turnout.cpp index eca9ae2..a6e3f2d 100644 --- a/source/libmarklin/turnout.cpp +++ b/source/libmarklin/turnout.cpp @@ -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); } diff --git a/source/libmarklin/turnout.h b/source/libmarklin/turnout.h index edf1c03..801772b 100644 --- a/source/libmarklin/turnout.h +++ b/source/libmarklin/turnout.h @@ -30,8 +30,6 @@ private: bool switch_timeout(); void turnout_event(unsigned, bool); }; -typedef std::list TurnoutSeq; -typedef std::map TurnoutMap; } // namespace Marklin diff --git a/source/shoppinglist/main.cpp b/source/shoppinglist/main.cpp index a87e2f8..5f88780 100644 --- a/source/shoppinglist/main.cpp +++ b/source/shoppinglist/main.cpp @@ -1,9 +1,8 @@ -#include #include #include #include -#include -#include +#include +#include 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); } -- 2.43.0