From f74ce147edde73319e55475433adb8e1d87b7201 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 25 Oct 2010 11:40:33 +0000 Subject: [PATCH] Maintain a Block pointer in Track Drop Layout::get_block_by_track --- source/engineer/engineer.cpp | 2 +- source/engineer/trainpanel.cpp | 2 +- source/libmarklin/block.cpp | 7 +++++++ source/libmarklin/layout.cpp | 32 ++++++++++++-------------------- source/libmarklin/layout.h | 1 - source/libmarklin/track.cpp | 20 ++++++++++++++++++++ source/libmarklin/track.h | 4 ++++ 7 files changed, 45 insertions(+), 23 deletions(-) diff --git a/source/engineer/engineer.cpp b/source/engineer/engineer.cpp index 9db63fe..32b77ed 100644 --- a/source/engineer/engineer.cpp +++ b/source/engineer/engineer.cpp @@ -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 diff --git a/source/engineer/trainpanel.cpp b/source/engineer/trainpanel.cpp index c1fc1d9..a0dbbee 100644 --- a/source/engineer/trainpanel.cpp +++ b/source/engineer/trainpanel.cpp @@ -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) { diff --git a/source/libmarklin/block.cpp b/source/libmarklin/block.cpp index 780ee1b..ec07947 100644 --- a/source/libmarklin/block.cpp +++ b/source/libmarklin/block.cpp @@ -24,6 +24,7 @@ Block::Block(Layout &l, Track &start): train(0) { tracks.insert(&start); + start.set_block(this); list 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 trks = tracks; + tracks.clear(); + for(set::iterator i=trks.begin(); i!=trks.end(); ++i) + (*i)->set_block(0); + for(vector::iterator i=endpoints.begin(); i!=endpoints.end(); ++i) if(Block *blk = i->link) { diff --git a/source/libmarklin/layout.cpp b/source/libmarklin/layout.cpp index f8ad397..f1bc321 100644 --- a/source/libmarklin/layout.cpp +++ b/source/libmarklin/layout.cpp @@ -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::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 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 del_blocks; + + del_blocks.insert(&track.get_block()); + const vector &links = track.get_links(); - for(set::iterator i=blocks.begin(); i!=blocks.end();) - { - bool del = (*i)->has_track(track); - for(vector::const_iterator j=links.begin(); (!del && j!=links.end()); ++j) - del = (*i)->has_track(**j); - - if(del) - delete *i++; - else - ++i; - } + for(vector::const_iterator i=links.begin(); i!=links.end(); ++i) + if(*i) + del_blocks.insert(&(*i)->get_block()); + + for(set::iterator i=del_blocks.begin(); i!=del_blocks.end(); ++i) + delete *i; create_blocks(); } diff --git a/source/libmarklin/layout.h b/source/libmarklin/layout.h index 0f88fab..e96bc95 100644 --- a/source/libmarklin/layout.h +++ b/source/libmarklin/layout.h @@ -81,7 +81,6 @@ public: void add_block(Block &); Block &get_block(unsigned) const; - Block &get_block_by_track(Track &) const; const std::set &get_blocks() const { return blocks; } void create_blocks(); void create_blocks(Track &); diff --git a/source/libmarklin/track.cpp b/source/libmarklin/track.cpp index 6938820..5f1ca43 100644 --- a/source/libmarklin/track.cpp +++ b/source/libmarklin/track.cpp @@ -6,6 +6,7 @@ Distributed under the GPL */ #include +#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; diff --git a/source/libmarklin/track.h b/source/libmarklin/track.h index aff7396..f3d8981 100644 --- a/source/libmarklin/track.h +++ b/source/libmarklin/track.h @@ -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); -- 2.45.2