-
Notifications
You must be signed in to change notification settings - Fork 396
Expand file tree
/
Copy pathOFPADecodingContext.cs
More file actions
92 lines (79 loc) · 2.94 KB
/
OFPADecodingContext.cs
File metadata and controls
92 lines (79 loc) · 2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.Utilities
{
/// <summary>
/// Shared async decoding context for OFPA filenames.
/// Handles scheduling, stale-guard, PropertyChanged notification,
/// and reactive enable/disable in response to Repository.EnableOFPADecoding changes.
/// </summary>
internal sealed class OFPADecodingContext : ObservableObject, IDisposable
{
public IReadOnlyDictionary<string, string> DecodedPaths => _decodedPaths;
public OFPADecodingContext(ViewModels.Repository repo, Action onReEnabled)
{
_repo = repo;
_onReEnabled = onReEnabled;
_repo.PropertyChanged += OnRepositoryPropertyChanged;
}
public void Dispose()
{
if (_repo != null)
_repo.PropertyChanged -= OnRepositoryPropertyChanged;
_repo = null;
_onReEnabled = null;
}
/// <summary>
/// Schedule an async OFPA decode. The caller provides a factory
/// that returns the decoded path map. Stale requests are discarded.
/// </summary>
public void ScheduleRefresh(Func<Task<Dictionary<string, string>>> lookupFactory)
{
var requestId = Interlocked.Increment(ref _requestId);
_ = RunAsync(lookupFactory, requestId);
}
public void Clear()
{
Interlocked.Increment(ref _requestId);
_decodedPaths = null;
OnPropertyChanged(nameof(DecodedPaths));
}
private async Task RunAsync(Func<Task<Dictionary<string, string>>> lookupFactory, long requestId)
{
Dictionary<string, string> results = null;
try
{
results = await lookupFactory().ConfigureAwait(false);
}
catch (Exception)
{
// Decode failures are non-fatal; raw paths remain visible.
}
await Dispatcher.UIThread.InvokeAsync(() =>
{
if (_repo == null || !_repo.EnableOFPADecoding || requestId != Interlocked.Read(ref _requestId))
return;
_decodedPaths = results;
OnPropertyChanged(nameof(DecodedPaths));
});
}
private void OnRepositoryPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != nameof(ViewModels.Repository.EnableOFPADecoding))
return;
if (_repo?.EnableOFPADecoding == true)
_onReEnabled?.Invoke();
else
Clear();
}
private ViewModels.Repository _repo;
private Action _onReEnabled;
private Dictionary<string, string> _decodedPaths;
private long _requestId;
}
}