]> git.tdb.fi Git - r2c2.git/commitdiff
Do not require unique names for routes
authorMikko Rasa <tdb@tdb.fi>
Fri, 15 Oct 2010 17:32:53 +0000 (17:32 +0000)
committerMikko Rasa <tdb@tdb.fi>
Fri, 15 Oct 2010 17:32:53 +0000 (17:32 +0000)
Support renaming routes
Add delete and rename buttons for routes in designer's toolbar

source/designer/designer.cpp
source/designer/designer.h
source/designer/toolbar.cpp
source/designer/toolbar.h
source/engineer/routeselect.cpp
source/libmarklin/layout.cpp
source/libmarklin/layout.h
source/libmarklin/route.cpp
source/libmarklin/route.h
source/network/server.cpp

index 396cb074c98b6cd83deae38f4b9df443d4473c7f..7fbab1fd4cdd705abfdfe877f6de8603ffcf544a 100644 (file)
@@ -86,6 +86,7 @@ Designer::Designer(int argc, char **argv):
        pipeline->add_renderable_for_pass(layout_3d->get_scene(), 0);
        if(base_object)
                pipeline->add_renderable_for_pass(*base_object, 0);
+       pipeline->add_renderable_for_pass(layout_3d->get_path_scene(), "unlit");
        pipeline->add_renderable_for_pass(layout_3d->get_endpoint_scene(), "unlit");
 
        light.set_position(0, -0.259, 0.966, 0);
@@ -129,6 +130,8 @@ Designer::Designer(int argc, char **argv):
        const list<Track3D *> &tracks = layout_3d->get_tracks();
        for(list<Track3D *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
                update_track_icon(**i);
+
+       edit_route(0);
 }
 
 Designer::~Designer()
@@ -202,12 +205,18 @@ void Designer::set_sensor_id()
        }
 }
 
-void Designer::edit_route(Route &r)
+void Designer::rename_route()
 {
        if(!cur_route)
-               pipeline->add_renderable_for_pass(layout_3d->get_path_scene(), "unlit");
+               return;
+
+       InputDialog *input = new InputDialog(*this, "Route name", cur_route->get_name());
+       input->signal_accept.connect(sigc::mem_fun(this, &Designer::route_name_accept));
+}
 
-       cur_route = &r;
+void Designer::edit_route(Route *r)
+{
+       cur_route = r;
        show_route(r);
 }
 
@@ -227,7 +236,7 @@ void Designer::add_selection_to_route()
                IO::print("%s\n", e.what());
        }
 
-       show_route(*cur_route);
+       show_route(cur_route);
 }
 
 Point Designer::map_pointer_coords(int x, int y)
@@ -545,6 +554,12 @@ void Designer::sensor_id_accept(const string &text)
        }
 }
 
+void Designer::route_name_accept(const string &text)
+{
+       if(cur_route)
+               cur_route->set_name(text);
+}
+
 void Designer::view_all()
 {
        Point minp;
@@ -590,20 +605,19 @@ string Designer::tooltip(int x, int y)
        return string();
 }
 
-void Designer::show_route(const Route &route)
+void Designer::show_route(const Route *route)
 {
        const set<Track *> &ltracks = layout->get_tracks();
-       const set<const Track *> &rtracks = route.get_tracks();
        for(set<Track *>::iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
        {
                Track3D &t3d = layout_3d->get_track(**i);
-               if(rtracks.count(*i))
+               if(route && route->get_tracks().count(*i))
                {
                        t3d.get_path().set_color(GL::Color(0.5, 0.8, 1.0));
                        if((*i)->get_type().is_turnout())
                        {
                                unsigned tid = (*i)->get_turnout_id();
-                               int path = (tid ? route.get_turnout(tid) : -1);
+                               int path = (tid ? route->get_turnout(tid) : -1);
                                if(path>=0)
                                        t3d.get_path().set_path(path);
                                else
index 5d22afb1c924c8b0a872d763820dc8567b8bff1f..5cb0c7849fe834186b2dad44aea14dcb66790711 100644 (file)
@@ -91,8 +91,9 @@ public:
        void new_track();
        void set_turnout_id();
        void set_sensor_id();
+       void rename_route();
 
-       void edit_route(Marklin::Route &);
+       void edit_route(Marklin::Route *);
        Marklin::Route *get_current_route() const { return cur_route; }
        void add_selection_to_route();
 
@@ -112,9 +113,10 @@ private:
        void measure_done();
        void turnout_id_accept(const std::string &);
        void sensor_id_accept(const std::string &);
+       void route_name_accept(const std::string &);
        void view_all();
        std::string tooltip(int, int);
-       void show_route(const Marklin::Route &);
+       void show_route(const Marklin::Route *);
 };
 
 #endif
index ee990ddb6d56bdd8569c2c2fcc9970fe1bd8baaa..ec18adb259980ef19ff17805ac2bcadbf75cacf3 100644 (file)
@@ -20,7 +20,7 @@ Toolbar::Toolbar(Designer &d):
        GLtk::Panel(d.get_ui_resources()),
        designer(d)
 {
-       set_size(410, 40);
+       set_size(640, 40);
 
        GLtk::Button *btn;
        GLtk::Label *lbl;
@@ -40,7 +40,7 @@ Toolbar::Toolbar(Designer &d):
        btn->set_tooltip("Exit Designer");
        btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::quit));
 
-       add(*(btn=new GLtk::Button(res, "NewT")));
+       add(*(btn=new GLtk::Button(res, "+Trk")));
        btn->set_geometry(GLtk::Geometry(135, 10, 40, 24));
        btn->set_tooltip("Add a track piece");
        btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::new_track));
@@ -59,18 +59,33 @@ Toolbar::Toolbar(Designer &d):
        lbl->set_geometry(GLtk::Geometry(265, 22, 40, 13));
 
        add(*(drp_routes=new GLtk::Dropdown(res)));
-       drp_routes->set_geometry(GLtk::Geometry(265, 5, 100, 17));
+       drp_routes->set_geometry(GLtk::Geometry(265, 5, 250, 17));
        drp_routes->set_tooltip("Select route to edit");
        drp_routes->append("(new route)");
        drp_routes->signal_item_selected.connect(sigc::mem_fun(this, &Toolbar::route_selected));
 
-       add(*(btn=new GLtk::Button(res, "AddT")));
-       btn->set_geometry(GLtk::Geometry(365, 10, 40, 24));
+       add(*(btn=new GLtk::Button(res, "Del")));
+       btn->set_geometry(GLtk::Geometry(515, 10, 40, 24));
+       btn->set_tooltip("Delete the current route");
+       btn->signal_clicked.connect(sigc::mem_fun(this, &Toolbar::delete_route_clicked));
+
+       add(*(btn=new GLtk::Button(res, "Name")));
+       btn->set_geometry(GLtk::Geometry(555, 10, 40, 24));
+       btn->set_tooltip("Rename the current route");
+       btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::rename_route));
+
+       add(*(btn=new GLtk::Button(res, "Add")));
+       btn->set_geometry(GLtk::Geometry(595, 10, 40, 24));
        btn->set_tooltip("Add selected tracks to current route");
        btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::add_selection_to_route));
 
-       designer.get_layout()->signal_route_added.connect(sigc::hide(sigc::mem_fun(this, &Toolbar::update_routes)));
+       designer.get_layout()->signal_route_added.connect(sigc::mem_fun(this, &Toolbar::route_added));
        designer.get_layout()->signal_route_removed.connect(sigc::hide(sigc::mem_fun(this, &Toolbar::update_routes)));
+
+       const set<Route *> &routes = designer.get_layout()->get_routes();
+       for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
+               (*i)->signal_name_changed.connect(sigc::hide(sigc::mem_fun(this, &Toolbar::update_routes)));
+
        update_routes();
 }
 
@@ -79,36 +94,50 @@ void Toolbar::route_selected(unsigned index, const string &)
        if(index==drp_routes->get_n_items()-1)
        {
                Layout &layout = *designer.get_layout();
-               Route *route = new Route(layout, format("Route %d", layout.get_routes().size()+1));
-               designer.edit_route(*route);
+               const set<Route *> &routes = designer.get_layout()->get_routes();
+               Route *route = new Route(layout);
+               route->set_name(format("Route %d", routes.size()));
+               designer.edit_route(route);
 
-               const map<string, Route *> &routes = designer.get_layout()->get_routes();
                int selected = -1;
                unsigned n = 0;
-               for(map<string, Route *>::const_iterator i=routes.begin(); (selected<0 && i!=routes.end()); ++i, ++n)
-                       if(i->second==route)
+               for(set<Route *>::const_iterator i=routes.begin(); (selected<0 && i!=routes.end()); ++i, ++n)
+                       if(*i==route)
                                selected = n;
                drp_routes->set_selected_index(selected);
        }
        else
        {
-               const map<string, Route *> &routes = designer.get_layout()->get_routes();
-               map<string, Route *>::const_iterator i = routes.begin();
+               const set<Route *> &routes = designer.get_layout()->get_routes();
+               set<Route *>::const_iterator i = routes.begin();
                advance(i, index);
-               designer.edit_route(*i->second);
+               designer.edit_route(*i);
        }
 }
 
+void Toolbar::delete_route_clicked()
+{
+       Route *route = designer.get_current_route();
+       designer.edit_route(0);
+       delete route;
+}
+
+void Toolbar::route_added(Route &r)
+{
+       r.signal_name_changed.connect(sigc::hide(sigc::mem_fun(this, &Toolbar::update_routes)));
+       update_routes();
+}
+
 void Toolbar::update_routes()
 {
        drp_routes->clear();
-       const map<string, Route *> &routes = designer.get_layout()->get_routes();
+       const set<Route *> &routes = designer.get_layout()->get_routes();
        int selected = -1;
        unsigned n = 0;
-       for(map<string, Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i, ++n)
+       for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i, ++n)
        {
-               drp_routes->append(i->second->get_name());
-               if(i->second==designer.get_current_route())
+               drp_routes->append((*i)->get_name());
+               if(*i==designer.get_current_route())
                        selected = n;
        }
        drp_routes->append("(new route)");
index a41f968682de7f7dae0b45ce7719536041b8ee6a..2a935d365fc686c7c7bbfc4d5bf88f95ffaf2e6f 100644 (file)
@@ -11,6 +11,7 @@ Distributed under the GPL
 #include <sigc++/trackable.h>
 #include <msp/gltk/dropdown.h>
 #include <msp/gltk/panel.h>
+#include "libmarklin/route.h"
 
 class Designer;
 
@@ -24,6 +25,8 @@ public:
        Toolbar(Designer &);
 private:
        void route_selected(unsigned, const std::string &);
+       void delete_route_clicked();
+       void route_added(Marklin::Route &);
        void update_routes();
 };
 
index c285f35f7031f7610551511d05bb12c4fb9432f8..6cda460c810652b42b5adb89641f6093ffe347fd 100644 (file)
@@ -30,13 +30,13 @@ RouteSelect::RouteSelect(Engineer &e, const GLtk::Resources &r, Train &t):
        drp_route->set_geometry(GLtk::Geometry(10, geom.h-50, geom.w-20, 20));
        drp_route->append("(none)");
        drp_route->set_selected_index(0);
-       const map<string, Route *> &routes = engineer.get_layout().get_routes();
+       const set<Route *> &routes = engineer.get_layout().get_routes();
        unsigned n = 1;
-       for(map<string, Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
-               if(!i->second->is_temporary())
+       for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
+               if(!(*i)->is_temporary())
                {
-                       drp_route->append(i->second->get_name());
-                       if(i->second==train.get_route())
+                       drp_route->append((*i)->get_name());
+                       if(*i==train.get_route())
                                drp_route->set_selected_index(n);
                        ++n;
                }
@@ -46,12 +46,12 @@ void RouteSelect::on_ok_clicked()
 {
        if(drp_route->get_selected_index()>0)
        {
-               const map<string, Route *> &routes = engineer.get_layout().get_routes();
-               map<string, Route *>::const_iterator i = routes.begin();
+               const set<Route *> &routes = engineer.get_layout().get_routes();
+               set<Route *>::const_iterator i = routes.begin();
                unsigned n = drp_route->get_selected_index()-1;
                while(i!=routes.end())
                {
-                       if(!i->second->is_temporary())
+                       if(!(*i)->is_temporary())
                        {
                                if(!n)
                                        break;
@@ -60,7 +60,7 @@ void RouteSelect::on_ok_clicked()
                        ++i;
                }
                
-               train.set_route(i->second);
+               train.set_route(*i);
        }
        else
                train.set_route(0);
index a495a21968b62ade01645c3e733939d101c1feea..d32781578243a1631634d23ecf78e7223387ec93 100644 (file)
@@ -41,7 +41,7 @@ Layout::~Layout()
        while(!trains.empty())
                delete trains.begin()->second;
        while(!routes.empty())
-               delete routes.begin()->second;
+               delete *routes.begin();
        while(!tracks.empty())
                delete *tracks.begin();
        while(!blocks.empty())
@@ -148,30 +148,27 @@ void Layout::remove_block(Block &b)
 
 void Layout::add_route(Route &r)
 {
-       if(routes.count(r.get_name()))
-               throw KeyError("Duplicate route name", r.get_name());
-
-       routes[r.get_name()] = &r;
-       signal_route_added.emit(r);
+       if(routes.insert(&r).second)
+               signal_route_added.emit(r);
 }
 
 Route &Layout::get_route(const string &name) const
 {
-       map<string, Route *>::const_iterator i = routes.find(name);
-       if(i==routes.end())
-               throw KeyError("Unknown route", name);
-       return *i->second;
+       for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
+               if((*i)->get_name()==name)
+                       return **i;
+       throw KeyError("Unknown route", name);
 }
 
 void Layout::update_routes()
 {
-       for(map<string, Route *>::iterator i=routes.begin(); i!=routes.end(); ++i)
-               i->second->update_turnouts();
+       for(set<Route *>::iterator i=routes.begin(); i!=routes.end(); ++i)
+               (*i)->update_turnouts();
 }
 
 void Layout::remove_route(Route &r)
 {
-       if(routes.erase(r.get_name()))
+       if(routes.erase(&r))
                signal_route_removed.emit(r);
 }
 
@@ -249,14 +246,13 @@ void Layout::save(const string &fn)
                writer.write(st);
        }
 
-       for(map<string, Route *>::iterator i=routes.begin(); i!=routes.end(); ++i)
+       for(set<Route *>::iterator i=routes.begin(); i!=routes.end(); ++i)
        {
-               if(i->second->is_temporary())
+               if((*i)->is_temporary())
                        continue;
 
                DataFile::Statement st("route");
-               st.append(i->first);
-               i->second->save(st.sub);
+               (*i)->save(st.sub);
                writer.write(st);
        }
 }
@@ -296,7 +292,8 @@ Layout::Loader::Loader(Layout &l):
        new_tracks(false)
 {
        add("base",  &Layout::base);
-       add("route", &Loader::route);
+       add("route", static_cast<void (Loader::*)()>(&Loader::route));
+       add("route", static_cast<void (Loader::*)(const string &)>(&Loader::route));
        add("track", &Loader::track);
        add("train", &Loader::train);
 }
@@ -307,9 +304,16 @@ void Layout::Loader::finish()
                (*i)->check_slope();
 }
 
+void Layout::Loader::route()
+{
+       Route *rte = new Route(obj);
+       load_sub(*rte);
+}
+
 void Layout::Loader::route(const string &n)
 {
-       Route *rte = new Route(obj, n);
+       Route *rte = new Route(obj);
+       rte->set_name(n);
        load_sub(*rte);
 }
 
index f820cb5dc73e6c6fc05166ab6816de11b7922c06..4e7bcd96ce83a8da61cd1396cfab41d90168cd3a 100644 (file)
@@ -35,6 +35,7 @@ public:
                Loader(Layout &);
        private:
                virtual void finish();
+               void route();
                void route(const std::string &);
                void track(unsigned);
                void train(unsigned, unsigned);
@@ -57,7 +58,7 @@ private:
        Driver *driver;
        std::string base;
        std::set<Track *> tracks;
-       std::map<std::string, Route *> routes;
+       std::set<Route *> routes;
        std::set<Block *> blocks;
        std::map<unsigned, Train *> trains;
        std::set<Vehicle *> vehicles;
@@ -87,7 +88,7 @@ public:
        void remove_block(Block &);
 
        void add_route(Route &);
-       const std::map<std::string, Route *> &get_routes() const { return routes; }
+       const std::set<Route *> &get_routes() const { return routes; }
        Route &get_route(const std::string &) const;
        void update_routes();
        void remove_route(Route &);
index cdbcf1dc4c8cc778f4183277dae9c6b65616f572..6cd58413d61ee562231b70e00c2ef44f3ec0e510 100644 (file)
@@ -119,17 +119,16 @@ list<const Track *> dijkstra(const Track &from, unsigned ep, const Pred &goal)
        return result;
 }
 
-unsigned count = 0;
-
 template<typename Pred>
 Route *create_route(const Track &from, unsigned ep, const Pred &goal)
 {
        list<const Track *> tracks = dijkstra(from, ep, goal);
 
-       Route *route = new Route(from.get_layout(), format("-%d-", ++count));
+       Route *route = new Route(from.get_layout());
        for(list<const Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                route->add_track(**i);
 
+       route->set_name("Pathfinder");
        route->set_temporary(true);
 
        return route;
@@ -140,9 +139,8 @@ Route *create_route(const Track &from, unsigned ep, const Pred &goal)
 
 namespace Marklin {
 
-Route::Route(Layout &l, const string &n):
+Route::Route(Layout &l):
        layout(l),
-       name(n),
        temporary(false)
 {
        layout.add_route(*this);
@@ -154,6 +152,12 @@ Route::~Route()
        layout.remove_route(*this);
 }
 
+void Route::set_name(const string &n)
+{
+       name = n;
+       signal_name_changed.emit(name);
+}
+
 void Route::set_temporary(bool t)
 {
        temporary = t;
@@ -302,6 +306,7 @@ void Route::update_turnouts()
 
 void Route::save(list<DataFile::Statement> &st) const
 {
+       st.push_back((DataFile::Statement("name"), name));
        for(map<unsigned, int>::const_iterator i=turnouts.begin(); i!=turnouts.end(); ++i)
                st.push_back((DataFile::Statement("turnout"), i->first, i->second));
 }
@@ -377,6 +382,7 @@ Route *Route::find(const Track &from, unsigned ep, const Route &to)
 Route::Loader::Loader(Route &r):
        DataFile::BasicLoader<Route>(r)
 {
+       add("name",    &Route::name);
        add("turnout", &Loader::turnout);
 }
 
index 6b36f46ec3ed5a68fbad407aef800f2d76f64eb1..7c188b00e702bf37bf7786ccbdbd0af010799b20 100644 (file)
@@ -36,6 +36,8 @@ public:
                void turnout(unsigned, unsigned);
        };
 
+       sigc::signal<void, const std::string &> signal_name_changed;
+
 private:
        Layout &layout;
        std::string name;
@@ -44,9 +46,10 @@ private:
        TurnoutMap turnouts;
 
 public:
-       Route(Layout &, const std::string &);
+       Route(Layout &);
        ~Route();
 
+       void set_name(const std::string &);
        const std::string &get_name() const { return name; }
        void set_temporary(bool);
        bool is_temporary() const { return temporary; }
index 8db68717ddf27743b903d85c94976df10a605f83..d27683965897161a1c50f26db4716070c53f5002 100644 (file)
@@ -119,11 +119,11 @@ Server::Connection::~Connection()
 
 void Server::Connection::handshake_done()
 {
-       const map<string, Route *> &routes = server.layout.get_routes();
-       for(map<string, Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
+       const set<Route *> &routes = server.layout.get_routes();
+       for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
        {
                RouteInfoPacket pkt;
-               pkt.name = i->first;
+               pkt.name = (*i)->get_name();
                comm.send(pkt);
        }