]> git.tdb.fi Git - r2c2.git/commitdiff
Reduce interface clutter in Layout by storing Objects in a uniform way
authorMikko Rasa <tdb@tdb.fi>
Wed, 5 Jun 2013 10:53:12 +0000 (13:53 +0300)
committerMikko Rasa <tdb@tdb.fi>
Wed, 5 Jun 2013 10:53:12 +0000 (13:53 +0300)
18 files changed:
source/3d/layout.cpp
source/3d/layout.h
source/3d/view.cpp
source/designer/designer.cpp
source/designer/designer.h
source/designer/manipulator.cpp
source/designer/measure.cpp
source/designer/svgexporter.cpp
source/engineer/engineer.cpp
source/libr2c2/blockallocator.cpp
source/libr2c2/layout.cpp
source/libr2c2/layout.h
source/libr2c2/route.cpp
source/libr2c2/route.h
source/libr2c2/signal.cpp
source/libr2c2/track.cpp
source/libr2c2/vehicle.cpp
source/libr2c2/vehicle.h

index d243374de5f7df4eed4a66931711b43dd201041c..2927e446741df4e1ad2ae194949831f449cc2afc 100644 (file)
@@ -16,19 +16,12 @@ Layout3D::Layout3D(Layout &l):
        sun.set_position(0, -0.259, 0.966, 0);
        lighting.attach(0, sun);
 
-       layout.signal_track_added.connect(sigc::mem_fun(this, &Layout3D::track_added));
-       layout.signal_track_removed.connect(sigc::mem_fun(this, &Layout3D::track_removed));
-       layout.signal_vehicle_added.connect(sigc::mem_fun(this, &Layout3D::vehicle_added));
-       layout.signal_vehicle_removed.connect(sigc::mem_fun(this, &Layout3D::vehicle_removed));
-       layout.signal_signal_added.connect(sigc::mem_fun(this, &Layout3D::signal_added));
-       layout.signal_signal_removed.connect(sigc::mem_fun(this, &Layout3D::signal_removed));
-
-       const set<Track *> &ltracks = layout.get_tracks();
-       for(set<Track *>::iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
-               track_added(**i);
-       const set<Signal *> &lsignals = layout.get_signals();
-       for(set<Signal *>::iterator i=lsignals.begin(); i!=lsignals.end(); ++i)
-               signal_added(**i);
+       layout.signal_object_added.connect(sigc::mem_fun(this, &Layout3D::object_added));
+       layout.signal_object_removed.connect(sigc::mem_fun(this, &Layout3D::object_removed));
+
+       const set<Object *> &lobjs = layout.get_all<Object>();
+       for(set<Object *>::iterator i=lobjs.begin(); i!=lobjs.end(); ++i)
+               object_added(**i);
 }
 
 Layout3D::~Layout3D()
@@ -97,40 +90,36 @@ Signal3D &Layout3D::get_signal(Signal &s) const
        return *get_item(signals, &s);
 }
 
-void Layout3D::track_added(Track &t)
-{
-       new Track3D(*this, t);
-}
-
-void Layout3D::track_removed(Track &t)
-{
-       TrackMap::iterator i = tracks.find(&t);
-       if(i!=tracks.end())
-               delete i->second;
-}
-
-void Layout3D::vehicle_added(Vehicle &v)
-{
-       new Vehicle3D(*this, v);
-}
-
-void Layout3D::vehicle_removed(Vehicle &v)
-{
-       VehicleMap::iterator i = vehicles.find(&v);
-       if(i!=vehicles.end())
-               delete i->second;
-}
-
-void Layout3D::signal_added(Signal &s)
-{
-       new Signal3D(*this, s);
-}
-
-void Layout3D::signal_removed(Signal &s)
-{
-       SignalMap::iterator i = signals.find(&s);
-       if(i!=signals.end())
-               delete i->second;
+void Layout3D::object_added(Object &o)
+{
+       if(Track *t = dynamic_cast<Track *>(&o))
+               new Track3D(*this, *t);
+       else if(Signal *s = dynamic_cast<Signal *>(&o))
+               new Signal3D(*this, *s);
+       else if(Vehicle *v = dynamic_cast<Vehicle *>(&o))
+               new Vehicle3D(*this, *v);
+}
+
+void Layout3D::object_removed(Object &o)
+{
+       if(Track *t = dynamic_cast<Track *>(&o))
+       {
+               TrackMap::iterator i = tracks.find(t);
+               if(i!=tracks.end())
+                       delete i->second;
+       }
+       else if(Signal *s = dynamic_cast<Signal *>(&o))
+       {
+               SignalMap::iterator i = signals.find(s);
+               if(i!=signals.end())
+                       delete i->second;
+       }
+       else if(Vehicle *v = dynamic_cast<Vehicle *>(&o))
+       {
+               VehicleMap::iterator i = vehicles.find(v);
+               if(i!=vehicles.end())
+                       delete i->second;
+       }
 }
 
 } // namespace R2C2
index 1e189bd1ce0eedd88a0541672e9d58f60e6f6efc..8456fa8e7404d62fbcec19a0792e3b35cc56e56a 100644 (file)
@@ -61,12 +61,8 @@ public:
        const Msp::GL::Lighting &get_lighting() const { return lighting; }
 
 private:
-       void track_added(Track &);
-       void track_removed(Track &);
-       void vehicle_added(Vehicle &);
-       void vehicle_removed(Vehicle &);
-       void signal_added(Signal &);
-       void signal_removed(Signal &);
+       void object_added(Object &);
+       void object_removed(Object &);
 };
 
 } // namespace R2C2
index 6b5115d1ed79a2fd143b40cce34ac3e3d8bfd39a..e058be7bf5661b9fe357fd74082b963097d31e0d 100644 (file)
@@ -28,7 +28,7 @@ View3D::View3D(Layout3D &l, unsigned w, unsigned h):
 
 void View3D::view_all(bool tight)
 {
-       const set<Track *> &tracks = layout.get_layout().get_tracks();
+       const set<Track *> &tracks = layout.get_layout().get_all<Track>();
        Geometry::BoundingBox<float, 3> bbox;
        for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
                bbox = bbox|(*i)->get_bounding_box();
index 6d4d49d10b1c349138f027988cc1fa0af302afcd..d640073427c5c936ce2ceb53ced27d9a0472775f 100644 (file)
@@ -68,8 +68,8 @@ Designer::Designer(int argc, char **argv):
        layout = new Layout(catalogue);
        layout_3d = new Layout3D(*layout);
 
-       layout->signal_track_added.connect(sigc::mem_fun(this, &Designer::track_added));
-       layout->signal_track_removed.connect(sigc::mem_fun(this, &Designer::track_removed));
+       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)
        {
@@ -412,7 +412,7 @@ void Designer::key_press(unsigned key)
        else if(key==Msp::Input::KEY_F && shift)
        {
                const set<Track *> &tracks = selection.get_objects<Track>();
-               const set<Track *> &ltracks = layout->get_tracks();
+               const set<Track *> &ltracks = layout->get_all<Track>();
                for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
                {
                        (*i)->set_flex(!(*i)->get_flex());
@@ -513,16 +513,20 @@ void Designer::render()
        glColor3f(1.0, 1.0, 1.0);
 }
 
-void Designer::track_added(Track &trk)
+void Designer::object_added(Object &obj)
 {
-       new_tracks.push_back(&trk);
+       if(Track *trk = dynamic_cast<Track *>(&obj))
+               new_tracks.push_back(trk);
 }
 
-void Designer::track_removed(Track &trk)
+void Designer::object_removed(Object &obj)
 {
-       list<Track *>::iterator i = find(new_tracks.begin(), new_tracks.end(), &trk);
-       if(i!=new_tracks.end())
-               new_tracks.erase(i);
+       if(Track *trk = dynamic_cast<Track *>(&obj))
+       {
+               list<Track *>::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)
@@ -531,7 +535,7 @@ Object *Designer::pick_object(const Vector &pointer)
        const GL::Vector3 &cpos = view.get_camera().get_position();
        GL::Vector4 cray = view.get_camera().unproject(GL::Vector4(pointer.x, pointer.y, 0, 0));
 
-       return view.get_layout().get_layout().pick_object(Ray(cpos, Vector(cray)));
+       return view.get_layout().get_layout().pick<Object>(Ray(cpos, Vector(cray)));
 }
 
 void Designer::update_track_icon(Track3D &track)
@@ -651,7 +655,7 @@ string Designer::tooltip(int x, int y)
 
 void Designer::clear_paths()
 {
-       const set<Track *> &ltracks = layout->get_tracks();
+       const set<Track *> &ltracks = layout->get_all<Track>();
        for(set<Track *>::iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
        {
                Track3D &t3d = layout_3d->get_track(**i);
index 8348f60d3920d6ac276be5102571a000817cda16..fd70358c56698b0ee923a478d1902becdce06e35 100644 (file)
@@ -113,8 +113,8 @@ private:
        void axis_motion(unsigned, float, float);
        void apply_camera();
        void render();
-       void track_added(R2C2::Track &);
-       void track_removed(R2C2::Track &);
+       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();
index 2ee967679428ebdf1595b74669128a194b31291a..ba27cae58fd88906cb3d620e75568b234ac799b7 100644 (file)
@@ -322,7 +322,7 @@ void Manipulator::button_press(unsigned btn)
                                        j->object->break_link(**i);
                }
 
-               const set<Track *> &ltracks = designer.get_layout().get_tracks();
+               const set<Track *> &ltracks = designer.get_layout().get_all<Track>();
                for(set<Track *>::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
                {
                        bool ok = true;
@@ -366,7 +366,7 @@ void Manipulator::axis_motion(unsigned axis, float value, float)
                        i->object->set_rotation(i->rot);
                }
 
-               const set<Track *> &ltracks = designer.get_layout().get_tracks();
+               const set<Track *> &ltracks = designer.get_layout().get_all<Track>();
                float limit = max(designer.get_layout().get_catalogue().get_gauge(),
                        designer.get_camera_controller().get_view_scale()/100.0f);
                MObject *snapped = 0;
index c7fead1af705a4c60a8230b5e04750d8fd21cd5c..f0d64e2f4d893b91da0a9bd7af60b65dc8e0ebdf 100644 (file)
@@ -120,7 +120,7 @@ void Measure::update_mesh()
 
 void Measure::snap_to_tracks(Snap &sn)
 {
-       const set<Track *> &ltracks = designer.get_layout().get_tracks();
+       const set<Track *> &ltracks = designer.get_layout().get_all<Track>();
        for(set<Track *>::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
                if((*i)->snap(sn, 0.01, SNAP_NODE))
                        return;
index ca95f90a012be3c9c2e203dd4bdbfbbecd39ce39..9f42ab4eacfe8c907b5218fa366982a1c56dfed8 100644 (file)
@@ -36,7 +36,7 @@ void SvgExporter::save(const string &fn)
 
        Vector minp;
        Vector maxp;
-       const set<Track *> &tracks = layout.get_tracks();
+       const set<Track *> &tracks = layout.get_all<Track>();
        for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
                xmlpp::Element *elem = root->add_child("g");
index b7b114baf6084e94e2efa802b095e48b4b209253..b3c1f5f69960d970b2533dad00adc41f2c10b6de 100644 (file)
@@ -388,7 +388,7 @@ Track *Engineer::pick_track(const Vector &p)
        const GL::Vector3 &start = camera.get_position();
        GL::Vector4 ray = camera.unproject(GL::Vector4(p.x, p.y, 0, 0));
 
-       return layout.pick_track(Ray(start, Vector(ray)));
+       return layout.pick<Track>(Ray(start, Vector(ray)));
 }
 
 void Engineer::process_new_train(Train &train)
index acb59aeae808beab4a212b245435bf7f9c181c93..f73697a5b45381f8173b045ce70de1ac0abfd590 100644 (file)
@@ -26,7 +26,7 @@ BlockAllocator::BlockAllocator(Train &t):
        layout.signal_block_reserved.connect(sigc::mem_fun(this, &BlockAllocator::block_reserved));
        layout.signal_sensor_state_changed.connect(sigc::mem_fun(this, &BlockAllocator::sensor_state_changed));
 
-       const set<Track *> &tracks = layout.get_tracks();
+       const set<Track *> &tracks = layout.get_all<Track>();
        for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
                if((*i)->get_turnout_id())
                        (*i)->signal_path_changed.connect(sigc::hide(sigc::bind(sigc::mem_fun(this, &BlockAllocator::turnout_path_changed), sigc::ref(**i))));
index 16542953a76320697ece0cb037767c70d9793ef3..6db66a62fc99644e2bedf7e85942b67d49e12b5b 100644 (file)
@@ -16,6 +16,7 @@
 #include "trackcircuit.h"
 #include "tracktype.h"
 #include "train.h"
+#include "vehicle.h"
 #include "vehicletype.h"
 #include "zone.h"
 
@@ -51,10 +52,8 @@ Layout::~Layout()
                delete *routes.begin();
        while(!zones.empty())
                delete *zones.begin();
-       while(!signals.empty())
-               delete *signals.begin();
-       while(!tracks.empty())
-               delete *tracks.begin();
+       objects.del<Signal>();
+       objects.del<Track>();
        while(!blocks.empty())
                delete *blocks.begin();
 }
@@ -66,78 +65,93 @@ Driver &Layout::get_driver() const
        return *driver;
 }
 
-void Layout::add_track(Track &t)
+void Layout::add(Object &o)
 {
-       if(tracks.insert(&t).second)
+       if(objects.insert(o))
+               signal_object_added.emit(o);
+}
+
+void Layout::add(Track &t)
+{
+       if(objects.insert(t))
        {
+               // Blocks must be recreated first
                create_blocks();
-               signal_track_added.emit(t);
+               signal_object_added.emit(t);
        }
 }
 
-Track *Layout::pick_track(const Ray &ray)
+template<>
+const set<Object *> &Layout::get_all<Object>() const
 {
-       return pick(tracks, ray);
+       return objects.get();
 }
 
-void Layout::remove_track(Track &t)
+template<>
+const set<Track *> &Layout::get_all<Track>() const
 {
-       if(tracks.erase(&t))
-       {
-               create_blocks(t);
-               signal_track_removed.emit(t);
-       }
+       return objects.get<Track>();
 }
 
-unsigned Layout::allocate_turnout_id()
+template<>
+const set<Signal *> &Layout::get_all<Signal>() const
 {
-       set<unsigned> used_ids;
-       for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
-               if((*i)->get_turnout_id())
-                       used_ids.insert((*i)->get_turnout_id());
-
-       unsigned result = next_turnout_id;
-       while(used_ids.count(result))
-               ++result;
-       next_turnout_id = result+1;
-
-       return result;
+       return objects.get<Signal>();
 }
 
-void Layout::add_signal(Signal &s)
+template<>
+const set<Vehicle *> &Layout::get_all<Vehicle>() const
 {
-       if(signals.insert(&s).second)
-               signal_signal_added.emit(s);
+       return objects.get<Vehicle>();
 }
 
-Signal *Layout::pick_signal(const Ray &ray)
+template<typename T>
+T *Layout::pick(const Ray &ray)
 {
-       return pick(signals, ray);
+       const set<Object *> &objs = objects.get();
+       for(set<Object *>::const_iterator i=objs.begin(); i!=objs.end(); ++i)
+               if(T *t = dynamic_cast<T *>(*i))
+                       if(t->collide_ray(ray))
+                               return t;
+
+       return 0;
 }
 
-void Layout::remove_signal(Signal &s)
+template Object *Layout::pick<Object>(const Ray &);
+template Track *Layout::pick<Track>(const Ray &);
+template Signal *Layout::pick<Signal>(const Ray &);
+template Vehicle *Layout::pick<Vehicle>(const Ray &);
+
+void Layout::remove(Object &o)
 {
-       if(signals.erase(&s))
-               signal_signal_removed.emit(s);
+       if(objects.erase(o))
+               signal_object_removed.emit(o);
 }
 
-Object *Layout::pick_object(const Ray &ray)
+void Layout::remove(Track &t)
 {
-       if(Object *obj = pick_track(ray))
-               return obj;
-       else if((obj = pick_signal(ray)))
-               return obj;
-       return 0;
+       if(objects.erase(t))
+       {
+               // Blocks must be recreated first
+               create_blocks(t);
+               signal_object_removed.emit(t);
+       }
 }
 
-template<typename T>
-T *Layout::pick(const set<T *> &objs, const Ray &ray)
+unsigned Layout::allocate_turnout_id()
 {
-       for(typename set<T *>::const_iterator i=objs.begin(); i!=objs.end(); ++i)
-               if((*i)->collide_ray(ray))
-                       return *i;
+       set<unsigned> used_ids;
+       const set<Track *> &tracks = objects.get<Track>();
+       for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
+               if((*i)->get_turnout_id())
+                       used_ids.insert((*i)->get_turnout_id());
 
-       return 0;
+       unsigned result = next_turnout_id;
+       while(used_ids.count(result))
+               ++result;
+       next_turnout_id = result+1;
+
+       return result;
 }
 
 void Layout::add_block(Block &b)
@@ -164,6 +178,7 @@ void Layout::create_blocks()
                used_tracks.insert(btracks.begin(), btracks.end());
        }
 
+       const set<Track *> &tracks = objects.get<Track>();
        for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
                if(used_tracks.count(*i)==0)
                {
@@ -277,18 +292,6 @@ void Layout::remove_train(Train &t)
                signal_train_removed.emit(t);
 }
 
-void Layout::add_vehicle(Vehicle &v)
-{
-       if(vehicles.insert(&v).second)
-               signal_vehicle_added.emit(v);
-}
-
-void Layout::remove_vehicle(Vehicle &v)
-{
-       if(vehicles.erase(&v))
-               signal_vehicle_removed.emit(v);
-}
-
 void Layout::add_sensor(Sensor &s)
 {
        if(sensors.insert(&s).second)
@@ -316,6 +319,7 @@ void Layout::tick()
 
        for(set<Sensor *>::iterator i=sensors.begin(); i!=sensors.end(); ++i)
                (*i)->tick(dt);
+       const set<Signal *> &signals = objects.get<Signal>();
        for(set<Signal *>::iterator i=signals.begin(); i!=signals.end(); ++i)
                (*i)->tick(dt);
        for(map<unsigned, Train *>::iterator i=trains.begin(); i!=trains.end(); ++i)
@@ -338,6 +342,7 @@ void Layout::save(const string &fn) const
        if(!base.empty())
                writer.write((DataFile::Statement("base"), base));
 
+       const set<Track *> &tracks = objects.get<Track>();
        for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
                DataFile::Statement st("track");
@@ -346,6 +351,7 @@ void Layout::save(const string &fn) const
                writer.write(st);
        }
 
+       const set<Signal *> &signals = objects.get<Signal>();
        for(set<Signal *>::const_iterator i=signals.begin(); i!=signals.end(); ++i)
        {
                DataFile::Statement st("signal");
@@ -377,6 +383,7 @@ void Layout::save_dynamic(const string &fn) const
        IO::BufferedFile out(fn, IO::M_WRITE);
        DataFile::Writer writer(out);
 
+       const set<Track *> &tracks = objects.get<Track>();
        for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
                if(unsigned tid = (*i)->get_turnout_id())
                        writer.write((DataFile::Statement("turnout"), tid, (*i)->get_active_path()));
@@ -406,6 +413,59 @@ void Layout::sensor_state_changed(Sensor &sensor, Sensor::State state)
 }
 
 
+template<typename B>
+Layout::Storage<B>::~Storage()
+{
+       while(!base.empty())
+               delete *base.begin();
+}
+
+template<typename B>
+bool Layout::Storage<B>::insert(B &b)
+{
+       bool result = base.insert(&b).second;
+       if(result)
+               caches.clear();
+       return result;
+}
+
+template<typename B>
+bool Layout::Storage<B>::erase(B &b)
+{
+       bool result = base.erase(&b);
+       if(result)
+               caches.clear();
+       return result;
+}
+
+template<typename B>
+template<typename T>
+const set<T *> &Layout::Storage<B>::get() const
+{
+       for(list<Variant>::const_iterator i=caches.begin(); i!=caches.end(); ++i)
+               if(i->check_type<set<T *> >())
+                       return i->value<set<T *> >();
+
+       caches.push_back(set<T *>());
+       set<T *> &result = caches.back().value<set<T *> >();
+       for(typename set<B *>::const_iterator i=base.begin(); i!=base.end(); ++i)
+               if(T *t = dynamic_cast<T *>(*i))
+                       result.insert(t);
+
+       return result;
+}
+
+template<typename B>
+template<typename T>
+void Layout::Storage<B>::del()
+{
+       set<T *> ts = get<T>();
+       for(typename set<T *>::iterator i=ts.begin(); i!=ts.end(); ++i)
+               if(base.count(*i))
+                       delete *i;
+}
+
+
 Layout::Loader::Loader(Layout &l):
        DataFile::ObjectLoader<Layout>(l),
        new_tracks(false)
@@ -453,7 +513,8 @@ void Layout::Loader::track(ArticleNumber art_nr)
        Track *trk = new Track(obj, obj.catalogue.get_track(art_nr));
        load_sub(*trk);
        new_tracks = true;
-       for(set<Track *>::iterator i=obj.tracks.begin(); i!=obj.tracks.end(); ++i)
+       const set<Track *> &tracks = obj.objects.get<Track>();
+       for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
                if(*i!=trk)
                        trk->link_to(**i);
 }
index de5588cefb98449790a8f4ca3923c868399acbaf..f9a2ba1bd5f7cf73f06dbd39956c0afa4166cffb 100644 (file)
@@ -44,21 +44,41 @@ public:
                void zone();
        };
 
+private:
+       template<typename B>
+       class Storage
+       {
+       private:
+               std::set<B *> base;
+               mutable std::list<Msp::Variant> caches;
+
+       public:
+               ~Storage();
+
+               bool insert(B &);
+               bool erase(B &);
+
+               const std::set<B *> &get() const { return base; }
+
+               template<typename T>
+               const std::set<T *> &get() const;
+
+               template<typename T>
+               void del();
+       };
+
+public:
        typedef std::set<Zone *> ZoneSet;
        typedef std::vector<Zone *> ZoneArray;
 
-       sigc::signal<void, Track &> signal_track_added;
-       sigc::signal<void, Track &> signal_track_removed;
-       sigc::signal<void, Signal &> signal_signal_added;
-       sigc::signal<void, Signal &> signal_signal_removed;
+       sigc::signal<void, Object &> signal_object_added;
+       sigc::signal<void, Object &> signal_object_removed;
        sigc::signal<void, Route &> signal_route_added;
        sigc::signal<void, Route &> signal_route_removed;
        sigc::signal<void, Zone &> signal_zone_added;
        sigc::signal<void, Zone &> signal_zone_removed;
        sigc::signal<void, Train &> signal_train_added;
        sigc::signal<void, Train &> signal_train_removed;
-       sigc::signal<void, Vehicle &> signal_vehicle_added;
-       sigc::signal<void, Vehicle &> signal_vehicle_removed;
        sigc::signal<void, Block &, Train *> signal_block_reserved;
        sigc::signal<void, Sensor &, Sensor::State> signal_sensor_state_changed;
        sigc::signal<void, const std::string &> signal_emergency;
@@ -67,14 +87,12 @@ private:
        Catalogue &catalogue;
        Driver *driver;
        std::string base;
-       std::set<Track *> tracks;
-       std::set<Signal *> signals;
+       Storage<Object> objects;
        std::set<Route *> routes;
        ZoneSet zones;
        std::set<Block *> blocks;
        std::set<Sensor *> sensors;
        std::map<unsigned, Train *> trains;
-       std::set<Vehicle *> vehicles;
        Msp::Time::TimeStamp last_tick;
        unsigned next_turnout_id;
 
@@ -87,24 +105,20 @@ public:
        Driver &get_driver() const;
        const std::string &get_base() const { return base; }
 
-       void add_track(Track &);
-       const std::set<Track *> &get_tracks() const { return tracks; }
-       Track *pick_track(const Ray &);
-       void remove_track(Track &);
-       unsigned allocate_turnout_id();
-
-       void add_signal(Signal &);
-       const std::set<Signal *> &get_signals() const { return signals; }
-       Signal *pick_signal(const Ray &);
-       void remove_signal(Signal &);
+       void add(Object &);
+       void add(Track &);
 
-       Object *pick_object(const Ray &);
+       template<typename T>
+       const std::set<T *> &get_all() const;
 
-private:
        template<typename T>
-       static T *pick(const std::set<T *> &, const Ray &);
+       T *pick(const Ray &);
+
+       void remove(Object &);
+       void remove(Track &);
+
+       unsigned allocate_turnout_id();
 
-public:
        void add_block(Block &);
        Block &get_block(unsigned) const;
        const std::set<Block *> &get_blocks() const { return blocks; }
@@ -129,9 +143,6 @@ public:
        const std::map<unsigned, Train *> &get_trains() const { return trains; }
        void remove_train(Train &);
 
-       void add_vehicle(Vehicle &);
-       void remove_vehicle(Vehicle &);
-
        void add_sensor(Sensor &);
        void remove_sensor(Sensor &);
 
index 80c61088eda68223be46299bac6621b289291d35..685ad666404688275cfa87eda6f7a48a0e60c9b4 100644 (file)
@@ -147,7 +147,7 @@ Route::Route(Layout &l):
        temporary(false)
 {
        layout.add_route(*this);
-       layout.signal_track_removed.connect(sigc::mem_fun(this, &Route::track_removed));
+       layout.signal_object_removed.connect(sigc::mem_fun(this, &Route::object_removed));
 }
 
 Route::~Route()
@@ -402,9 +402,10 @@ RouteValidityMask Route::check_validity(Track &trk) const
        return static_cast<RouteValidityMask>(result);
 }
 
-void Route::track_removed(Track &t)
+void Route::object_removed(Object &o)
 {
-       tracks.erase(&t);
+       if(Track *t = dynamic_cast<Track *>(&o))
+               tracks.erase(t);
 }
 
 Route *Route::find(const TrackIter &from, Track &to)
@@ -437,7 +438,7 @@ Route::Loader::Loader(Route &r):
 
 void Route::Loader::finish()
 {
-       const set<Track *> &ltracks = obj.layout.get_tracks();
+       const set<Track *> &ltracks = obj.layout.get_all<Track>();
        for(set<Track *>::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
        {
                unsigned tid = (*i)->get_turnout_id();
index e5164ce06a283f854d5ce2f7e1881bbac159610f..0dd16f44342c89b84650dcbc5de6865c0a9c2f04 100644 (file)
@@ -10,6 +10,7 @@
 namespace R2C2 {
 
 class Layout;
+class Object;
 class Track;
 class TrackIter;
 class Zone;
@@ -81,7 +82,7 @@ public:
        void save(std::list<Msp::DataFile::Statement> &) const;
 private:
        RouteValidityMask check_validity(Track &) const;
-       void track_removed(Track &);
+       void object_removed(Object &);
 
 public:
        static Route *find(const TrackIter &, Track &);
index a858e0dc92b99293eb142f8172f7902d563acb22..38e11248793258641a6ef3557c247bb8406f3b09 100644 (file)
@@ -24,14 +24,14 @@ Signal::Signal(Layout &l, const SignalType &t):
        check_allocated_blocks(false),
        passing(false)
 {
-       layout.add_signal(*this);
+       layout.add(*this);
 
        layout.signal_block_reserved.connect(sigc::mem_fun(this, &Signal::block_reserved));
 }
 
 Signal::~Signal()
 {
-       layout.remove_signal(*this);
+       layout.remove(*this);
 }
 
 Signal *Signal::clone(Layout *to_layout) const
@@ -59,7 +59,7 @@ void Signal::set_position(const Vector &p)
 
 void Signal::update_location()
 {
-       const set<Track *> &tracks = layout.get_tracks();
+       const set<Track *> &tracks = layout.get_all<Track>();
        float limit = layout.get_catalogue().get_gauge()*2;
        float dist = -1;
        for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
index c2b190f0551410b149a408e450ee16041151295c..51c73c237ccd27a8873ae26effc0a632434dc2c5 100644 (file)
@@ -26,7 +26,7 @@ Track::Track(Layout &l, const TrackType &t):
        if(type.is_turnout())
                turnout_id = layout.allocate_turnout_id();
 
-       layout.add_track(*this);
+       layout.add(*this);
 
        if(layout.has_driver())
                layout.get_driver().signal_turnout.connect(sigc::mem_fun(this, &Track::turnout_event));
@@ -37,7 +37,7 @@ Track::Track(Layout &l, const TrackType &t):
 Track::~Track()
 {
        break_links();
-       layout.remove_track(*this);
+       layout.remove(*this);
 }
 
 Track *Track::clone(Layout *to_layout) const
index 1c4a5b0f441ec9d5e6b40f711cc54afd176cbf08..457cb332dc2f5148327988ad797184205fee632a 100644 (file)
@@ -25,7 +25,7 @@ Vehicle::Vehicle(Layout &l, const VehicleType &t):
        bogies.assign(type.get_bogies().begin(), type.get_bogies().end());
        rods.assign(type.get_rods().begin(), type.get_rods().end());
 
-       layout.add_vehicle(*this);
+       layout.add(*this);
 }
 
 Vehicle::~Vehicle()
@@ -34,7 +34,7 @@ Vehicle::~Vehicle()
                detach_back();
        if(prev)
                detach_front();
-       layout.remove_vehicle(*this);
+       layout.remove(*this);
 }
 
 Vehicle *Vehicle::clone(Layout *to_layout) const
index d259201f0ec4df982fc353e005c1730f80d29e72..e7427b1e92ef6bb61b95ae48b9241664997b7413 100644 (file)
@@ -124,8 +124,6 @@ public:
        virtual unsigned get_n_link_slots() const;
        virtual Vehicle *get_link(unsigned) const;
        virtual int get_link_slot(const Object &) const;
-
-       virtual bool collide_ray(const Vector &, const Vector &) const { return false; }
 };
 
 } // namespace R2C2