20
20
using System . Collections . Generic ;
21
21
using System . IO ;
22
22
using System . Linq ;
23
+ using System . Threading ;
23
24
using System . Threading . Tasks ;
24
25
using xivModdingFramework . General . Enums ;
25
26
using xivModdingFramework . Helpers ;
@@ -37,6 +38,7 @@ public class Modding
37
38
{
38
39
private readonly DirectoryInfo _gameDirectory ;
39
40
private readonly Version _modlistVersion = new Version ( 1 , 0 ) ;
41
+ private static SemaphoreSlim _modlistSemaphore = new SemaphoreSlim ( 1 ) ;
40
42
41
43
public DirectoryInfo ModListDirectory { get ; }
42
44
@@ -52,14 +54,79 @@ public Modding(DirectoryInfo gameDirectory)
52
54
53
55
}
54
56
57
+ // Caching information for modlists.
58
+ private static Dictionary < string , DateTime > _cachedModlistsModTime = new Dictionary < string , DateTime > ( ) ;
59
+ private static Dictionary < string , ModList > _cachedModlists = new Dictionary < string , ModList > ( ) ;
55
60
public ModList GetModList ( )
56
61
{
57
- return JsonConvert . DeserializeObject < ModList > ( File . ReadAllText ( ModListDirectory . FullName ) ) ;
62
+ ModList val ;
63
+ _modlistSemaphore . Wait ( ) ;
64
+ try
65
+ {
66
+ var modTime = File . GetLastWriteTime ( ModListDirectory . FullName ) ;
67
+ if ( _cachedModlists . ContainsKey ( ModListDirectory . FullName ) && modTime <= _cachedModlistsModTime [ ModListDirectory . FullName ] )
68
+ {
69
+ // We have a cached file, and the modList file has not been touched since we cached it.
70
+ // Return the cached copy (Skip full read & Json deserialize)
71
+ val = _cachedModlists [ ModListDirectory . FullName ] ;
72
+ }
73
+ else
74
+ {
75
+ // Cache was either stale or missing, load the file from disk and update cache.
76
+ val = JsonConvert . DeserializeObject < ModList > ( File . ReadAllText ( ModListDirectory . FullName ) ) ;
77
+ modTime = File . GetLastWriteTime ( ModListDirectory . FullName ) ;
78
+
79
+ _cachedModlists [ ModListDirectory . FullName ] = val ;
80
+ _cachedModlistsModTime [ ModListDirectory . FullName ] = modTime ;
81
+
82
+ }
83
+ } finally {
84
+ _modlistSemaphore . Release ( ) ;
85
+ }
86
+ return val ;
87
+ }
88
+ public async Task < ModList > GetModListAsync ( )
89
+ {
90
+ ModList val ;
91
+ await _modlistSemaphore . WaitAsync ( ) ;
92
+ try
93
+ {
94
+ var modTime = File . GetLastWriteTime ( ModListDirectory . FullName ) ;
95
+ if ( _cachedModlists . ContainsKey ( ModListDirectory . FullName ) && modTime <= _cachedModlistsModTime [ ModListDirectory . FullName ] )
96
+ {
97
+ // We have a cached file, and the modList file has not been touched since we cached it.
98
+ // Return the cached copy (Skip full read & Json deserialize)
99
+ val = _cachedModlists [ ModListDirectory . FullName ] ;
100
+ }
101
+ else
102
+ {
103
+ // Cache was either stale or missing, load the file from disk and update cache.
104
+ val = JsonConvert . DeserializeObject < ModList > ( File . ReadAllText ( ModListDirectory . FullName ) ) ;
105
+ modTime = File . GetLastWriteTime ( ModListDirectory . FullName ) ;
106
+
107
+ _cachedModlists [ ModListDirectory . FullName ] = val ;
108
+ _cachedModlistsModTime [ ModListDirectory . FullName ] = modTime ;
109
+
110
+ }
111
+ }
112
+ finally
113
+ {
114
+ _modlistSemaphore . Release ( ) ;
115
+ }
116
+ return val ;
58
117
}
59
118
60
119
public void SaveModList ( ModList ml )
61
120
{
121
+ _modlistSemaphore . Wait ( ) ;
122
+ File . WriteAllText ( ModListDirectory . FullName , JsonConvert . SerializeObject ( ml , Formatting . Indented ) ) ;
123
+ _modlistSemaphore . Release ( ) ;
124
+ }
125
+ public void SaveModListAsync ( ModList ml )
126
+ {
127
+ _modlistSemaphore . WaitAsync ( ) ;
62
128
File . WriteAllText ( ModListDirectory . FullName , JsonConvert . SerializeObject ( ml , Formatting . Indented ) ) ;
129
+ _modlistSemaphore . Release ( ) ;
63
130
}
64
131
65
132
public async Task DeleteAllFilesAddedByTexTools ( )
0 commit comments