]> git.tdb.fi Git - r2c2.git/commitdiff
Streamline various block-related algorithms
authorMikko Rasa <tdb@tdb.fi>
Fri, 7 Jun 2013 16:18:04 +0000 (19:18 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 7 Jun 2013 16:18:04 +0000 (19:18 +0300)
source/libr2c2/block.cpp
source/libr2c2/block.h
source/libr2c2/blockiter.cpp
source/libr2c2/trackiter.cpp

index bf77433491df7b210631dd886c0d7435ced23e93..f6818166d22c8996c58199abb45e464c2b54fcbc 100644 (file)
@@ -20,41 +20,29 @@ Block::Block(Layout &l, Track &start):
        turnout_id(start.get_turnout_id()),
        train(0)
 {
-       tracks.insert(&start);
-       start.set_block(this);
+       add_track(start);
 
-       list<Track *> queue;
-       queue.push_back(&start);
-
-       while(!queue.empty())
+       if(start.get_type().is_turnout())
        {
-               Track *track = queue.front();
-               queue.erase(queue.begin());
-
-               const vector<Track *> &links = track->get_links();
-               for(unsigned i=0; i<links.size(); ++i)
-                       if(links[i] && !tracks.count(links[i]))
-                       {
-                               if(links[i]->get_sensor_id()==sensor_id && links[i]->get_turnout_id()==turnout_id)
-                               {
-                                       queue.push_back(links[i]);
-                                       add_track(*links[i]);
-                                       links[i]->set_block(this);
-                               }
-                               else
-                                       endpoints.push_back(Endpoint(track, i));
-                       }
+               unsigned nls = start.get_n_link_slots();
+               for(unsigned i=0; i<nls; ++i)
+                       endpoints.push_back(Endpoint(&start, i));
        }
-
-       determine_id();
-
-       for(unsigned i=0; i<endpoints.size(); ++i)
+       else
        {
-               unsigned path = 1<<i;
-               endpoints[i].paths |= path;
-               find_paths(endpoints[i].track_iter(), path);
+               unsigned nls = start.get_n_link_slots();
+               for(unsigned i=0; i<nls; ++i)
+               {
+                       TrackIter iter = TrackIter(&start, i).flip();
+                       for(; (iter && check_validity(*iter)==VALID); iter=iter.next())
+                               add_track(*iter);
+                       if((iter = iter.flip()))
+                               endpoints.push_back(Endpoint(iter.track(), iter.entry()));
+               }
        }
 
+       determine_id();
+
        sensor = new TrackCircuit(layout, *this);
 
        layout.add_block(*this);
@@ -79,6 +67,11 @@ Block::~Block()
        delete sensor;
 }
 
+void Block::on_track_added(Track &track)
+{
+       track.set_block(this);
+}
+
 TrackChain::Validity Block::check_validity(Track &track) const
 {
        if(track.get_sensor_id()!=sensor_id || track.get_turnout_id()!=turnout_id)
@@ -172,27 +165,6 @@ bool Block::reserve(Train *t)
                return false;
 }
 
-void Block::find_paths(const TrackIter &track, unsigned path)
-{
-       unsigned mask = track.endpoint().paths;
-       for(unsigned i=0; mask>>i; ++i)
-               if(mask&(1<<i))
-               {
-                       TrackIter next = track.next(i);
-                       if(!next)
-                               continue;
-                       else if(has_track(*next))
-                               find_paths(track.next(i), path);
-                       else
-                       {
-                               next = next.flip();
-                               for(vector<Endpoint>::iterator j=endpoints.begin(); j!=endpoints.end(); ++j)
-                                       if(j->track==next.track() && j->track_ep==next.entry())
-                                               j->paths |= path;
-                       }
-               }
-}
-
 void Block::determine_id()
 {
        if(sensor_id)
@@ -218,8 +190,7 @@ void Block::determine_id()
 Block::Endpoint::Endpoint(Track *t, unsigned e):
        track(t),
        track_ep(e),
-       link(0),
-       paths(0)
+       link(0)
 { }
 
 TrackIter Block::Endpoint::track_iter() const
index 7d6211b0a5b303b9e85669fb96d72882606c838d..4309290da3f3145a553a405009dc35a4c60b8ad9 100644 (file)
@@ -22,7 +22,6 @@ public:
                Track *track;
                unsigned track_ep;
                Block *link;
-               unsigned paths;
 
                Endpoint(Track *, unsigned);
 
@@ -44,6 +43,7 @@ public:
        ~Block();
 
 private:
+       virtual void on_track_added(Track &);
        virtual Validity check_validity(Track &) const;
 
 public:
@@ -61,7 +61,6 @@ public:
        bool reserve(Train *);
        Train *get_train() const { return train; }
 private:
-       void find_paths(const TrackIter &, unsigned);
        void determine_id();
 };
 
index 038600bbffa933a25c6e5022790b04437b4000dc..a3f6d876a8b40000472283ca276c586bcfc1c482 100644 (file)
@@ -40,24 +40,18 @@ const Block::Endpoint &BlockIter::endpoint() const
 int BlockIter::get_exit(const Route *route) const
 {
        const vector<Block::Endpoint> &eps = _block->get_endpoints();
-       TrackIter t_iter = track_iter();
-
-       while(t_iter)
+       if(_block->get_turnout_id())
        {
-               if(!_block->has_track(*t_iter))
-                       throw logic_error("internal error (block traversal escaped the block)");
-
+               /* The endpoints of a turnout block exactly correspond to the endpoints
+               of the track. */
+               TrackIter t_iter = track_iter();
                unsigned path = (route ? route->get_path(*t_iter) : t_iter->get_active_path());
-               TrackIter t_exit = t_iter.reverse(path);
-
-               for(unsigned i=0; i<eps.size(); ++i)
-                       if(eps[i].track==t_exit.track() && eps[i].track_ep==t_exit.entry())
-                               return i;
-
-               t_iter = t_exit.flip();
+               return t_iter.reverse(path).entry();
        }
-
-       return -1;
+       else if(eps.size()==2)
+               return 1-_entry;
+       else
+               return -1;
 }
 
 BlockIter BlockIter::next(const Route *route) const
index e07c71c02bac8faa42f7ec067eb184c3f7847e97..da949e75160351363b0ec2513deb81143a5ec6ea 100644 (file)
@@ -37,7 +37,9 @@ BlockIter TrackIter::block_iter() const
 
        if(!_track->get_type().is_turnout())
        {
-               TrackIter rev = reverse();
+               /* Since there was no endpoint match, the preceding track can't be in a
+               different block. */
+               TrackIter rev = flip();
                TrackIter last;
                while(rev && &rev.track()->get_block()==&block)
                {