]> git.tdb.fi Git - r2c2.git/blobdiff - source/libmarklin/layout.cpp
Make LCD output selectable at runtime through an extra I/O pin
[r2c2.git] / source / libmarklin / layout.cpp
index f89b78335d30f0f720778ccbcd4b3822fc8defb8..5f590dbb9a762473c9daa279356ddafe49061ffe 100644 (file)
@@ -75,9 +75,16 @@ void Layout::remove_track(Track &t)
 
 unsigned Layout::allocate_turnout_id(bool dbl)
 {
-       unsigned result = next_turnout_id++;
-       if(dbl)
-               ++next_turnout_id;
+       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) || (dbl && used_ids.count(result+1)))
+               ++result;
+       next_turnout_id = result+1+dbl;
+
        return result;
 }
 
@@ -95,15 +102,6 @@ Block &Layout::get_block(unsigned id) const
        throw KeyError("Unknown block", lexical_cast(id));
 }
 
-Block &Layout::get_block_by_track(Track &t) const
-{
-       for(set<Block *>::const_iterator i=blocks.begin(); i!=blocks.end(); ++i)
-               if((*i)->get_tracks().count(&t))
-                       return **i;
-
-       throw InvalidParameterValue("No block found for track");
-}
-
 void Layout::create_blocks()
 {
        set<Track *> used_tracks;
@@ -128,18 +126,19 @@ void Layout::create_blocks()
 
 void Layout::create_blocks(Track &track)
 {
+       /* Must collect the blocks in a set first while all tracks are still
+       guaranteed to have blocks and to avoid duplicate deletes */
+       set<Block *> del_blocks;
+
+       del_blocks.insert(&track.get_block());
+
        const vector<Track *> &links = track.get_links();
-       for(set<Block *>::iterator i=blocks.begin(); i!=blocks.end();)
-       {
-               bool del = (*i)->get_tracks().count(&track);
-               for(vector<Track *>::const_iterator j=links.begin(); (!del && j!=links.end()); ++j)
-                       del = (*i)->get_tracks().count(*j);
-
-               if(del)
-                       delete *i++;
-               else
-                       ++i;
-       }
+       for(vector<Track *>::const_iterator i=links.begin(); i!=links.end(); ++i)
+               if(*i)
+                       del_blocks.insert(&(*i)->get_block());
+
+       for(set<Block *>::iterator i=del_blocks.begin(); i!=del_blocks.end(); ++i)
+               delete *i;
 
        create_blocks();
 }
@@ -270,6 +269,7 @@ void Layout::save_trains(const string &fn)
                DataFile::Statement st("train");
                st.append(i->second->get_locomotive_type().get_article_number());
                st.append(i->second->get_address());
+               st.append(i->second->get_protocol());
                i->second->save(st.sub);
                writer.write(st);
        }
@@ -297,8 +297,10 @@ Layout::Loader::Loader(Layout &l):
        add("base",  &Layout::base);
        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);
+       add("track", static_cast<void (Loader::*)(unsigned)>(&Loader::track));
+       add("track", static_cast<void (Loader::*)(ArticleNumber)>(&Loader::track));
+       add("train", static_cast<void (Loader::*)(unsigned, unsigned, const std::string &)>(&Loader::train));
+       add("train", static_cast<void (Loader::*)(ArticleNumber, unsigned, const std::string &)>(&Loader::train));
 }
 
 void Layout::Loader::finish()
@@ -321,6 +323,11 @@ void Layout::Loader::route(const string &n)
 }
 
 void Layout::Loader::track(unsigned art_nr)
+{
+       track(ArticleNumber(art_nr));
+}
+
+void Layout::Loader::track(ArticleNumber art_nr)
 {
        Track *trk = new Track(obj, obj.catalogue.get_track(art_nr));
        load_sub(*trk);
@@ -330,9 +337,14 @@ void Layout::Loader::track(unsigned art_nr)
                        trk->snap_to(**i, true);
 }
 
-void Layout::Loader::train(unsigned art_nr, unsigned addr)
+void Layout::Loader::train(unsigned art_nr, unsigned addr, const std::string &proto)
+{
+       train(ArticleNumber(art_nr), addr, proto);
+}
+
+void Layout::Loader::train(ArticleNumber art_nr, unsigned addr, const std::string &proto)
 {
-       Train *trn = new Train(obj, obj.catalogue.get_vehicle(art_nr), addr);
+       Train *trn = new Train(obj, obj.catalogue.get_vehicle(art_nr), addr, proto);
        load_sub(*trn);
 }