Skip to content

Commit 4ad866e

Browse files
authored
Refactored to be thread safe. (#3973)
1 parent f26fd28 commit 4ad866e

File tree

1 file changed

+155
-69
lines changed

1 file changed

+155
-69
lines changed

Terminal.Gui/Drawing/Color/ColorScheme.Colors.cs

+155-69
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ namespace Terminal.Gui;
1111
/// </summary>
1212
public sealed class Colors : INotifyCollectionChanged, IDictionary<string, ColorScheme?>
1313
{
14+
private static readonly object _lock = new object ();
15+
1416
static Colors ()
1517
{
16-
ColorSchemes = new (5, StringComparer.InvariantCultureIgnoreCase);
18+
ColorSchemes = new Dictionary<string, ColorScheme?> (5, StringComparer.InvariantCultureIgnoreCase);
1719
Reset ();
1820
}
1921

@@ -66,111 +68,195 @@ static Colors ()
6668
[UsedImplicitly]
6769
public static Dictionary<string, ColorScheme?> ColorSchemes { get; private set; }
6870

69-
/// <inheritdoc/>
70-
public IEnumerator<KeyValuePair<string, ColorScheme?>> GetEnumerator () { return ColorSchemes.GetEnumerator (); }
71-
72-
/// <inheritdoc/>
73-
IEnumerator IEnumerable.GetEnumerator () { return GetEnumerator (); }
71+
/// <summary>
72+
/// Raised when the collection changes.
73+
/// </summary>
74+
public event NotifyCollectionChangedEventHandler? CollectionChanged;
7475

75-
/// <inheritdoc/>
76-
public void Add (KeyValuePair<string, ColorScheme?> item)
76+
/// <inheritdoc />
77+
public ColorScheme? this [string key]
7778
{
78-
ColorSchemes.Add (item.Key, item.Value);
79-
CollectionChanged?.Invoke (this, new (NotifyCollectionChangedAction.Add, item));
79+
get
80+
{
81+
lock (_lock)
82+
{
83+
return ColorSchemes [key];
84+
}
85+
}
86+
set
87+
{
88+
lock (_lock)
89+
{
90+
if (ColorSchemes.ContainsKey (key))
91+
{
92+
ColorScheme? oldValue = ColorSchemes [key];
93+
ColorSchemes [key] = value;
94+
CollectionChanged?.Invoke (this, new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Replace, value, oldValue));
95+
}
96+
else
97+
{
98+
ColorSchemes.Add (key, value);
99+
CollectionChanged?.Invoke (this, new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Add, new KeyValuePair<string, ColorScheme?> (key, value)));
100+
}
101+
}
102+
}
80103
}
81104

82-
/// <inheritdoc/>
83-
public void Clear ()
105+
/// <inheritdoc />
106+
public int Count
84107
{
85-
ColorSchemes.Clear ();
86-
CollectionChanged?.Invoke (this, new (NotifyCollectionChangedAction.Reset));
108+
get
109+
{
110+
lock (_lock)
111+
{
112+
return ColorSchemes.Count;
113+
}
114+
}
87115
}
88116

89-
/// <inheritdoc/>
90-
public bool Contains (KeyValuePair<string, ColorScheme?> item) { return ColorSchemes.Contains (item); }
91-
92-
/// <inheritdoc/>
93-
public void CopyTo (KeyValuePair<string, ColorScheme?> [] array, int arrayIndex) { ((ICollection)ColorSchemes).CopyTo (array, arrayIndex); }
117+
/// <inheritdoc />
118+
public bool IsReadOnly => false;
94119

95-
/// <inheritdoc/>
96-
public bool Remove (KeyValuePair<string, ColorScheme?> item)
120+
/// <inheritdoc />
121+
public ICollection<string> Keys
97122
{
98-
if (ColorSchemes.Remove (item.Key))
123+
get
99124
{
100-
CollectionChanged?.Invoke (this, new (NotifyCollectionChangedAction.Remove, item));
101-
102-
return true;
125+
lock (_lock)
126+
{
127+
return new List<string> (ColorSchemes.Keys);
128+
}
103129
}
130+
}
104131

105-
return false;
132+
/// <inheritdoc />
133+
public ICollection<ColorScheme?> Values
134+
{
135+
get
136+
{
137+
lock (_lock)
138+
{
139+
return new List<ColorScheme?> (ColorSchemes.Values);
140+
}
141+
}
106142
}
107143

108-
/// <inheritdoc/>
109-
public int Count => ColorSchemes.Count;
144+
/// <inheritdoc />
145+
public void Add (KeyValuePair<string, ColorScheme?> item)
146+
{
147+
lock (_lock)
148+
{
149+
ColorSchemes.Add (item.Key, item.Value);
150+
CollectionChanged?.Invoke (this, new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Add, item));
151+
}
152+
}
110153

111-
/// <inheritdoc/>
112-
public bool IsReadOnly => false;
154+
/// <inheritdoc />
155+
public void Add (string key, ColorScheme? value)
156+
{
157+
Add (new KeyValuePair<string, ColorScheme?> (key, value));
158+
}
113159

114-
/// <inheritdoc/>
115-
public void Add (string key, ColorScheme? value) { Add (new (key, value)); }
160+
/// <inheritdoc />
161+
public void Clear ()
162+
{
163+
lock (_lock)
164+
{
165+
ColorSchemes.Clear ();
166+
CollectionChanged?.Invoke (this, new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Reset));
167+
}
168+
}
116169

117-
/// <inheritdoc/>
118-
public bool ContainsKey (string key) { return ColorSchemes.ContainsKey (key); }
170+
/// <inheritdoc />
171+
public bool Contains (KeyValuePair<string, ColorScheme?> item)
172+
{
173+
lock (_lock)
174+
{
175+
return ColorSchemes.Contains (item);
176+
}
177+
}
119178

120-
/// <inheritdoc/>
121-
public bool Remove (string key)
179+
/// <inheritdoc />
180+
public bool ContainsKey (string key)
122181
{
123-
if (ColorSchemes.Remove (key))
182+
lock (_lock)
124183
{
125-
CollectionChanged?.Invoke (this, new (NotifyCollectionChangedAction.Remove, key));
184+
return ColorSchemes.ContainsKey (key);
185+
}
186+
}
126187

127-
return true;
188+
public void CopyTo (KeyValuePair<string, ColorScheme?> [] array, int arrayIndex)
189+
{
190+
lock (_lock)
191+
{
192+
((ICollection)ColorSchemes).CopyTo (array, arrayIndex);
128193
}
194+
}
129195

130-
return false;
196+
public IEnumerator<KeyValuePair<string, ColorScheme?>> GetEnumerator ()
197+
{
198+
lock (_lock)
199+
{
200+
return new List<KeyValuePair<string, ColorScheme?>> (ColorSchemes).GetEnumerator ();
201+
}
131202
}
132203

133-
/// <inheritdoc/>
134-
public bool TryGetValue (string key, out ColorScheme? value) { return ColorSchemes.TryGetValue (key, out value); }
204+
IEnumerator IEnumerable.GetEnumerator ()
205+
{
206+
return GetEnumerator ();
207+
}
135208

136-
/// <inheritdoc/>
137-
public ColorScheme? this [string key]
209+
public bool Remove (KeyValuePair<string, ColorScheme?> item)
138210
{
139-
get => ColorSchemes [key];
140-
set
211+
lock (_lock)
141212
{
142-
if (ColorSchemes.TryAdd (key, value))
213+
if (ColorSchemes.Remove (item.Key))
143214
{
144-
CollectionChanged?.Invoke (this, new (NotifyCollectionChangedAction.Add, new KeyValuePair<string, ColorScheme?> (key, value)));
215+
CollectionChanged?.Invoke (this, new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Remove, item));
216+
return true;
145217
}
146-
else
218+
return false;
219+
}
220+
}
221+
222+
public bool Remove (string key)
223+
{
224+
lock (_lock)
225+
{
226+
if (ColorSchemes.Remove (key))
147227
{
148-
ColorScheme? oldValue = ColorSchemes [key];
149-
ColorSchemes [key] = value;
150-
CollectionChanged?.Invoke (this, new (NotifyCollectionChangedAction.Replace, value, oldValue));
228+
CollectionChanged?.Invoke (this, new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Remove, key));
229+
return true;
151230
}
231+
return false;
152232
}
153233
}
154234

155-
/// <inheritdoc/>
156-
public ICollection<string> Keys => ColorSchemes.Keys;
235+
/// <inheritdoc />
236+
public bool TryGetValue (string key, out ColorScheme? value)
237+
{
238+
lock (_lock)
239+
{
240+
return ColorSchemes.TryGetValue (key, out value);
241+
}
242+
}
157243

158-
/// <inheritdoc/>
159-
public ICollection<ColorScheme?> Values => ColorSchemes.Values;
160244

161-
/// <inheritdoc/>
162-
public event NotifyCollectionChangedEventHandler? CollectionChanged;
163-
164-
/// <summary>Resets the <see cref="ColorSchemes"/> dictionary to the default values.</summary>
245+
/// <summary>
246+
/// Resets the <see cref="ColorSchemes"/> dictionary to its default values.
247+
/// </summary>
248+
/// <returns></returns>
165249
public static Dictionary<string, ColorScheme?> Reset ()
166250
{
167-
ColorSchemes.Clear ();
168-
ColorSchemes.Add ("TopLevel", new ());
169-
ColorSchemes.Add ("Base", new ());
170-
ColorSchemes.Add ("Dialog", new ());
171-
ColorSchemes.Add ("Menu", new ());
172-
ColorSchemes.Add ("Error", new ());
173-
174-
return ColorSchemes;
251+
lock (_lock)
252+
{
253+
ColorSchemes.Clear ();
254+
ColorSchemes.Add ("TopLevel", new ColorScheme ());
255+
ColorSchemes.Add ("Base", new ColorScheme ());
256+
ColorSchemes.Add ("Dialog", new ColorScheme ());
257+
ColorSchemes.Add ("Menu", new ColorScheme ());
258+
ColorSchemes.Add ("Error", new ColorScheme ());
259+
return ColorSchemes;
260+
}
175261
}
176-
}
262+
}

0 commit comments

Comments
 (0)