From: Mikko Rasa Date: Sat, 20 Jul 2013 16:03:17 +0000 (+0300) Subject: New approach for displaying track state X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=5116fff210cdc3f0fbdae13046cc60450aad5e8f;p=r2c2.git New approach for displaying track state Paths can now be displayed over either rail in addition to the center of the track. Track circuit and allocation state are displayed separately, allowing more information to be shown. Instead of pre-creating a path for each track, only create them as needed. Local controller objects are much more manageable than bundling everything into one giant class. --- diff --git a/source/3d/allocation.cpp b/source/3d/allocation.cpp new file mode 100644 index 0000000..4bafb11 --- /dev/null +++ b/source/3d/allocation.cpp @@ -0,0 +1,74 @@ +#include "libr2c2/block.h" +#include "allocation.h" +#include "layout.h" +#include "path.h" +#include "track.h" + +using namespace Msp; + +namespace R2C2 { + +Allocation3D::Allocation3D(Layout3D &l, Train &t): + Utility3D(l), + train(t) +{ + layout.get_layout().signal_block_reserved.connect(sigc::mem_fun(this, &Allocation3D::block_reserved)); + train.signal_advanced.connect(sigc::mem_fun(this, &Allocation3D::train_advanced)); +} + +void Allocation3D::set_color(const GL::Color &c) +{ + color = c; + for(PathMap::const_iterator i=paths.begin(); i!=paths.end(); ++i) + { + float intensity = 0.5+train.get_block_allocator().is_block_current(*i->first)*0.5; + for(PathList::const_iterator j=i->second.begin(); j!=i->second.end(); ++j) + (*j)->set_color(color*intensity); + } +} + +void Allocation3D::block_reserved(Block &block, Train *t) +{ + if(t && t!=&train) + return; + + if(t) + { + if(paths.count(&block)) + return; + + PathList &bpaths = paths[&block]; + const Block::TrackSet &tracks = block.get_tracks(); + for(Block::TrackSet::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) + { + Path3D *path = new Path3D(layout.get(**i)); + bpaths.push_back(path); + path->set_layer(1); + float intensity = 0.5+train.get_block_allocator().is_block_current(block)*0.5; + path->set_color(color*intensity); + path->set_automatic(); + } + } + else + { + PathMap::iterator i = paths.find(&block); + if(i==paths.end()) + return; + + for(PathList::iterator j=i->second.begin(); j!=i->second.end(); ++j) + delete *j; + paths.erase(i); + } +} + +void Allocation3D::train_advanced(Block &block) +{ + PathMap::iterator i = paths.find(&block); + if(i==paths.end()) + return; + + for(PathList::iterator j=i->second.begin(); j!=i->second.end(); ++j) + (*j)->set_color(color); +} + +} // namespace R2C2 diff --git a/source/3d/allocation.h b/source/3d/allocation.h new file mode 100644 index 0000000..87ea309 --- /dev/null +++ b/source/3d/allocation.h @@ -0,0 +1,35 @@ +#ifndef R2C2_3D_ALLOCATION_H_ +#define R2C2_3D_ALLOCATION_H_ + +#include +#include "libr2c2/train.h" +#include "utility.h" + +namespace R2C2 { + +class Layout3D; +class Path3D; + +class Allocation3D: public Utility3D, public sigc::trackable +{ +private: + typedef std::list PathList; + typedef std::map PathMap; + + Train &train; + Msp::GL::Color color; + PathMap paths; + +public: + Allocation3D(Layout3D &, Train &); + + void set_color(const Msp::GL::Color &); + +private: + void block_reserved(Block &, Train *); + void train_advanced(Block &); +}; + +} // namespace R2C2 + +#endif diff --git a/source/3d/layout.cpp b/source/3d/layout.cpp index 1bbbed8..72e5052 100644 --- a/source/3d/layout.cpp +++ b/source/3d/layout.cpp @@ -2,6 +2,7 @@ #include "layout.h" #include "signal.h" #include "track.h" +#include "utility.h" #include "vehicle.h" using namespace std; @@ -27,6 +28,8 @@ Layout3D::Layout3D(Layout &l): Layout3D::~Layout3D() { + while(!utilities.empty()) + delete *utilities.begin(); while(!objects.empty()) delete objects.begin()->second; } @@ -57,6 +60,16 @@ void Layout3D::remove(Object3D &o) objects.erase(&o.get_object()); } +void Layout3D::add(Utility3D &u) +{ + utilities.insert(&u); +} + +void Layout3D::remove(Utility3D &u) +{ + utilities.erase(&u); +} + void Layout3D::object_added(Object &o) { if(Track *t = dynamic_cast(&o)) diff --git a/source/3d/layout.h b/source/3d/layout.h index df414f2..d5aad26 100644 --- a/source/3d/layout.h +++ b/source/3d/layout.h @@ -12,6 +12,7 @@ namespace R2C2 { class Object3D; +class Utility3D; class Layout3D: public sigc::trackable { @@ -22,6 +23,7 @@ private: Layout &layout; Catalogue3D catalogue; ObjectMap objects; + std::set utilities; Msp::GL::InstanceScene scene; Msp::GL::SimpleScene ep_scene; Msp::GL::InstanceScene path_scene; @@ -46,6 +48,9 @@ public: T &get(Object &o) const { return dynamic_cast(get(o)); } + void add(Utility3D &); + void remove(Utility3D &); + Msp::GL::Scene &get_scene() { return scene; } Msp::GL::Scene &get_endpoint_scene() { return ep_scene; } Msp::GL::Scene &get_path_scene() { return path_scene; } diff --git a/source/3d/path.cpp b/source/3d/path.cpp index 816631b..f9e51f4 100644 --- a/source/3d/path.cpp +++ b/source/3d/path.cpp @@ -12,17 +12,24 @@ using namespace Msp; namespace R2C2 { Path3D::Path3D(const Track3D &t): + Utility3D(t.get_layout()), track(t), - paths(0), + path(t.get_track().get_active_path()), + side(0), automatic(true), + mesh(0), z_offs(0) { - track.get_layout().get_path_scene().add(*this); + update_mesh(); + + layout.get_path_scene().add(*this); + if(track.get_track().get_type().is_turnout()) + track.get_track().signal_path_changed.connect(sigc::mem_fun(this, &Path3D::path_changed)); } Path3D::~Path3D() { - track.get_layout().get_path_scene().remove(*this); + layout.get_path_scene().remove(*this); } void Path3D::set_automatic() @@ -30,20 +37,19 @@ void Path3D::set_automatic() automatic = true; } -void Path3D::set_path(unsigned p) +void Path3D::set_path(int p) { - if(!(track.get_track().get_type().get_paths()&(1<=0 && !(track.get_track().get_type().get_paths()&(1<0 ? 1 : 0); + update_mesh(); } void Path3D::set_color(const GL::Color &c) @@ -53,7 +59,21 @@ void Path3D::set_color(const GL::Color &c) void Path3D::set_layer(float l) { - z_offs = l*track.get_track().get_layout().get_catalogue().get_gauge()*0.01; + z_offs = l*layout.get_layout().get_catalogue().get_gauge()*0.01; +} + +void Path3D::path_changed(unsigned p) +{ + if(automatic) + { + path = p; + update_mesh(); + } +} + +void Path3D::update_mesh() +{ + mesh = &track.get_type().get_path_mesh(path, side); } long Path3D::get_instance_key() const @@ -65,19 +85,12 @@ void Path3D::render(GL::Renderer &renderer, const GL::Tag &tag) const { if(tag=="unlit") { - unsigned mask = (automatic ? 1<>=1) - if(mask&1) - track.get_type().get_path_mesh(i).draw(renderer); + mesh->draw(renderer); } } diff --git a/source/3d/path.h b/source/3d/path.h index 58dae24..ceeb178 100644 --- a/source/3d/path.h +++ b/source/3d/path.h @@ -4,17 +4,20 @@ #include #include #include +#include "utility.h" namespace R2C2 { class Track3D; -class Path3D: public Msp::GL::Renderable +class Path3D: public Utility3D, public Msp::GL::Renderable, public sigc::trackable { private: const Track3D &track; - unsigned paths; + int path; + int side; bool automatic; + const Msp::GL::Mesh *mesh; Msp::GL::Color color; float z_offs; @@ -23,11 +26,15 @@ public: ~Path3D(); void set_automatic(); - void set_path(unsigned); - void set_mask(unsigned); + void set_path(int); + void set_side(int); void set_color(const Msp::GL::Color &); void set_layer(float); +private: + void path_changed(unsigned); + void update_mesh(); +public: virtual long get_instance_key() const; virtual void render(Msp::GL::Renderer &, const Msp::GL::Tag &) const; diff --git a/source/3d/track.cpp b/source/3d/track.cpp index 0fa6344..ee7671c 100644 --- a/source/3d/track.cpp +++ b/source/3d/track.cpp @@ -17,8 +17,7 @@ Track3D::Track3D(Layout3D &l, Track &t): Object3D(l, t), GL::ObjectInstance(l.get_catalogue().get_track(t.get_type()).get_object()), track(t), - type(layout.get_catalogue().get_track(track.get_type())), - path(new Path3D(*this)) + type(layout.get_catalogue().get_track(track.get_type())) { layout.get_scene().add(*this); @@ -37,8 +36,6 @@ Track3D::Track3D(Layout3D &l, Track &t): Track3D::~Track3D() { - delete path; - layout.get_scene().remove(*this); for(vector::iterator i=endpoints.begin(); i!=endpoints.end(); ++i) diff --git a/source/3d/track.h b/source/3d/track.h index c66a65f..9b70b63 100644 --- a/source/3d/track.h +++ b/source/3d/track.h @@ -21,7 +21,6 @@ private: Track &track; const TrackType3D &type; std::vector endpoints; - Path3D *path; public: Track3D(Layout3D &, Track &); @@ -30,7 +29,6 @@ public: Layout3D &get_layout() const { return layout; } Track &get_track() const { return track; } const TrackType3D &get_type() const { return type; } - Path3D &get_path() { return *path; } virtual Vector get_node() const; virtual bool is_visible() const { return true; } diff --git a/source/3d/trackcircuit.cpp b/source/3d/trackcircuit.cpp new file mode 100644 index 0000000..d74ee20 --- /dev/null +++ b/source/3d/trackcircuit.cpp @@ -0,0 +1,44 @@ +#include "libr2c2/blockiter.h" +#include "libr2c2/trackiter.h" +#include "layout.h" +#include "path.h" +#include "track.h" +#include "trackcircuit.h" + +using namespace std; +using namespace Msp; + +namespace R2C2 { + +TrackCircuit3D::TrackCircuit3D(Layout3D &l, TrackCircuit &tc): + Utility3D(l), + track_circuit(tc) +{ + Block *block = track_circuit.get_block(); + TrackIter iter = BlockIter(block, 0).track_iter(); + for(; (iter && &iter->get_block()==block); iter=iter.next()) + { + Path3D *path = new Path3D(layout.get(*iter)); + paths.push_back(path); + path->set_side(iter.entry()*2-1); + } + + track_circuit.signal_state_changed.connect(sigc::mem_fun(this, &TrackCircuit3D::state_changed)); + state_changed(track_circuit.get_state()); +} + +void TrackCircuit3D::state_changed(Sensor::State state) +{ + GL::Color color; + if(state>=Sensor::ACTIVE) + color = GL::Color(0.3f, 0.8f, 0.0f); + else if(state>Sensor::INACTIVE) + color = GL::Color(0.6f, 0.5f, 0.0f); + else + color = GL::Color(0.0f, 0.3f, 0.6f); + + for(list::const_iterator i=paths.begin(); i!=paths.end(); ++i) + (*i)->set_color(color); +} + +} // namespace R2C2 diff --git a/source/3d/trackcircuit.h b/source/3d/trackcircuit.h new file mode 100644 index 0000000..ae032b0 --- /dev/null +++ b/source/3d/trackcircuit.h @@ -0,0 +1,27 @@ +#ifndef R2C2_TRACKCIRCUIT_H_ +#define R2C2_TRACKCIRCUIT_H_ + +#include +#include "utility.h" + +namespace R2C2 { + +class Layout3D; +class Path3D; + +class TrackCircuit3D: public Utility3D, public sigc::trackable +{ +private: + TrackCircuit &track_circuit; + std::list paths; + +public: + TrackCircuit3D(Layout3D &, TrackCircuit &); + +private: + void state_changed(Sensor::State); +}; + +} // namespace R2C2 + +#endif diff --git a/source/3d/tracktype.cpp b/source/3d/tracktype.cpp index e402c89..f6b3d5f 100644 --- a/source/3d/tracktype.cpp +++ b/source/3d/tracktype.cpp @@ -57,28 +57,45 @@ TrackType3D::TrackType3D(Catalogue3D &cat3d, const TrackType &tt): own_data = true; } - + unsigned paths = tt.get_paths(); - for(unsigned i=0; paths; ++i, paths>>=1) + for(int i=-1; i<=1; ++i) { - GL::Mesh *m = 0; - if(paths&1) + // TODO Make profile width configurable + Profile profile; + if(i==0) + { + float rail_w = (rail_max.x-rail_min.x)*2; + profile.append_vertex(Vector(rail_w*-0.5, 0, 0), false); + profile.append_vertex(Vector(rail_w*0.5, 0, 0), false); + } + else { - m = new GL::Mesh(GL::VERTEX3); + profile.append_vertex(Vector(i*(gauge*0.5+rail_min.x*2), 0, 0), false); + profile.append_vertex(Vector(i*(gauge*0.5+rail_max.x*2), 0, 0), false); + } + + // TODO Avoid generating redundant meshes for single-path tracks + for(int j=-1; j<=4; ++j) + { + if(j>=0 && !((paths>>j)&1)) + continue; + + GL::Mesh *m = new GL::Mesh(GL::VERTEX3); GL::MeshBuilder bld(*m); unsigned index = 0; - for(vector::const_iterator j=parts.begin(); j!=parts.end(); ++j) - if(j->get_path()==i) - build_part(*j, cat.get_path_profile(), Vector(0, 0, ballast_h+1.5*rail_h), false, bld, index); + for(vector::const_iterator k=parts.begin(); k!=parts.end(); ++k) + if(j<0 || k->get_path()==static_cast(j)) + build_part(*k, profile, Vector(0, 0, ballast_h+1.5*rail_h), false, bld, index); + path_meshes[(j&0xFF)|((i&3)<<8)] = m; } - path_meshes.push_back(m); } } TrackType3D::~TrackType3D() { - for(vector::iterator i=path_meshes.begin(); i!=path_meshes.end(); ++i) - delete *i; + for(map::iterator i=path_meshes.begin(); i!=path_meshes.end(); ++i) + delete i->second; if(own_data) { delete object; @@ -86,13 +103,10 @@ TrackType3D::~TrackType3D() } } -const GL::Mesh &TrackType3D::get_path_mesh(unsigned p) const +const GL::Mesh &TrackType3D::get_path_mesh(int p, int s) const { - if(p>=path_meshes.size()) - throw out_of_range("TrackType3D::get_path_mesh"); - if(!path_meshes[p]) - throw invalid_argument("TrackType3D::get_path_mesh"); - return *path_meshes[p]; + unsigned key = (p<0 ? 0xFF : p) | ((s&3)<<8); + return *get_item(path_meshes, key); } void TrackType3D::build_part(const TrackPart &part, const Profile &profile, const Vector &offset, bool mirror, GL::MeshBuilder &bld, unsigned &base_index) diff --git a/source/3d/tracktype.h b/source/3d/tracktype.h index 952e898..27bf7fe 100644 --- a/source/3d/tracktype.h +++ b/source/3d/tracktype.h @@ -1,6 +1,7 @@ #ifndef R2C2_3D_TRACKTYPE_H_ #define R2C2_3D_TRACKTYPE_H_ +#include #include #include #include @@ -18,14 +19,14 @@ private: Msp::GL::Mesh *mesh; Msp::GL::Object *object; bool own_data; - std::vector path_meshes; + std::map path_meshes; public: TrackType3D(Catalogue3D &, const TrackType &); ~TrackType3D(); const Msp::GL::Object &get_object() const { return *object; } - const Msp::GL::Mesh &get_path_mesh(unsigned) const; + const Msp::GL::Mesh &get_path_mesh(int, int) const; private: void build_part(const TrackPart &, const Profile &, const Vector &, bool, Msp::GL::MeshBuilder &, unsigned &); diff --git a/source/3d/utility.cpp b/source/3d/utility.cpp new file mode 100644 index 0000000..d7026f2 --- /dev/null +++ b/source/3d/utility.cpp @@ -0,0 +1,17 @@ +#include "layout.h" +#include "utility.h" + +namespace R2C2 { + +Utility3D::Utility3D(Layout3D &l): + layout(l) +{ + layout.add(*this); +} + +Utility3D::~Utility3D() +{ + layout.remove(*this); +} + +} // namespace R2C2 diff --git a/source/3d/utility.h b/source/3d/utility.h new file mode 100644 index 0000000..f448164 --- /dev/null +++ b/source/3d/utility.h @@ -0,0 +1,20 @@ +#ifndef R2C2_3D_UTILITY_H_ +#define R2C2_3D_UTILITY_H_ + +namespace R2C2 { + +class Layout3D; + +class Utility3D +{ +protected: + Layout3D &layout; + + Utility3D(Layout3D &); +public: + virtual ~Utility3D(); +}; + +} // namespace R2C2 + +#endif diff --git a/source/designer/designer.cpp b/source/designer/designer.cpp index 930df58..3c3f83c 100644 --- a/source/designer/designer.cpp +++ b/source/designer/designer.cpp @@ -68,9 +68,6 @@ Designer::Designer(int argc, char **argv): layout = new Layout(catalogue); layout_3d = new Layout3D(*layout); - layout->signal_object_added.connect(sigc::mem_fun(this, &Designer::object_added)); - layout->signal_object_removed.connect(sigc::mem_fun(this, &Designer::object_removed)); - if(argc>1) { filename = argv[1]; @@ -361,10 +358,6 @@ void Designer::tick() root.tick(); camera_ctl->tick(dt); - for(list::iterator i=new_tracks.begin(); i!=new_tracks.end(); ++i) - layout_3d->get(**i).get_path().set_mask(0); - new_tracks.clear(); - render(); window.swap_buffers(); @@ -525,22 +518,6 @@ void Designer::render() root.render(); } -void Designer::object_added(Object &obj) -{ - if(Track *trk = dynamic_cast(&obj)) - new_tracks.push_back(trk); -} - -void Designer::object_removed(Object &obj) -{ - if(Track *trk = dynamic_cast(&obj)) - { - list::iterator i = find(new_tracks.begin(), new_tracks.end(), trk); - if(i!=new_tracks.end()) - new_tracks.erase(i); - } -} - Object *Designer::pick_object(const Vector &pointer) { View3D &view = *(mode==CATALOGUE ? cat_view : main_view); @@ -656,12 +633,9 @@ string Designer::tooltip(int x, int y) void Designer::clear_paths() { - const set <racks = layout->get_all(); - for(set::iterator i=ltracks.begin(); i!=ltracks.end(); ++i) - { - Track3D &t3d = layout_3d->get(**i); - t3d.get_path().set_mask(0); - } + for(list::iterator i=highlight_paths.begin(); i!=highlight_paths.end(); ++i) + delete *i; + highlight_paths.clear(); } void Designer::show_route(const Route &route) @@ -672,14 +646,10 @@ void Designer::show_route(const Route &route) for(set::iterator i=rtracks.begin(); i!=rtracks.end(); ++i) { Track3D &t3d = layout_3d->get(**i); - t3d.get_path().set_color(GL::Color(0.5, 0.8, 1.0)); - int path = -1; + Path3D *path = new Path3D(t3d); + path->set_color(GL::Color(0.5, 0.8, 1.0)); if(unsigned tid = (*i)->get_turnout_id()) - path = route.get_turnout(tid); - if(path>=0) - t3d.get_path().set_path(path); - else - t3d.get_path().set_mask((*i)->get_type().get_paths()); + path->set_path(route.get_turnout(tid)); } } @@ -691,7 +661,7 @@ void Designer::show_zone(const Zone &zone) for(Zone::TrackSet::const_iterator i=ztracks.begin(); i!=ztracks.end(); ++i) { Track3D &t3d = layout_3d->get(**i); - t3d.get_path().set_color(GL::Color(0.8, 1.0, 0.5)); - t3d.get_path().set_mask((*i)->get_type().get_paths()); + Path3D *path = new Path3D(t3d); + path->set_color(GL::Color(0.8, 1.0, 0.5)); } } diff --git a/source/designer/designer.h b/source/designer/designer.h index b78ad81..02649cb 100644 --- a/source/designer/designer.h +++ b/source/designer/designer.h @@ -63,7 +63,7 @@ private: Msp::GL::Object *base_object; R2C2::Route *cur_route; R2C2::Zone *cur_zone; - std::list new_tracks; + std::list highlight_paths; Mode mode; Selection selection; @@ -113,8 +113,6 @@ private: void axis_motion(unsigned, float, float); void apply_camera(); void render(); - void object_added(R2C2::Object &); - void object_removed(R2C2::Object &); R2C2::Object *pick_object(const R2C2::Vector &); void update_track_icon(R2C2::Track3D &); void selection_changed(); diff --git a/source/engineer/engineer.cpp b/source/engineer/engineer.cpp index 8c1738e..f0999d9 100644 --- a/source/engineer/engineer.cpp +++ b/source/engineer/engineer.cpp @@ -19,8 +19,10 @@ #include "libr2c2/driver.h" #include "libr2c2/trackcircuit.h" #include "libr2c2/tracktype.h" +#include "3d/allocation.h" #include "3d/path.h" #include "3d/track.h" +#include "3d/trackcircuit.h" #include "3d/vehicle.h" #include "engineer.h" #include "mainwindow.h" @@ -70,12 +72,16 @@ Engineer::Engineer(int argc, char **argv): DataFile::load(layout, options.layout_fn); layout.signal_train_added.connect(sigc::mem_fun(this, &Engineer::train_added)); - layout.signal_block_reserved.connect(sigc::hide<1>(sigc::mem_fun(this, &Engineer::reset_block_color))); layout.signal_emergency.connect(sigc::mem_fun(this, &Engineer::set_status)); const set &blocks = layout.get_all(); for(set::const_iterator i=blocks.begin(); i!=blocks.end(); ++i) - if(Sensor *sensor = (*i)->get_sensor()) - sensor->signal_state_changed.connect(sigc::hide(sigc::bind(sigc::mem_fun(this, &Engineer::reset_block_color), sigc::ref(**i)))); + if(TrackCircuit *tc = (*i)->get_sensor()) + new TrackCircuit3D(layout_3d, *tc); + + const set &tracks = layout.get_all(); + for(set::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) + if((*i)->get_type().is_turnout()) + new Path3D(layout_3d.get(**i)); if(FS::exists(options.state_fn)) DataFile::load(layout, options.state_fn); @@ -208,12 +214,8 @@ void Engineer::tick() delete picking_path; picking_path = new Path3D(layout_3d.get(*track)); - if(picking_entry>=0) - picking_path->set_mask(picking_track->get_type().get_endpoint(picking_entry).paths); - else - picking_path->set_mask(picking_track->get_type().get_paths()); picking_path->set_color(GL::Color(0)); - picking_path->set_layer(1); + picking_path->set_layer(2); } } } @@ -250,7 +252,6 @@ void Engineer::button_press(unsigned btn) else if(btn==3 && picking_entry>=0) { picking_entry = (picking_entry+1)%picking_track->get_type().get_endpoints().size(); - picking_path->set_mask(picking_track->get_type().get_endpoint(picking_entry).paths); } } else @@ -350,37 +351,6 @@ void Engineer::view_all() camera.set_depth_clip(pos.z*0.5, pos.z*1.5); } -void Engineer::set_block_color(const Block &block, const GL::Color &color) -{ - const set &tracks = block.get_tracks(); - for(set::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) - layout_3d.get(**i).get_path().set_color(color); -} - -void Engineer::reset_block_color(const Block &block) -{ - bool active = false; - if(Sensor *sensor = block.get_sensor()) - active = sensor->get_state()>Sensor::INACTIVE; - - if(block.get_train()) - { - GL::Color color; - map::iterator i = train_colors.find(block.get_train()); - if(i!=train_colors.end()) - color = i->second; - - if(active) - set_block_color(block, color*0.6); - else - set_block_color(block, color*0.5+0.5); - } - else if(active) - set_block_color(block, GL::Color(0.6)); - else - set_block_color(block, GL::Color(1)); -} - Object *Engineer::pick_object(const Vector &p) { const GL::Vector3 &start = camera.get_position(); @@ -430,6 +400,9 @@ void Engineer::train_added(Train &train) } } train_colors[&train] = best_color; + + Allocation3D *alloc = new Allocation3D(layout_3d, train); + alloc->set_color(best_color); } void Engineer::sighandler(int sig) diff --git a/source/engineer/engineer.h b/source/engineer/engineer.h index 7997242..d7fb2b8 100644 --- a/source/engineer/engineer.h +++ b/source/engineer/engineer.h @@ -80,8 +80,6 @@ private: void button_press(unsigned); void axis_motion(unsigned, float, float); void view_all(); - void set_block_color(const R2C2::Block &, const Msp::GL::Color &); - void reset_block_color(const R2C2::Block &); void sensor_event(unsigned, bool); void block_reserved(const R2C2::Block &, const R2C2::Train *); R2C2::Object *pick_object(const R2C2::Vector &); diff --git a/source/libr2c2/catalogue.cpp b/source/libr2c2/catalogue.cpp index ec3e95a..ab268cd 100644 --- a/source/libr2c2/catalogue.cpp +++ b/source/libr2c2/catalogue.cpp @@ -88,9 +88,6 @@ void Catalogue::Loader::ballast_profile() void Catalogue::Loader::gauge(float g) { obj.gauge = g/1000; - obj.path_profile = Profile(); - obj.path_profile.append_vertex(Vector(0.1*obj.gauge, 0, 0), false); - obj.path_profile.append_vertex(Vector(-0.1*obj.gauge, 0, 0), false); } void Catalogue::Loader::layout() diff --git a/source/libr2c2/catalogue.h b/source/libr2c2/catalogue.h index 12ee006..d13c982 100644 --- a/source/libr2c2/catalogue.h +++ b/source/libr2c2/catalogue.h @@ -44,7 +44,6 @@ private: float gauge; Profile rail_profile; Profile ballast_profile; - Profile path_profile; std::string track_technique; TrackMap tracks; VehicleMap vehicles; @@ -60,7 +59,6 @@ public: float get_rail_elevation() const; const Profile &get_rail_profile() const { return rail_profile; } const Profile &get_ballast_profile() const { return ballast_profile; } - const Profile &get_path_profile() const { return path_profile; } const std::string &get_track_technique() const { return track_technique; } void add_track(TrackType &); diff --git a/source/libr2c2/trackchain.cpp b/source/libr2c2/trackchain.cpp index 3d9d66a..bb4e77b 100644 --- a/source/libr2c2/trackchain.cpp +++ b/source/libr2c2/trackchain.cpp @@ -23,6 +23,7 @@ void TrackChain::add_track(Track &track) tracks.insert(&track); update_ends(track); on_track_added(track); + signal_track_added.emit(track); } void TrackChain::add_tracks(const TrackSet &trks) @@ -38,10 +39,12 @@ void TrackChain::add_tracks(const TrackSet &trks) for(TrackSet::iterator i=pending.begin(); i!=pending.end(); ++i) if((valid=check_validity(**i))==VALID) { - tracks.insert(*i); - update_ends(**i); - on_track_added(**i); + Track *t = *i; pending.erase(i); + tracks.insert(t); + update_ends(*t); + on_track_added(*t); + signal_track_added.emit(*t); break; } @@ -127,9 +130,12 @@ bool TrackChain::has_track(Track &t) const void TrackChain::object_removed(Object &obj) { if(Track *track = dynamic_cast(&obj)) + { tracks.erase(track); /* TODO If the track was in the middle of the chain, keep only the longest fragment */ + signal_track_removed.emit(*track); + } } } // namespace R2C2 diff --git a/source/libr2c2/trackchain.h b/source/libr2c2/trackchain.h index e73e23b..b4704f0 100644 --- a/source/libr2c2/trackchain.h +++ b/source/libr2c2/trackchain.h @@ -33,6 +33,10 @@ protected: INCOMPATIBLE }; +public: + sigc::signal signal_track_added; + sigc::signal signal_track_removed; + Layout &layout; TrackSet tracks; TrackIter ends[2];