1- using System . Collections . Generic ;
1+ using System ;
2+ using System . Collections ;
3+ using System . Collections . Concurrent ;
4+ using System . Collections . Generic ;
25using System . Linq ;
36using System . Reflection ;
4-
7+ using System . Threading ;
58using HarmonyLib ;
69using RimWorld ;
710using UnityEngine ;
@@ -13,6 +16,9 @@ internal class ModSwitch : Mod {
1316
1417 public static bool IsRestartDefered ;
1518
19+ public volatile static IDictionary < string , uint > TSUpdateCache = new ConcurrentDictionary < string , uint > ( ) ;
20+
21+
1622 static ModSwitch ( ) {
1723 fiModLister_mods = AccessTools . Field ( typeof ( ModLister ) , "mods" ) ;
1824 }
@@ -30,14 +36,16 @@ public ModSwitch(ModContentPack content) : base(content) {
3036
3137 CustomSettings = GetSettings < Settings > ( ) ;
3238
33- if ( ModsConfigUI . Helpers . PreInitTSUpdateCache . Count != null ) {
34- var entries = ModsConfigUI . Helpers . PreInitTSUpdateCache . ToArray ( ) ;
35- ModsConfigUI . Helpers . PreInitTSUpdateCache . Clear ( ) ;
36- Log . Message ( $ "ModSwitch - copying cached steam TS values.") ;
3739
38- foreach ( KeyValuePair < string , uint > cachedTSValue in entries ) {
40+ var cachedValues = Interlocked . Exchange ( ref TSUpdateCache , new SteamUpdateAdapter ( CustomSettings ) ) ;
41+ if ( cachedValues . Count != 0 ) {
42+ // yes, there may *still* be a race condition where we overwrite a later, but previously written, update timestamp with a cached, but earlier timestamp... not going to block threads here
43+
44+ Log . Message ( $ "ModSwitch - copying cached steam TS values.") ;
45+ foreach ( KeyValuePair < string , uint > cachedTSValue in cachedValues ) {
3946 CustomSettings . Attributes [ cachedTSValue . Key ] . LastUpdateTS = cachedTSValue . Value ;
4047 }
48+
4149 }
4250 }
4351
@@ -57,5 +65,72 @@ public override void DoSettingsWindowContents(Rect inRect) {
5765 public override string SettingsCategory ( ) {
5866 return LanguageKeys . keyed . ModSwitch . Translate ( ) ;
5967 }
68+
69+ /// <summary>
70+ /// <em>Severely</em> restricted dictionary adapter for writing steam TS updates to ModSwitch settings.
71+ /// <em>ONLY</em> the index setter <seealso cref="SteamUpdateAdapter.this"/> is actually implemented.
72+ /// All other calls will fail.
73+ /// </summary>
74+ private class SteamUpdateAdapter : IDictionary < string , uint > {
75+ private readonly Settings _owner ;
76+
77+ public SteamUpdateAdapter ( Settings owner ) {
78+ _owner = owner ;
79+ }
80+
81+ public IEnumerator < KeyValuePair < string , uint > > GetEnumerator ( ) {
82+ throw new NotImplementedException ( ) ;
83+ }
84+
85+ IEnumerator IEnumerable . GetEnumerator ( ) {
86+ return GetEnumerator ( ) ;
87+ }
88+
89+ public void Add ( KeyValuePair < string , uint > item ) {
90+ throw new NotImplementedException ( ) ;
91+ }
92+
93+ public void Clear ( ) {
94+ throw new NotImplementedException ( ) ;
95+ }
96+
97+ public bool Contains ( KeyValuePair < string , uint > item ) {
98+ throw new NotImplementedException ( ) ;
99+ }
100+
101+ public void CopyTo ( KeyValuePair < string , uint > [ ] array , int arrayIndex ) {
102+ throw new NotImplementedException ( ) ;
103+ }
104+
105+ public bool Remove ( KeyValuePair < string , uint > item ) {
106+ throw new NotImplementedException ( ) ;
107+ }
108+
109+ public int Count { get ; }
110+ public bool IsReadOnly { get ; }
111+ public bool ContainsKey ( string key ) {
112+ throw new NotImplementedException ( ) ;
113+ }
114+
115+ public void Add ( string key , uint value ) {
116+ throw new NotImplementedException ( ) ;
117+ }
118+
119+ public bool Remove ( string key ) {
120+ throw new NotImplementedException ( ) ;
121+ }
122+
123+ public bool TryGetValue ( string key , out uint value ) {
124+ throw new NotImplementedException ( ) ;
125+ }
126+
127+ public uint this [ string key ] {
128+ get => throw new NotImplementedException ( ) ;
129+ set => _owner . Attributes [ key ] . LastUpdateTS = value ;
130+ }
131+
132+ public ICollection < string > Keys => throw new NotImplementedException ( ) ;
133+ public ICollection < uint > Values => throw new NotImplementedException ( ) ;
134+ }
60135 }
61136}
0 commit comments