src/signal.cpp
changeset 9791 7bcdf05e5e5b
parent 9775 22e256c3bf46
child 9818 bec6961fb6b6
equal deleted inserted replaced
9790:5d5c70e0334e 9791:7bcdf05e5e5b
   254 	SF_EXIT   = 1 << 1, ///< exitsignal found
   254 	SF_EXIT   = 1 << 1, ///< exitsignal found
   255 	SF_EXIT2  = 1 << 2, ///< two or more exits found
   255 	SF_EXIT2  = 1 << 2, ///< two or more exits found
   256 	SF_GREEN  = 1 << 3, ///< green exitsignal found
   256 	SF_GREEN  = 1 << 3, ///< green exitsignal found
   257 	SF_GREEN2 = 1 << 4, ///< two or more green exits found
   257 	SF_GREEN2 = 1 << 4, ///< two or more green exits found
   258 	SF_FULL   = 1 << 5, ///< some of buffers was full, do not continue
   258 	SF_FULL   = 1 << 5, ///< some of buffers was full, do not continue
       
   259 	SF_PBS    = 1 << 6, ///< pbs signal found
   259 };
   260 };
   260 
   261 
   261 DECLARE_ENUM_AS_BIT_SET(SigFlags)
   262 DECLARE_ENUM_AS_BIT_SET(SigFlags)
   262 
   263 
   263 
   264 
   321 					if (HasSignalOnTrack(tile, track)) { // now check whole track, not trackdir
   322 					if (HasSignalOnTrack(tile, track)) { // now check whole track, not trackdir
   322 						SignalType sig = GetSignalType(tile, track);
   323 						SignalType sig = GetSignalType(tile, track);
   323 						Trackdir trackdir = (Trackdir)FindFirstBit((tracks * 0x101) & _enterdir_to_trackdirbits[enterdir]);
   324 						Trackdir trackdir = (Trackdir)FindFirstBit((tracks * 0x101) & _enterdir_to_trackdirbits[enterdir]);
   324 						Trackdir reversedir = ReverseTrackdir(trackdir);
   325 						Trackdir reversedir = ReverseTrackdir(trackdir);
   325 						/* add (tile, reversetrackdir) to 'to-be-updated' set when there is
   326 						/* add (tile, reversetrackdir) to 'to-be-updated' set when there is
   326 						 * ANY signal in REVERSE direction
   327 						 * ANY conventional signal in REVERSE direction
   327 						 * (if it is a presignal EXIT and it changes, it will be added to 'to-be-done' set later) */
   328 						 * (if it is a presignal EXIT and it changes, it will be added to 'to-be-done' set later) */
   328 						if (HasSignalOnTrackdir(tile, reversedir)) {
   329 						if (HasSignalOnTrackdir(tile, reversedir)) {
   329 							if (!_tbuset.Add(tile, reversedir)) return flags | SF_FULL;
   330 							if (IsPbsSignal(sig)) {
       
   331 								flags |= SF_PBS;
       
   332 							} else if (!_tbuset.Add(tile, reversedir)) {
       
   333 								return flags | SF_FULL;
       
   334 							}
   330 						}
   335 						}
       
   336 						if (HasSignalOnTrackdir(tile, trackdir) && !IsOnewaySignal(tile, track)) flags |= SF_PBS;
       
   337 
   331 						/* if it is a presignal EXIT in OUR direction and we haven't found 2 green exits yes, do special check */
   338 						/* if it is a presignal EXIT in OUR direction and we haven't found 2 green exits yes, do special check */
   332 						if (!(flags & SF_GREEN2) && (sig & SIGTYPE_EXIT) && HasSignalOnTrackdir(tile, trackdir)) { // found presignal exit
   339 						if (!(flags & SF_GREEN2) && IsPresignalExit(tile, track) && HasSignalOnTrackdir(tile, trackdir)) { // found presignal exit
   333 							if (flags & SF_EXIT) flags |= SF_EXIT2; // found two (or more) exits
   340 							if (flags & SF_EXIT) flags |= SF_EXIT2; // found two (or more) exits
   334 							flags |= SF_EXIT; // found at least one exit - allow for compiler optimizations
   341 							flags |= SF_EXIT; // found at least one exit - allow for compiler optimizations
   335 							if (GetSignalStateByTrackdir(tile, trackdir) == SIGNAL_STATE_GREEN) { // found green presignal exit
   342 							if (GetSignalStateByTrackdir(tile, trackdir) == SIGNAL_STATE_GREEN) { // found green presignal exit
   336 								if (flags & SF_GREEN) flags |= SF_GREEN2;
   343 								if (flags & SF_GREEN) flags |= SF_GREEN2;
   337 								flags |= SF_GREEN;
   344 								flags |= SF_GREEN;
   338 							}
   345 							}
   339 						}
   346 						}
       
   347 
   340 						continue;
   348 						continue;
   341 					}
   349 					}
   342 				}
   350 				}
   343 
   351 
   344 				for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) { // test all possible exit directions
   352 				for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) { // test all possible exit directions
   432 						/* only one green exit, and it is this one - so all other exits are red */
   440 						/* only one green exit, and it is this one - so all other exits are red */
   433 						(!(flags & SF_GREEN2) && GetSignalStateByTrackdir(tile, ReverseTrackdir(trackdir)) == SIGNAL_STATE_GREEN))) {
   441 						(!(flags & SF_GREEN2) && GetSignalStateByTrackdir(tile, ReverseTrackdir(trackdir)) == SIGNAL_STATE_GREEN))) {
   434 					newstate = SIGNAL_STATE_RED;
   442 					newstate = SIGNAL_STATE_RED;
   435 				}
   443 				}
   436 			} else { // entry, at least one exit, no green exit
   444 			} else { // entry, at least one exit, no green exit
   437 				if (sig & SIGTYPE_ENTRY && (flags & SF_EXIT && !(flags & SF_GREEN))) newstate = SIGNAL_STATE_RED;
   445 				if (IsPresignalEntry(tile, TrackdirToTrack(trackdir)) && flags & SF_EXIT && !(flags & SF_GREEN)) newstate = SIGNAL_STATE_RED;
   438 			}
   446 			}
   439 		}
   447 		}
   440 
   448 
   441 		/* only when the state changes */
   449 		/* only when the state changes */
   442 		if (newstate != GetSignalStateByTrackdir(tile, trackdir)) {
   450 		if (newstate != GetSignalStateByTrackdir(tile, trackdir)) {
   443 			if (sig & SIGTYPE_EXIT) {
   451 			if (IsPresignalExit(tile, TrackdirToTrack(trackdir))) {
   444 				/* for pre-signal exits, add block to the global set */
   452 				/* for pre-signal exits, add block to the global set */
   445 				DiagDirection exitdir = TrackdirToExitdir(ReverseTrackdir(trackdir));
   453 				DiagDirection exitdir = TrackdirToExitdir(ReverseTrackdir(trackdir));
   446 				_globset.Add(tile, exitdir); // do not check for full global set, first update all signals
   454 				_globset.Add(tile, exitdir); // do not check for full global set, first update all signals
   447 			}
   455 			}
   448 			SetSignalStateByTrackdir(tile, trackdir, newstate);
   456 			SetSignalStateByTrackdir(tile, trackdir, newstate);