@@ -64,7 +64,7 @@ public class Signals
6464 public int noSignals ;
6565 private int foundSignals ;
6666
67- private static int updatecount ;
67+ private static int UpdateIndex ;
6868
6969 public List < TrackCircuitSection > TrackCircuitList ;
7070 private Dictionary < int , CrossOverItem > CrossoverList = new Dictionary < int , CrossOverItem > ( ) ;
@@ -553,6 +553,11 @@ private void BuildSignalWorld(Simulator simulator, SignalConfigurationFile sigcf
553553
554554 } //BuildSignalWorld
555555
556+ Stopwatch UpdateTimer = new Stopwatch ( ) ;
557+ long UpdateCounter = 0 ;
558+ long UpdateTickTarget = 10000 ;
559+ // long DebugUpdateCounter = 0;
560+
556561 /// <summary>
557562 /// Update : perform signal updates
558563 /// </summary>
@@ -562,30 +567,39 @@ public void Update(bool preUpdate)
562567
563568 if ( foundSignals > 0 )
564569 {
565-
566570 // loop through all signals
567571 // update required part
568- // in preupdate, process all
569-
570- int totalSignal = foundSignals ;
571-
572- int updatestep = ( totalSignal / 20 ) + 1 ;
573- if ( preUpdate )
574- {
575- updatestep = totalSignal ;
576- }
577-
578- for ( int icount = updatecount ; icount < Math . Min ( totalSignal , updatecount + updatestep ) ; icount ++ )
572+ var updates = 0 ;
573+ var updateStep = 0 ;
574+ var targetTicks = Stopwatch . GetTimestamp ( ) + UpdateTickTarget ;
575+ UpdateTimer . Start ( ) ;
576+ while ( updateStep < foundSignals )
579577 {
580- SignalObject signal = SignalObjects [ icount ] ;
578+ var signal = SignalObjects [ ( UpdateIndex + updateStep ) % foundSignals ] ;
581579 if ( signal != null && ! signal . noupdate ) // to cater for orphans, and skip signals which do not require updates
582580 {
583581 signal . Update ( ) ;
582+ updates ++ ;
584583 }
584+ updateStep ++ ;
585+
586+ // in preupdate, process all
587+ if ( ! preUpdate && updates % 10 == 0 && Stopwatch . GetTimestamp ( ) >= targetTicks ) break ;
585588 }
589+ UpdateCounter += updates ;
590+ UpdateTimer . Stop ( ) ;
586591
587- updatecount += updatestep ;
588- updatecount = updatecount >= totalSignal ? 0 : updatecount ;
592+ if ( UpdateIndex + updateStep >= foundSignals )
593+ {
594+ // Calculate how long it takes to update all signals and target 1/20th of that
595+ // Slow adjustment using clamp stops it jumping around too much
596+ var ticksPerSignal = ( double ) UpdateTimer . ElapsedTicks / UpdateCounter ;
597+ UpdateTickTarget = ( long ) MathHelper . Clamp ( ( float ) ( ticksPerSignal * foundSignals / 20 ) , UpdateTickTarget - 100 , UpdateTickTarget + 100 ) ;
598+ // if (++DebugUpdateCounter % 10 == 0) Trace.WriteLine($"Signal update for {UpdateCounter,5} signals took {(double)UpdateTimer.ElapsedTicks * 1000 / Stopwatch.Frequency,9:F6} ms ({ticksPerSignal * 1000 / Stopwatch.Frequency,9:F6} ms/signal); new {(double)UpdateTickTarget * 1000 / Stopwatch.Frequency,6:F6} ms target");
599+ UpdateTimer . Reset ( ) ;
600+ UpdateCounter = 0 ;
601+ }
602+ UpdateIndex = ( UpdateIndex + updateStep ) % foundSignals ;
589603 }
590604 }
591605
0 commit comments