A game framework written with osu! in mind.
at master 85 lines 3.1 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4#if NET5_0 5using System; 6using System.Collections.Generic; 7using System.IO; 8using System.Linq; 9using System.Threading; 10using System.Threading.Tasks; 11using Newtonsoft.Json; 12using OpenTabletDriver; 13using OpenTabletDriver.Plugin; 14using OpenTabletDriver.Plugin.Tablet; 15using osu.Framework.Logging; 16using LogLevel = osu.Framework.Logging.LogLevel; 17 18namespace osu.Framework.Input.Handlers.Tablet 19{ 20 public class TabletDriver : Driver 21 { 22 private static readonly IEnumerable<int> known_vendors = Enum.GetValues<DeviceVendor>().Cast<int>(); 23 24 public TabletDriver() 25 { 26 Log.Output += (sender, logMessage) => Logger.Log($"{logMessage.Group}: {logMessage.Message}", level: (LogLevel)logMessage.Level); 27 DevicesChanged += (sender, args) => 28 { 29 // it's worth noting that this event fires on *any* device change system-wide, including non-tablet devices. 30 if (Tablet == null && args.Additions.Any()) 31 DetectTablet(); 32 }; 33 } 34 35 private readonly object detectLock = new object(); 36 37 private CancellationTokenSource cancellationSource; 38 39 public void DetectTablet() 40 { 41 lock (detectLock) 42 { 43 cancellationSource?.Cancel(); 44 45 var cancellationToken = (cancellationSource = new CancellationTokenSource()).Token; 46 47 Task.Run(async () => 48 { 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(); 53 54 if (foundVendor > 0) 55 { 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 } 63 } 64 }, cancellationToken); 65 } 66 } 67 68 private IEnumerable<TabletConfiguration> getConfigurations() 69 { 70 // Retrieve all embedded configurations 71 var asm = typeof(Driver).Assembly; 72 return asm.GetManifestResourceNames() 73 .Where(path => path.Contains(".json")) 74 .Select(path => deserialize(asm.GetManifestResourceStream(path))); 75 } 76 77 private TabletConfiguration deserialize(Stream stream) 78 { 79 using (var reader = new StreamReader(stream)) 80 using (var jsonReader = new JsonTextReader(reader)) 81 return new JsonSerializer().Deserialize<TabletConfiguration>(jsonReader); 82 } 83 } 84} 85#endif