]> git.tdb.fi Git - r2c2.git/commitdiff
Maintain a Block pointer in Track
authorMikko Rasa <tdb@tdb.fi>
Mon, 25 Oct 2010 11:40:33 +0000 (11:40 +0000)
committerMikko Rasa <tdb@tdb.fi>
Mon, 25 Oct 2010 11:40:33 +0000 (11:40 +0000)
Drop Layout::get_block_by_track

source/engineer/engineer.cpp
source/engineer/trainpanel.cpp
source/libmarklin/block.cpp
source/libmarklin/layout.cpp
source/libmarklin/layout.h
source/libmarklin/track.cpp
source/libmarklin/track.h

index 9db63fe0c70c22f81eb68074e88067fb6ade1fd6..32b77eda830989c4f1fc918afeec8bc2c4e49b59 100644 (file)
@@ -282,7 +282,7 @@ void Engineer::button_press(int x, int y, unsigned btn, unsigned)
                        Track &track = t3d->get_track();
                        if(track.get_turnout_id())
                        {
-                               Block &block = layout.get_block_by_track(track);
+                               Block &block = track.get_block();
                                if(block.get_train() && !block.get_train()->free_block(block))
                                        set_status("Turnout is busy");
                                else
index c1fc1d9cac6c74109b2a8393a85b6f82411adb5e..a0dbbeef3890e345b773344f78c4c8d87ce6d8bd 100644 (file)
@@ -262,7 +262,7 @@ void TrainPanel::place(Track *track, unsigned ep)
 {
        pick_conn.disconnect();
 
-       Block &block = engineer.get_layout().get_block_by_track(*track);
+       Block &block = track->get_block();
 
        while(1)
        {
index 780ee1bbd293e75a9e442f6a83a80c8a38a28f26..ec07947d7e1cbffa500f05b29661ba7178b99fa8 100644 (file)
@@ -24,6 +24,7 @@ Block::Block(Layout &l, Track &start):
        train(0)
 {
        tracks.insert(&start);
+       start.set_block(this);
 
        list<Track *> queue;
        queue.push_back(&start);
@@ -41,6 +42,7 @@ Block::Block(Layout &l, Track &start):
                                {
                                        queue.push_back(links[i]);
                                        tracks.insert(links[i]);
+                                       links[i]->set_block(this);
                                }
                                else
                                        endpoints.push_back(Endpoint(track, i));
@@ -62,6 +64,11 @@ Block::Block(Layout &l, Track &start):
 
 Block::~Block()
 {
+       set<Track *> trks = tracks;
+       tracks.clear();
+       for(set<Track *>::iterator i=trks.begin(); i!=trks.end(); ++i)
+               (*i)->set_block(0);
+
        for(vector<Endpoint>::iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
                if(Block *blk = i->link)
                {
index f8ad397f183992507ea2eb0140d1d2ae20bccf2c..f1bc3211bab00b5a8e6d4403f8d0ad3607694834 100644 (file)
@@ -95,15 +95,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)->has_track(t))
-                       return **i;
-
-       throw InvalidParameterValue("No block found for track");
-}
-
 void Layout::create_blocks()
 {
        set<Track *> used_tracks;
@@ -128,18 +119,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)->has_track(track);
-               for(vector<Track *>::const_iterator j=links.begin(); (!del && j!=links.end()); ++j)
-                       del = (*i)->has_track(**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();
 }
index 0f88fab5c36ca690c04b07ff91940877fea96756..e96bc951298c385d7906075238a092a738a5ff16 100644 (file)
@@ -81,7 +81,6 @@ public:
 
        void add_block(Block &);
        Block &get_block(unsigned) const;
-       Block &get_block_by_track(Track &) const;
        const std::set<Block *> &get_blocks() const { return blocks; }
        void create_blocks();
        void create_blocks(Track &);
index 6938820fafc26fe1b43c86405fc1703762f10364..5f1ca438644eea5d094a09dcf61e019fe954f5f2 100644 (file)
@@ -6,6 +6,7 @@ Distributed under the GPL
 */
 
 #include <cmath>
+#include "block.h"
 #include "driver.h"
 #include "layout.h"
 #include "track.h"
@@ -19,6 +20,7 @@ namespace Marklin {
 Track::Track(Layout &l, const TrackType &t):
        layout(l),
        type(t),
+       block(0),
        rot(0),
        slope(0),
        flex(false),
@@ -41,6 +43,24 @@ Track::~Track()
        layout.remove_track(*this);
 }
 
+void Track::set_block(Block *b)
+{
+       if(b && !b->has_track(*this))
+               throw InvalidParameterValue("Track is not in the Block");
+       if(!b && block && block->has_track(*this))
+               throw InvalidState("Track is still in a Block");
+
+       block = b;
+}
+
+Block &Track::get_block() const
+{
+       if(!block)
+               throw InvalidState("No Block");
+
+       return *block;
+}
+
 void Track::set_position(const Point &p)
 {
        pos = p;
index aff73966b36199b86751d75b972e0afce129aa1e..f3d89815b72cb2a0a9338d583f02c2f4806396cf 100644 (file)
@@ -16,6 +16,7 @@ Distributed under the GPL
 
 namespace Marklin {
 
+class Block;
 class Layout;
 class TrackType;
 
@@ -35,6 +36,7 @@ public:
 private:
        Layout &layout;
        const TrackType &type;
+       Block *block;
        Point pos;
        float rot;
        float slope;
@@ -53,6 +55,8 @@ public:
        Layout &get_layout() const { return layout; }
        const TrackType &get_type() const { return type; }
 
+       void set_block(Block *);
+       Block &get_block() const;
        void set_position(const Point &);
        void set_rotation(float);
        void set_slope(float);