A game framework written with osu! in mind.

Debounce detection task, ensuring it only runs once (and after all devices are present)

+24 -13
+24 -13
osu.Framework/Input/Handlers/Tablet/TabletDriver.cs
··· 6 6 using System.Collections.Generic; 7 7 using System.IO; 8 8 using System.Linq; 9 + using System.Threading; 9 10 using System.Threading.Tasks; 10 11 using Newtonsoft.Json; 11 12 using OpenTabletDriver; ··· 25 26 Log.Output += (sender, logMessage) => Logger.Log($"{logMessage.Group}: {logMessage.Message}", level: (LogLevel)logMessage.Level); 26 27 DevicesChanged += (sender, args) => 27 28 { 29 + // it's worth noting that this event fires on *any* device change system-wide, including non-tablet devices. 28 30 if (Tablet == null && args.Additions.Any()) 29 31 DetectTablet(); 30 32 }; 31 33 } 32 34 33 - private Task detectionTask; 35 + private readonly object detectLock = new object(); 36 + 37 + private CancellationTokenSource cancellationSource; 34 38 35 39 public void DetectTablet() 36 40 { 37 - if (detectionTask?.IsCompleted == false) 38 - return; 41 + lock (detectLock) 42 + { 43 + cancellationSource?.Cancel(); 39 44 40 - detectionTask = Task.Run(() => 41 - { 42 - var foundVendor = CurrentDevices.Select(d => d.VendorID).Intersect(known_vendors).FirstOrDefault(); 45 + var cancellationToken = (cancellationSource = new CancellationTokenSource()).Token; 43 46 44 - if (foundVendor > 0) 47 + Task.Run(async () => 45 48 { 46 - Logger.Log($"Tablet detected (vid{foundVendor}), searching for usable configuration..."); 49 + // wait a small delay as multiple devices may appear over a very short interval. 50 + await Task.Delay(50, cancellationToken).ConfigureAwait(false); 51 + 52 + var foundVendor = CurrentDevices.Select(d => d.VendorID).Intersect(known_vendors).FirstOrDefault(); 47 53 48 - foreach (var config in getConfigurations()) 54 + if (foundVendor > 0) 49 55 { 50 - if (TryMatch(config)) 51 - break; 56 + Logger.Log($"Tablet detected (vid{foundVendor}), searching for usable configuration..."); 57 + 58 + foreach (var config in getConfigurations()) 59 + { 60 + if (TryMatch(config)) 61 + break; 62 + } 52 63 } 53 - } 54 - }); 64 + }, cancellationToken); 65 + } 55 66 } 56 67 57 68 private IEnumerable<TabletConfiguration> getConfigurations()