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); |