Skip to content

Commit fd6a71b

Browse files
NeWbY100claude
andcommitted
fix: correct IsBusy aggregation, dispatcher marshaling, and event leaks
- Extract UpdateIsBusy() to check all 6 busy flags consistently and add missing SrsReconstructor.IsRebuilding monitoring - Wrap CreatorViewModel and SrsCreatorViewModel OnProgress handlers in Dispatcher.BeginInvoke to prevent cross-thread ObservableCollection access - Replace anonymous PropertyChanged lambda with named handler in SampleRestorerViewModel so old entries can be unsubscribed on reload - Remove unused CancellationToken parameter from IBruteForceService.RunAsync Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 857acae commit fd6a71b

7 files changed

Lines changed: 46 additions & 14 deletions

File tree

ReScene.NET/Services/BruteForceService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class BruteForceService : IBruteForceService
1515

1616
private Manager? _manager;
1717

18-
public async Task<bool> RunAsync(BruteForceOptions options, CancellationToken ct)
18+
public async Task<bool> RunAsync(BruteForceOptions options)
1919
{
2020
var logger = new ReSceneLogger();
2121
logger.Logged += (s, e) => LogMessage?.Invoke(s, e);

ReScene.NET/Services/IBruteForceService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace ReScene.NET.Services;
44

55
public interface IBruteForceService
66
{
7-
Task<bool> RunAsync(BruteForceOptions options, CancellationToken ct);
7+
Task<bool> RunAsync(BruteForceOptions options);
88
void Stop();
99
event EventHandler<BruteForceProgressEventArgs>? Progress;
1010
event EventHandler<BruteForceStatusChangedEventArgs>? StatusChanged;

ReScene.NET/ViewModels/CreatorViewModel.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.ObjectModel;
2+
using System.Windows;
23
using CommunityToolkit.Mvvm.ComponentModel;
34
using CommunityToolkit.Mvvm.Input;
45
using ReScene.NET.Services;
@@ -214,9 +215,12 @@ private void CancelCreation()
214215

215216
private void OnProgress(object? _, SrrCreationProgressEventArgs e)
216217
{
217-
ProgressPercent = e.ProgressPercent;
218-
ProgressMessage = e.Message;
219-
Log(e.Message);
218+
Application.Current.Dispatcher.BeginInvoke(() =>
219+
{
220+
ProgressPercent = e.ProgressPercent;
221+
ProgressMessage = e.Message;
222+
Log(e.Message);
223+
});
220224
}
221225

222226
private void Log(string message)

ReScene.NET/ViewModels/MainWindowViewModel.cs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,31 +58,37 @@ public MainWindowViewModel(ISrrCreationService srrService, ISrsCreationService s
5858
if (e.PropertyName == nameof(InspectorViewModel.StatusMessage))
5959
StatusMessage = Inspector.StatusMessage;
6060
else if (e.PropertyName == nameof(InspectorViewModel.IsExporting))
61-
IsBusy = Inspector.IsExporting || Creator.IsCreating;
61+
UpdateIsBusy();
6262
};
6363

6464
Creator.PropertyChanged += (_, e) =>
6565
{
6666
if (e.PropertyName == nameof(CreatorViewModel.IsCreating))
67-
IsBusy = Inspector.IsExporting || Creator.IsCreating || SrsCreator.IsCreating;
67+
UpdateIsBusy();
6868
};
6969

7070
SrsCreator.PropertyChanged += (_, e) =>
7171
{
7272
if (e.PropertyName == nameof(SrsCreatorViewModel.IsCreating))
73-
IsBusy = Inspector.IsExporting || Creator.IsCreating || SrsCreator.IsCreating || Reconstructor.IsRunning;
73+
UpdateIsBusy();
7474
};
7575

7676
Reconstructor.PropertyChanged += (_, e) =>
7777
{
7878
if (e.PropertyName == nameof(ReconstructorViewModel.IsRunning))
79-
IsBusy = Inspector.IsExporting || Creator.IsCreating || SrsCreator.IsCreating || Reconstructor.IsRunning || SampleRestorer.IsRestoring;
79+
UpdateIsBusy();
80+
};
81+
82+
SrsReconstructor.PropertyChanged += (_, e) =>
83+
{
84+
if (e.PropertyName == nameof(SrsReconstructorViewModel.IsRebuilding))
85+
UpdateIsBusy();
8086
};
8187

8288
SampleRestorer.PropertyChanged += (_, e) =>
8389
{
8490
if (e.PropertyName == nameof(SampleRestorerViewModel.IsRestoring))
85-
IsBusy = Inspector.IsExporting || Creator.IsCreating || SrsCreator.IsCreating || Reconstructor.IsRunning || SampleRestorer.IsRestoring;
91+
UpdateIsBusy();
8692
};
8793
}
8894

@@ -110,6 +116,16 @@ public void OpenSceneFile(string filePath)
110116
Home.LoadRecentFiles();
111117
}
112118

119+
private void UpdateIsBusy()
120+
{
121+
IsBusy = Inspector.IsExporting
122+
|| Creator.IsCreating
123+
|| SrsCreator.IsCreating
124+
|| Reconstructor.IsRunning
125+
|| SrsReconstructor.IsRebuilding
126+
|| SampleRestorer.IsRestoring;
127+
}
128+
113129
public void Cleanup()
114130
{
115131
Inspector.Dispose();

ReScene.NET/ViewModels/ReconstructorViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ private async Task StartAsync()
757757

758758
// Run entirely on a background thread so the UI stays responsive
759759
// during setup (directory enumeration, input validation, etc.)
760-
bool success = await Task.Run(() => _bruteForceService.RunAsync(options, _cts.Token));
760+
bool success = await Task.Run(() => _bruteForceService.RunAsync(options));
761761

762762
// Mark final version entry
763763
if (_activeVersionIndex >= 0 && _activeVersionIndex < VersionEntries.Count)

ReScene.NET/ViewModels/SampleRestorerViewModel.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.ObjectModel;
2+
using System.ComponentModel;
23
using System.Diagnostics;
34
using System.Windows;
45
using CommunityToolkit.Mvvm.ComponentModel;
@@ -203,6 +204,8 @@ private void CancelRestore()
203204

204205
private void LoadSrsEntries()
205206
{
207+
foreach (var old in SrsEntries)
208+
old.PropertyChanged -= OnEntryPropertyChanged;
206209
SrsEntries.Clear();
207210

208211
try
@@ -217,7 +220,7 @@ private void LoadSrsEntries()
217220
SampleFileName = info.SampleFileName,
218221
IsSelected = true
219222
};
220-
entry.PropertyChanged += (_, _) => RestoreCommand.NotifyCanExecuteChanged();
223+
entry.PropertyChanged += OnEntryPropertyChanged;
221224
SrsEntries.Add(entry);
222225
}
223226

@@ -268,6 +271,11 @@ partial void OnMediaDirectoryPathChanged(string value)
268271
MatchMediaFiles();
269272
}
270273

274+
private void OnEntryPropertyChanged(object? _, PropertyChangedEventArgs e)
275+
{
276+
RestoreCommand.NotifyCanExecuteChanged();
277+
}
278+
271279
private void OnProgress(object? _, SrsReconstructionProgressEventArgs e)
272280
{
273281
Application.Current.Dispatcher.BeginInvoke(() =>

ReScene.NET/ViewModels/SrsCreatorViewModel.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.ObjectModel;
2+
using System.Windows;
23
using CommunityToolkit.Mvvm.ComponentModel;
34
using CommunityToolkit.Mvvm.Input;
45
using ReScene.NET.Services;
@@ -151,8 +152,11 @@ private void CancelCreation()
151152

152153
private void OnProgress(object? _, SrsCreationProgressEventArgs e)
153154
{
154-
ProgressMessage = e.Message;
155-
Log(e.Message);
155+
Application.Current.Dispatcher.BeginInvoke(() =>
156+
{
157+
ProgressMessage = e.Message;
158+
Log(e.Message);
159+
});
156160
}
157161

158162
private void Log(string message)

0 commit comments

Comments
 (0)