Skip to content

Commit 163c948

Browse files
authored
Merge pull request #21 from pauldendulk/fix/concurrent-excepton
Fix concurrent exception
2 parents 0aff25e + 0067293 commit 163c948

File tree

1 file changed

+28
-24
lines changed

1 file changed

+28
-24
lines changed
Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Collections.Generic;
1+
using System.Collections.Concurrent;
22
using System.Runtime.CompilerServices;
33
using SkiaSharp;
44

@@ -7,47 +7,51 @@ namespace VexTile.Renderer.Mvt.AliFlux;
77
// ReSharper disable once InconsistentNaming
88
public static class SKColorFactory
99
{
10-
private static readonly Dictionary<string, SKColor> Colours = new();
10+
// Use packed ARGB (0xAARRGGBB) as the key to avoid string allocations
11+
private static readonly ConcurrentDictionary<uint, SKColor> Colours = new();
1112

1213
// try to centralise this as tracking down where colours ar made is hard
1314
public static SKColor MakeColor(byte red, byte green, byte blue, byte alpha = 255, [CallerMemberName] string callerName = "<unknown>")
1415
{
15-
string key = MakeKey(red, green, blue, alpha);
16+
uint key = MakeKey(red, green, blue, alpha);
1617

17-
if (!Colours.TryGetValue(key, out SKColor color))
18-
{
19-
color = new SKColor(red, green, blue, alpha);
20-
Colours[key] = color;
18+
var color = Colours.GetOrAdd(key, _ => new SKColor(red, green, blue, alpha));
2119

2220
#if DEBUG_COLORS
23-
log.Debug($"{callerName} -> Created {key} :: SKColorFactory.MakeColor({red}, {green}, {blue}, {alpha})");
21+
var hex = MakeKeyHex(red, green, blue, alpha); // RRGGBBAA for readability
22+
log.Debug($"{callerName} -> GetOrAdd {hex} :: SKColorFactory.MakeColor({red}, {green}, {blue}, {alpha})");
2423
#endif
25-
}
26-
else
27-
{
28-
#if DEBUG_COLORS
29-
log.Debug($"{callerName} -> Got {key} :: SKColorFactory.MakeColor");
30-
#endif
31-
}
3224

3325
return color;
3426
}
3527

36-
private static string MakeKey(byte red, byte green, byte blue, byte alpha)
28+
private static uint MakeKey(byte red, byte green, byte blue, byte alpha)
3729
{
38-
string key = $"{red:x2}{green:x2}{blue:x2}{alpha:x2}";
39-
return key;
30+
// ARGB packed to match SKColor's internal layout
31+
return ((uint)alpha << 24) | ((uint)red << 16) | ((uint)green << 8) | blue;
4032
}
4133

42-
// make logging colors simpler
34+
#if DEBUG_COLORS
35+
// Keep previous readable logging format (RRGGBBAA)
36+
private static string MakeKeyHex(byte red, byte green, byte blue, byte alpha)
37+
{
38+
return $"{red:x2}{green:x2}{blue:x2}{alpha:x2}";
39+
}
40+
#endif
41+
42+
// Make logging colors simpler
4343
public static SKColor LogColor(SKColor color, [CallerMemberName] string callerName = "<unknown>")
4444
{
45-
string key = MakeKey(color.Red, color.Green, color.Blue, color.Alpha);
45+
// Use the packed ARGB from the color directly
46+
uint key = (uint)color;
47+
48+
_ = Colours.TryAdd(key, color);
49+
50+
#if DEBUG_COLORS
51+
var hex = MakeKeyHex(color.Red, color.Green, color.Blue, color.Alpha);
52+
log.Debug($"{callerName} -> Log {hex} :: SKColorFactory.LogColor");
53+
#endif
4654

47-
if (!Colours.TryGetValue(key, out _))
48-
{
49-
Colours.Add(key, color);
50-
}
5155
return color;
5256
}
5357
}

0 commit comments

Comments
 (0)