@@ -15,6 +15,33 @@ namespace DCL.Prefs
1515 /// </summary>
1616 public static class DCLPlayerPrefs
1717 {
18+ /// <summary>
19+ /// A stub to ensure graceful shutdown
20+ /// </summary>
21+ private sealed class DisposedDCLPlayerPrefs : IDCLPrefs
22+ {
23+ public void SetString ( string key , string value ) => Warn ( ) ;
24+ public void SetInt ( string key , int value ) => Warn ( ) ;
25+ public void SetFloat ( string key , float value ) => Warn ( ) ;
26+ public void SetBool ( string key , bool value ) => Warn ( ) ;
27+ public string GetString ( string key , string def ) { Warn ( ) ; return def ; }
28+ public int GetInt ( string key , int def ) { Warn ( ) ; return def ; }
29+ public float GetFloat ( string key , float def ) { Warn ( ) ; return def ; }
30+ public bool GetBool ( string key , bool def ) { Warn ( ) ; return def ; }
31+ public bool HasKey ( string key ) { Warn ( ) ; return false ; }
32+ public void DeleteKey ( string key ) => Warn ( ) ;
33+ public void DeleteAll ( ) => Warn ( ) ;
34+ public void Save ( ) => Warn ( ) ;
35+ public void SaveSync ( ) => Warn ( ) ;
36+
37+ [ System . Diagnostics . Conditional ( "UNITY_EDITOR" ) ]
38+ private static void Warn ( [ System . Runtime . CompilerServices . CallerMemberName ] string caller = "" )
39+ {
40+ // TODO: Use ReportHub when it properly lives in its own dependency.
41+ Debug . LogWarning ( $ "[DCLPlayerPrefs] { caller } called after shutdown — ignored.") ;
42+ }
43+ }
44+
1845 private const string VECTOR2_KEY_FORMAT = "{0}_{1}" ;
1946
2047 private static IDCLPrefs dclPrefs ;
@@ -135,7 +162,8 @@ private static void OnQuitting()
135162
136163 System . Diagnostics . Stopwatch stopwatch = System . Diagnostics . Stopwatch . StartNew ( ) ;
137164 ( dclPrefs as IDisposable ) ? . Dispose ( ) ;
138- dclPrefs = null ;
165+ // Avoid any shutdown exceptions, just throw warnings.
166+ dclPrefs = new DisposedDCLPlayerPrefs ( ) ;
139167 Debug . Log ( $ "[ExitUtils] [DCLPlayerPrefs] cleanup took { stopwatch . ElapsedMilliseconds } ms") ;
140168 }
141169
0 commit comments