@@ -69,6 +69,7 @@ public partial class MainWindow : Window
6969
7070 // filter by distance
7171 private readonly float cellSize = 0.5f ;
72+ // TODO Replace ConcurrentDictionary<(int,int,int),byte> with a compact, contention-free structure
7273 private static ConcurrentDictionary < ( int , int , int ) , byte > occupiedCells = new ( ) ;
7374
7475 // plugins
@@ -570,6 +571,7 @@ public class ProgressInfo
570571 public long MaxValue { get ; internal set ; } // Maximum value for the progress
571572 public string FilePath { get ; internal set ; }
572573 public bool UseJsonLog { get ; internal set ; }
574+ public int LastPercent = - 1 ;
573575 }
574576
575577 static void InitProgressBars ( ImportSettings importSettings )
@@ -634,57 +636,34 @@ static void ProgressTick(object sender, EventArgs e)
634636 // Update all progress bars based on the current values in the List
635637 lock ( lockObject ) // Lock to safely read progressInfos
636638 {
637- foreach ( var progressInfo in progressInfos )
639+ foreach ( var info in progressInfos )
638640 {
639- int index = progressInfo . Index ;
640- long currentValue = progressInfo . CurrentValue ;
641- long maxValue = progressInfo . MaxValue ;
642-
643- // Access ProgressBar directly from the StackPanel.Children using its index
644- if ( index >= 0 && index < mainWindowStatic . ProgressBarsContainer . Children . Count )
641+ int idx = info . Index ;
642+ long cur = info . CurrentValue ;
643+ long max = info . MaxValue <= 0 ? 1 : info . MaxValue ; // avoid /0
644+ int percent = ( int ) ( 100L * cur / max ) ;
645+
646+ // Update UI bar
647+ if ( idx >= 0 && idx < mainWindowStatic . ProgressBarsContainer . Children . Count &&
648+ mainWindowStatic . ProgressBarsContainer . Children [ idx ] is ProgressBar bar )
645649 {
646- if ( mainWindowStatic . ProgressBarsContainer . Children [ index ] is ProgressBar progressBar )
647- {
648- progressBar . Maximum = maxValue ;
649- progressBar . Value = currentValue ;
650- progressBar . Foreground = ( ( currentValue + 1 >= maxValue ) ? Brushes . Lime : Brushes . Red ) ; //+1 hack fix
651- //progressBar.ToolTip = $"Thread {index} - {currentValue} / {maxValue}"; // not visible, because modal dialog
652- //Log.Write("ProgressTick: " + index + " " + currentValue + " / " + maxValue);
653-
654- // print json progress
655- if ( progressInfo . UseJsonLog ) // TODO now same bool value is for each progressinfo..
656- {
657- string jsonString = "{" +
658- "\" event\" : \" " + LogEvent . Progress + "\" ," +
659- "\" thread\" : " + index + "," +
660- "\" currentPoint\" : " + currentValue + "," +
661- "\" totalPoints\" : " + maxValue + "," +
662- "\" percentage\" : " + ( int ) ( ( currentValue / ( float ) maxValue ) * 100.0 ) + "," +
663- "\" file\" : " + System . Text . Json . JsonSerializer . Serialize ( progressInfo . FilePath ) +
664- "}" ;
665- Log . Write ( jsonString , LogEvent . Progress ) ;
666- }
667- }
650+ bar . Maximum = max ;
651+ bar . Value = cur ;
652+ bar . Foreground = ( ( cur + 1 >= max ) ? Brushes . Lime : Brushes . Red ) ;
668653 }
669- } // foreach progressinfo
670- } // lock
671- //}
672- //else // finished ?
673- //{
674- // Log.Write("*************** ProgressTick: progressTotalPoints is 0, finishing..");
675- // mainWindowStatic.progressBarFiles.Value = 0;
676- // mainWindowStatic.lblStatus.Content = "";
677-
678- // foreach (UIElement element in mainWindowStatic.ProgressBarsContainer.Children)
679- // {
680- // if (element is ProgressBar progressBar)
681- // {
682- // progressBar.Value = 0;
683- // progressBar.Foreground = Brushes.Lime;
684- // }
685- // }
686- //}
654+
655+ // Emit JSON ONLY when percentage changes
656+ if ( info . UseJsonLog && percent != info . LastPercent )
657+ {
658+ info . LastPercent = percent ;
659+
660+ // Efficient JSON (no string concat)
661+ LogExtensions . WriteProgressUtf8 ( Log , threadIndex : idx , current : cur , total : max , percent : percent , filePath : info . FilePath ) ;
662+ } // foreach progressinfo
663+ } // lock
664+ }
687665 } ) ;
666+
688667 } // ProgressTick()
689668
690669
0 commit comments