]> git.tdb.fi Git - r2c2.git/commitdiff
Fix some problems with loading routes
authorMikko Rasa <tdb@tdb.fi>
Wed, 27 Jan 2010 21:17:22 +0000 (21:17 +0000)
committerMikko Rasa <tdb@tdb.fi>
Wed, 27 Jan 2010 21:17:22 +0000 (21:17 +0000)
Document some algorithms with comments
Add paths to the double-slip turnout

source/libmarklin/layout.cpp
source/libmarklin/route.cpp
tracks.dat

index 38336ae8d98f5ff6c3dfe3cbd3b4bc0e3c4bb4ab..afd5f03f81affe1c6cf5a8cb30f8077a0e12daed 100644 (file)
@@ -114,9 +114,11 @@ void Layout::check_routes()
 {
        for(map<string, Route *>::iterator i=routes.begin(); i!=routes.end(); ++i)
        {
-               // We must copy the turnout map, since adding tracks to the route will (temporarily) mess it up
+               /* We must copy the turnout map, since adding tracks to the route will
+               (temporarily) mess it up */
                const map<unsigned, int> turnouts = i->second->get_turnouts();
 
+               // Find any turnout in the route
                Track *track = 0;
                unsigned trk_path = 0;
                for(set<Track *>::const_iterator j=tracks.begin(); j!=tracks.end(); ++j)
@@ -133,35 +135,47 @@ void Layout::check_routes()
                if(!track)
                        continue;
 
-               i->second->add_track(*track);
-
+               // Find an applicable endpoint
                const vector<Endpoint> &eps = track->get_type().get_endpoints();
                unsigned ep = 0;
-               for(unsigned j=0; j<eps.size(); ++i)
+               for(unsigned j=0; j<eps.size(); ++j)
                        if(eps[j].paths&(1<<trk_path))
                        {
                                ep = j;
                                break;
                        }
 
-               Track *start = track;
+               Track *start = 0;
                while(1)
                {
+                       // Traverse the track and get the next one
                        unsigned out_ep = track->traverse(ep, trk_path);
                        Track *next = track->get_links()[out_ep];
                        if(!next || next == start)
                                break;
+
                        ep = next->get_endpoint_by_link(*track);
                        if(next->get_type().get_n_paths()>1)
                        {
+                               // Select correct path across the turnout, or break if we hit an unknown turnout
                                map<unsigned, int>::const_iterator j = turnouts.find(next->get_turnout_id());
                                if(j==turnouts.end())
                                        break;
                                trk_path = j->second;
                        }
                        else
+                       {
                                trk_path = 0;
-                       i->second->add_track(*next);
+
+                               /* Start adding tracks when we find the first non-turnout.  This
+                               prevents the occurrence of ambiguities while adding the tracks */
+                               if(!start)
+                                       start = next;
+                       }
+
+                       if(start)
+                               i->second->add_track(*next);
+
                        track = next;
                }
        }
index 40638d9683051fd3fa4581b14f3d6458d89d4880..20017d240a429562a1e7e3907999eb40c2a2ebb6 100644 (file)
@@ -92,17 +92,20 @@ void Route::update_turnouts()
                        const vector<Endpoint> &endpoints = (*i)->get_type().get_endpoints();
                        const vector<Track *> &links = (*i)->get_links();
 
+                       // Build a combined path mask from linked endpoints
                        unsigned mask = 15;
                        for(unsigned j=0; j<endpoints.size(); ++j)
                        {
                                if(!tracks.count(links[j]))
                                        continue;
+
                                if(unsigned tid2=links[j]->get_turnout_id())
                                {
                                        const Endpoint &ep = links[j]->get_type().get_endpoints()[links[j]->get_endpoint_by_link(**i)];
                                        int p = get_turnout(tid2);
                                        if(p>=0 && !(ep.paths&(1<<p)))
                                        {
+                                               // The linked track is a turnout and has a path which is incompatible with this endpoint
                                                mask &= ~endpoints[j].paths;
                                                continue;
                                        }
@@ -110,16 +113,19 @@ void Route::update_turnouts()
                                mask &= endpoints[j].paths;
                        }
 
-                       if(!(mask&(mask-1)))
+                       if(mask && !(mask&(mask-1)))
                        {
+                               // Exactly one possible choice, set the path accordingly
                                unsigned path = 0;
                                for(; (mask && !(mask&1)); mask>>=1, ++path) ;
                                turnouts[tid] = path;
                        }
-                       else
+                       else if(!turnouts.count(tid))
+                               // More than one possible choice, and no existing entry - set as undecided
                                turnouts[tid] = -1;
                }
 
+       // Remove any turnouts that do not exist in the route
        for(map<unsigned, int>::iterator i=turnouts.begin(); i!=turnouts.end();)
        {
                if(!found.count(i->first))
@@ -137,6 +143,7 @@ unsigned Route::check_validity(const Track &trk) const
                int epi=(*i)->get_endpoint_by_link(trk);
                if(epi>=0)
                {
+                       // Linked to an existing track - good
                        result |= 1;
                        const vector<Endpoint> &endpoints = (*i)->get_type().get_endpoints();
                        if(unsigned tid=(*i)->get_turnout_id())
@@ -144,11 +151,13 @@ unsigned Route::check_validity(const Track &trk) const
                                int r = get_turnout(tid);
                                if(r>=0)
                                {
+                                       // Linking to a turnout with path set is only good if we're continuing that path
                                        if(endpoints[epi].paths&(1<<r))
                                                result |= 2;
                                }
                                else
                                {
+                                       // Linked to a turnout with no path set - find out other linked tracks 
                                        unsigned count = 0;
                                        const vector<Track *> &links = (*i)->get_links();
                                        int epj = -1;
@@ -158,15 +167,19 @@ unsigned Route::check_validity(const Track &trk) const
                                                        ++count;
                                                        epj = k;
                                                }
+
+                                       // Only good if at most one other track is linked to the turnout
                                        if(count<=1)
                                        {
                                                result |= 2;
                                                if(epj>=0 && !(endpoints[epi].paths&endpoints[epj].paths))
+                                                       // Impossible path through the turnout - not good
                                                        result &= 3;
                                        }
                                }
                        }
                        else
+                               // Linked to something linear - good
                                result |= 2;
                }
        }
index 5fb597f8766fb8a11eec5caa50575c1e2b15e746..86089d021c9b870d4c48aff4dfa3c812ac8aafe4 100644 (file)
@@ -312,26 +312,30 @@ track 24630
 
 track 24624
 {
-       description "Turnout, double crossing";
+       description "Turnout, double slip";
        part
        {
                length 188.3;
+               path 0;
        };
        part
        {
                length 24.3;
                radius -437.5;
+               path 1;
        };
        part
        {
                start 8.34 38.74 -24.3;
                length 188.3;
+               path 2;
        };
        part
        {
                start 8.34 38.74 -24.3;
                length 24.3;
                radius 437.5;
+               path 3;
        };
 };