1
- using System . Collections . Generic ;
2
- using System . Diagnostics . Tracing ;
1
+ using System . Collections . Concurrent ;
2
+ using System . Collections . Generic ;
3
3
using System . Threading . Tasks ;
4
- using System . Windows . Forms ;
5
4
using BeatSaverSharp ;
6
5
using MultiplayerCore . Beatmaps . Abstractions ;
7
6
using MultiplayerCore . Beatmaps . Packets ;
7
+ using SiraUtil . Logging ;
8
8
using SiraUtil . Zenject ;
9
9
10
10
namespace MultiplayerCore . Beatmaps . Providers
11
11
{
12
12
public class MpBeatmapLevelProvider
13
13
{
14
14
private readonly BeatSaver _beatsaver ;
15
+ private readonly SiraLog _logger ;
15
16
private readonly Dictionary < string , MpBeatmap > _hashToNetworkMaps = new ( ) ;
16
- private readonly Dictionary < string , MpBeatmap > _hashToBeatsaverMaps = new ( ) ;
17
+ private readonly ConcurrentDictionary < string , Task < MpBeatmap ? > > _hashToBeatsaverMaps = new ( ) ;
17
18
18
19
internal MpBeatmapLevelProvider (
19
- UBinder < Plugin , BeatSaver > beatsaver )
20
+ UBinder < Plugin , BeatSaver > beatsaver ,
21
+ SiraLog logger )
20
22
{
21
23
_beatsaver = beatsaver . Value ;
24
+ _logger = logger ;
22
25
}
23
26
24
27
/// <summary>
@@ -44,23 +47,33 @@ internal MpBeatmapLevelProvider(
44
47
return new LocalBeatmapLevel ( levelHash , localBeatmapLevel ) ;
45
48
}
46
49
47
- /// <summary>
48
- /// Gets an <see cref="MpBeatmap"/> for the specified level hash from BeatSaver.
49
- /// </summary>
50
- /// <param name="levelHash">The hash of the level to get</param>
51
- /// <returns>An <see cref="MpBeatmap"/> with a matching level hash, or null if none was found.</returns>
52
- public async Task < MpBeatmap ? > GetBeatmapFromBeatSaver ( string levelHash )
50
+ /// <summary>
51
+ /// Gets an <see cref="MpBeatmap"/> for the specified level hash from BeatSaver.
52
+ /// </summary>
53
+ /// <param name="levelHash">The hash of the level to get</param>
54
+ /// <returns>An <see cref="MpBeatmap"/> with a matching level hash, or null if none was found.</returns>
55
+ public async Task < MpBeatmap ? > GetBeatmapFromBeatSaver ( string levelHash )
53
56
{
54
- if ( _hashToBeatsaverMaps . TryGetValue ( levelHash , out var map ) ) return map ;
55
- var beatmap = await _beatsaver . BeatmapByHash ( levelHash ) ;
56
- if ( beatmap != null )
57
+ if ( ! _hashToBeatsaverMaps . TryGetValue ( levelHash , out var map ) )
57
58
{
58
- map = new BeatSaverBeatmapLevel ( levelHash , beatmap ) ;
59
- _hashToBeatsaverMaps . Add ( levelHash , map ) ;
60
- return map ;
61
- }
59
+ map = Task . Run ( async ( ) =>
60
+ {
61
+ var beatmap = await _beatsaver . BeatmapByHash ( levelHash ) ;
62
+ if ( beatmap != null )
63
+ {
64
+ MpBeatmap bmap = new BeatSaverBeatmapLevel ( levelHash , beatmap ) ;
65
+ return bmap ;
66
+ }
67
+
68
+ return null ;
69
+ } ) ;
70
+
71
+ _hashToBeatsaverMaps [ levelHash ] = map ;
72
+ }
62
73
63
- return null ;
74
+ var bmap = await map ;
75
+ if ( bmap == null ) _hashToBeatsaverMaps . TryRemove ( levelHash , out _ ) ; // Ensure we remove null bmaps
76
+ return bmap ;
64
77
}
65
78
66
79
public BeatSaverPreviewMediaData MakeBeatSaverPreviewMediaData ( string levelHash ) => new BeatSaverPreviewMediaData ( _beatsaver , levelHash ) ;
0 commit comments