+void Route::update_turnout(Track &track)
+{
+ if(!track.get_type().is_turnout())
+ return;
+
+ // Build a combined path mask from linked endpoints
+ unsigned nls = track.get_n_link_slots();
+ unsigned mask = track.get_type().get_paths();
+ for(unsigned i=0; i<nls; ++i)
+ {
+ Track *link = track.get_link(i);
+ if(!tracks.count(link))
+ continue;
+
+ unsigned ep_mask = track.get_type().get_endpoint(i).paths;
+ if(link->get_type().is_turnout())
+ {
+ const TrackType::Endpoint &link_ep = link->get_type().get_endpoint(link->get_link_slot(track));
+ int p = get_turnout(link->get_turnout_address());
+ if(p>=0 && !link_ep.has_path(p))
+ // The linked track is a turnout and has a path which is incompatible with this endpoint
+ ep_mask = ~ep_mask;
+ }
+
+ mask &= ep_mask;
+ }
+
+ unsigned taddr = track.get_turnout_address();
+ if(mask && !(mask&(mask-1)))
+ {
+ // Exactly one possible choice, set the path accordingly
+ unsigned path = 0;
+ for(; (mask && !(mask&1)); mask>>=1, ++path) ;
+ turnouts[taddr] = path;
+ }
+ else if(!turnouts.count(taddr))
+ // More than one possible choice, and no existing entry - set as undecided
+ turnouts[taddr] = -1;
+}
+