Skip to content

Commit ddbc399

Browse files
authored
Merge pull request #397 from IridiumIO/dev
Add pause and cancel functionality
2 parents e6a4ba4 + 33bd05d commit ddbc399

File tree

5 files changed

+143
-20
lines changed

5 files changed

+143
-20
lines changed

CompactGUI.Core/Compactor.vb

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,61 @@ Public Class Compactor
2525
Private _EFInfo As _WOF_FILE_COMPRESSION_INFO_V1
2626
Private _EFInfoPtr As IntPtr
2727

28+
Private _pauseSemaphore As New SemaphoreSlim(1, 2)
2829

2930

31+
Private _processedFileCount As New Concurrent.ConcurrentDictionary(Of String, Integer)
32+
33+
Private _cancellationTokenSource As New CancellationTokenSource
34+
3035
Public Async Function RunCompactAsync(Optional progressMonitor As IProgress(Of (percentageProgress As Integer, currentFile As String)) = Nothing) As Task(Of Boolean)
3136

3237
Dim FilesList = Await BuildWorkingFilesList()
3338
Dim totalFiles As Integer = FilesList.Count
34-
Dim processedFileCount As Integer = 0
39+
40+
_processedFileCount.Clear()
3541

3642
Await Parallel.ForEachAsync(FilesList,
37-
Function(file, _ctx)
38-
Dim res = WOFCompressFile(file)
39-
Dim incremented = Interlocked.Increment(processedFileCount)
40-
progressMonitor.Report((CInt(((incremented / totalFiles) * 100)), file))
41-
End Function).ConfigureAwait(False)
43+
Function(file, _ctx) As ValueTask
44+
Return New ValueTask(PauseAndProcessFile(file, _cancellationTokenSource.Token, totalFiles, progressMonitor))
45+
End Function).ConfigureAwait(False)
46+
47+
If _cancellationTokenSource.IsCancellationRequested Then Return False
4248

4349
Return True
4450
End Function
4551

52+
Private Async Function PauseAndProcessFile(file As String, _ctx As CancellationToken, totalFiles As Integer, progressMonitor As IProgress(Of (percentageProgress As Integer, currentFile As String))) As Task
53+
54+
If _ctx.IsCancellationRequested Then Return
55+
Try
56+
Await _pauseSemaphore.WaitAsync(_ctx).ConfigureAwait(False)
57+
_pauseSemaphore.Release()
58+
59+
Catch ex As OperationCanceledException
60+
Return
61+
End Try
62+
63+
If _ctx.IsCancellationRequested Then Return
64+
65+
Dim res = WOFCompressFile(file)
66+
_processedFileCount.TryAdd(file, 1)
67+
Dim incremented = _processedFileCount.Count
68+
progressMonitor.Report((CInt(((incremented / totalFiles) * 100)), file))
69+
End Function
70+
71+
Public Sub PauseCompression()
72+
_pauseSemaphore.Wait()
73+
End Sub
74+
75+
Public Sub ResumeCompression()
76+
If _pauseSemaphore.CurrentCount = 0 Then _pauseSemaphore.Release()
77+
End Sub
78+
79+
Public Sub Cancel()
80+
ResumeCompression()
81+
_cancellationTokenSource.Cancel()
82+
End Sub
4683

4784
Private Function WOFCompressFile(path As String)
4885

CompactGUI.Core/Uncompactor.vb

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,42 @@ Imports System.Threading
33

44
Public Class Uncompactor
55

6+
7+
Private _pauseSemaphore As New SemaphoreSlim(1, 2)
8+
Private _processedFileCount As New Concurrent.ConcurrentDictionary(Of String, Integer)
9+
Private _cancellationTokenSource As New CancellationTokenSource
10+
11+
612
Public Async Function UncompactFiles(filesList As List(Of String), Optional progressMonitor As IProgress(Of (percentageProgress As Integer, currentFile As String)) = Nothing) As Task(Of Boolean)
713

814
Dim totalFiles As Integer = filesList.Count
9-
Dim processedFiles As Integer = 0
1015

16+
_processedFileCount.Clear()
1117
Await Parallel.ForEachAsync(filesList,
12-
Function(file, _ctx)
13-
Dim res = WOFDecompressFile(file)
14-
Dim incremented = Interlocked.Increment(processedFiles)
15-
progressMonitor.Report((CInt(((incremented / totalFiles) * 100)), file))
16-
End Function).ConfigureAwait(False)
18+
Function(file, _ctx) As ValueTask
19+
Return New ValueTask(PauseAndProcessFile(file, _cancellationTokenSource.Token, totalFiles, progressMonitor))
20+
End Function).ConfigureAwait(False)
1721
Return True
1822
End Function
1923

24+
Private Async Function PauseAndProcessFile(file As String, _ctx As CancellationToken, totalFiles As Integer, progressMonitor As IProgress(Of (percentageProgress As Integer, currentFile As String))) As Task
25+
If _ctx.IsCancellationRequested Then Return
26+
27+
Try
28+
Await _pauseSemaphore.WaitAsync(_ctx).ConfigureAwait(False)
29+
_pauseSemaphore.Release()
30+
31+
Catch ex As OperationCanceledException
32+
Return
33+
End Try
34+
35+
If _ctx.IsCancellationRequested Then Return
36+
Dim res = WOFDecompressFile(file)
37+
_processedFileCount.TryAdd(file, 1)
38+
Dim incremented = _processedFileCount.Count
39+
progressMonitor.Report((CInt(((incremented / totalFiles) * 100)), file))
40+
End Function
41+
2042
Private Function WOFDecompressFile(path As String)
2143

2244
Try
@@ -32,4 +54,17 @@ Public Class Uncompactor
3254

3355
End Function
3456

57+
58+
Public Sub PauseCompression()
59+
_pauseSemaphore.Wait()
60+
End Sub
61+
62+
Public Sub ResumeCompression()
63+
If _pauseSemaphore.CurrentCount = 0 Then _pauseSemaphore.Release()
64+
End Sub
65+
Public Sub Cancel()
66+
ResumeCompression()
67+
_cancellationTokenSource.Cancel()
68+
End Sub
69+
3570
End Class

CompactGUI/Models/UpdateHandler.vb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Imports System.Text.Json
33
Public Class UpdateHandler
44

5-
Public Shared CurrentVersion As New SemVersion(3, 0, 4)
5+
Public Shared CurrentVersion As New SemVersion(3, 1, 0)
66
Public Shared NewVersion As SemVersion
77
Shared UpdateURL As String = "https://raw.githubusercontent.com/IridiumIO/CompactGUI/database/version.json"
88

CompactGUI/ViewModels/MainViewModel.vb

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,14 @@ Public Class MainViewModel : Inherits ObservableObject
146146
End Sub
147147

148148

149+
Private Property CoreCompactor As Core.Compactor
150+
Private Property CoreUncompactor As Core.Uncompactor
151+
149152
Private Async Sub CompressBegin()
150153

151154
State = "CurrentlyCompressing"
155+
PauseResumeStatus = "Pause"
156+
CancelStatus = "Cancel"
152157
Watcher.IsActive = True
153158
CProgress.Report((0, ""))
154159

@@ -161,10 +166,11 @@ Public Class MainViewModel : Inherits ObservableObject
161166
End If
162167

163168

164-
Dim cm As New Core.Compactor(ActiveFolder.FolderName, Core.WOFConvertCompressionLevel(ActiveFolder.SelectedCompressionMode), exclist)
165-
Dim res = Await cm.RunCompactAsync(CProgress)
169+
CoreCompactor = New Core.Compactor(ActiveFolder.FolderName, Core.WOFConvertCompressionLevel(ActiveFolder.SelectedCompressionMode), exclist)
170+
Dim res = Await CoreCompactor.RunCompactAsync(CProgress)
166171

167-
ActiveFolder.IsFreshlyCompressed = True
172+
ActiveFolder.IsFreshlyCompressed = False
173+
If res Then ActiveFolder.IsFreshlyCompressed = True
168174

169175
BindableSettings.SelectedCompressionMode = ActiveFolder.SelectedCompressionMode
170176
BindableSettings.Save()
@@ -176,11 +182,14 @@ Public Class MainViewModel : Inherits ObservableObject
176182

177183
Private Async Sub UncompressBegin()
178184
State = "CurrentlyCompressing"
185+
PauseResumeStatus = "Pause"
186+
CancelStatus = "Cancel"
187+
179188
CProgress.Report((0, ""))
180189

181190
Dim compressedFilesList = ActiveFolder.AnalysisResults.Where(Function(rs) rs.CompressedSize < rs.UncompressedSize).Select(Of String)(Function(f) f.FileName).ToList
182-
Dim ucm As New Core.Uncompactor
183-
Dim res = Await ucm.UncompactFiles(compressedFilesList, CProgress)
191+
CoreUncompactor = New Core.Uncompactor
192+
Dim res = Await CoreUncompactor.UncompactFiles(compressedFilesList, CProgress)
184193

185194
ActiveFolder.IsFreshlyCompressed = False
186195
AnalyseBegin()
@@ -283,6 +292,8 @@ Public Class MainViewModel : Inherits ObservableObject
283292
End Get
284293
End Property
285294
Public ReadOnly Property Version As String = UpdateHandler.CurrentVersion.Friendly
295+
Public Property PauseResumeStatus As String = "Pause"
296+
Public Property CancelStatus As String = "Cancel"
286297

287298
#End Region
288299

@@ -297,7 +308,26 @@ Public Class MainViewModel : Inherits ObservableObject
297308
Public Property RemoveWatcherCommand As ICommand = New RelayCommand(Of Watcher.WatchedFolder)(Sub(f) Watcher.RemoveWatched(f))
298309
Public Property ReCompressWatchedCommand As ICommand = New RelayCommand(Of Watcher.WatchedFolder)(Sub(f) SelectFolder(f.Folder))
299310
Property RefreshWatchedCommand As ICommand = New RelayCommand(Sub() Task.Run(Function() Watcher.ParseWatchers(True)))
300-
311+
Public Property PauseCompressionCommand As RelayCommand = New RelayCommand(Sub()
312+
313+
If PauseResumeStatus = "Pause" Then
314+
PauseResumeStatus = "Pausing..."
315+
If CoreCompactor IsNot Nothing Then CoreCompactor.PauseCompression()
316+
If CoreUncompactor IsNot Nothing Then CoreUncompactor.PauseCompression()
317+
PauseResumeStatus = "Resume"
318+
Else
319+
If CoreCompactor IsNot Nothing Then CoreCompactor.ResumeCompression()
320+
If CoreUncompactor IsNot Nothing Then CoreUncompactor.ResumeCompression()
321+
PauseResumeStatus = "Pause"
322+
End If
323+
324+
End Sub)
325+
326+
Public Property CancelCompressionCommand As RelayCommand = New RelayCommand(Sub()
327+
CancelStatus = "Cancelling..."
328+
If CoreCompactor IsNot Nothing Then CoreCompactor.Cancel()
329+
If CoreUncompactor IsNot Nothing Then CoreUncompactor.Cancel()
330+
End Sub)
301331

302332
#End Region
303333

CompactGUI/Views/MainWindow.xaml

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1004,8 +1004,29 @@
10041004

10051005
<TextBlock x:Name="uiCurrentFileCompress" d:Text="/test/folder/gamefile.bin" Text="{Binding WorkingProgress.Item2, Mode=OneWay}" Margin="0,187,0,0" Foreground="#73808C" Opacity="0.4" FontSize="20" TextAlignment="Center" TextTrimming="CharacterEllipsis"/>
10061006

1007+
<StackPanel Orientation="Horizontal"
1008+
Margin="0,240,0,0"
1009+
VerticalAlignment="Top" HorizontalAlignment="Center">
1010+
<Button x:Name="btnPause"
1011+
Content="{Binding PauseResumeStatus}"
1012+
Background="#806B8399"
1013+
Width="138"
1014+
Height="48" Margin="20,0"
1015+
Foreground="White"
1016+
Style="{StaticResource RoundedButton}"
1017+
Command="{Binding PauseCompressionCommand}" />
1018+
<Button x:Name="btnCancel"
1019+
Content="{Binding CancelStatus, Mode=OneWay}"
1020+
Background="#806B8399"
1021+
Width="138"
1022+
Margin="20,0"
1023+
Height="48"
1024+
Foreground="White"
1025+
Style="{StaticResource RoundedButton}"
1026+
Command="{Binding CancelCompressionCommand}" />
1027+
</StackPanel>
10071028

1008-
</Grid>
1029+
</Grid>
10091030

10101031

10111032
</Grid>

0 commit comments

Comments
 (0)