From 59eed1faa56c34a32cb669c0f36e03d24ec063d3 Mon Sep 17 00:00:00 2001 From: X9VoiD Date: Wed, 30 Nov 2022 02:26:47 +0800 Subject: [PATCH] Fix relative mode issues --- .../Pointer/VMultiAbsolutePointer.cs | 12 ++- .../Pointer/VMultiRelativePointer.cs | 14 +-- .../VMultiMode/VMultiButtonHandler.cs | 4 +- .../VMultiMode/VMultiModeConstants.cs | 4 +- .../Pointer/WinInkAbsolutePointer.cs | 4 +- .../WindowsInk/Pointer/WinInkBasePointer.cs | 28 ++++-- .../Pointer/WinInkRelativePointer.cs | 10 +- .../WindowsInk/WinInkButtonHandler.cs | 2 +- src/VoiDPlugins.Library/VoiD/SharedStore.cs | 96 +++++++------------ 9 files changed, 84 insertions(+), 90 deletions(-) diff --git a/src/OutputMode/VMultiMode/Pointer/VMultiAbsolutePointer.cs b/src/OutputMode/VMultiMode/Pointer/VMultiAbsolutePointer.cs index e16c142..901a936 100644 --- a/src/OutputMode/VMultiMode/Pointer/VMultiAbsolutePointer.cs +++ b/src/OutputMode/VMultiMode/Pointer/VMultiAbsolutePointer.cs @@ -20,13 +20,17 @@ namespace VoiDPlugins.OutputMode public VMultiAbsolutePointer(TabletReference tabletReference, IVirtualScreen virtualScreen) { - _instance = new VMultiInstance("VMultiAbs", new AbsoluteInputReport()); var sharedStore = SharedStore.GetStore(tabletReference, STORE_KEY); - if (!sharedStore.TryAdd(INSTANCE, _instance)) - _instance = sharedStore.Get>(INSTANCE); - + _instance = sharedStore.GetOrUpdate(ABS_INSTANCE, createInstance, out _); _rawPointer = _instance.Pointer; _conversionFactor = new Vector2(32767, 32767) / new Vector2(virtualScreen.Width, virtualScreen.Height); + + sharedStore.SetOrAdd(MODE, ABS_INSTANCE); + + static VMultiInstance createInstance() + { + return new VMultiInstance("VMultiAbs", new AbsoluteInputReport()); + } } public void SetPosition(Vector2 pos) diff --git a/src/OutputMode/VMultiMode/Pointer/VMultiRelativePointer.cs b/src/OutputMode/VMultiMode/Pointer/VMultiRelativePointer.cs index 54308a7..272a6d8 100644 --- a/src/OutputMode/VMultiMode/Pointer/VMultiRelativePointer.cs +++ b/src/OutputMode/VMultiMode/Pointer/VMultiRelativePointer.cs @@ -18,20 +18,22 @@ namespace VoiDPlugins.OutputMode public VMultiRelativePointer(TabletReference tabletReference) { - _instance = new VMultiInstance("VMultiRel", new RelativeInputReport()); var sharedStore = SharedStore.GetStore(tabletReference, STORE_KEY); - if (!sharedStore.TryAdd(INSTANCE, _instance)) - _instance = sharedStore.Get>(INSTANCE); - + _instance = sharedStore.GetOrUpdate(REL_INSTANCE, createInstance, out var updated); _rawPointer = _instance.Pointer; + + sharedStore.SetOrAdd(MODE, REL_INSTANCE); + + static VMultiInstance createInstance() + { + return new VMultiInstance("VMultiRel", new RelativeInputReport()); + } } public void SetPosition(Vector2 delta) { if (delta == Vector2.Zero && _prev == Vector2.Zero) return; - if (_rawPointer is null) - return; delta += _error; _error = new Vector2(delta.X % 1, delta.Y % 1); diff --git a/src/OutputMode/VMultiMode/VMultiButtonHandler.cs b/src/OutputMode/VMultiMode/VMultiButtonHandler.cs index 2df1983..066df38 100644 --- a/src/OutputMode/VMultiMode/VMultiButtonHandler.cs +++ b/src/OutputMode/VMultiMode/VMultiButtonHandler.cs @@ -33,7 +33,9 @@ namespace VoiDPlugins.OutputMode { try { - _instance = SharedStore.GetStore(tabletReference, STORE_KEY).Get(INSTANCE); + var sharedStore = SharedStore.GetStore(tabletReference, STORE_KEY); + var mode = sharedStore.Get(MODE); + _instance = sharedStore.Get(mode); } catch { diff --git a/src/OutputMode/VMultiMode/VMultiModeConstants.cs b/src/OutputMode/VMultiMode/VMultiModeConstants.cs index e76cc8c..e3fa4cf 100644 --- a/src/OutputMode/VMultiMode/VMultiModeConstants.cs +++ b/src/OutputMode/VMultiMode/VMultiModeConstants.cs @@ -3,6 +3,8 @@ namespace VoiDPlugins.OutputMode public static class VMultiModeConstants { public const string STORE_KEY = "VMultiMode"; - public const int INSTANCE = 0; + public const int MODE = 0; + public const int ABS_INSTANCE = 1; + public const int REL_INSTANCE = 2; } } \ No newline at end of file diff --git a/src/OutputMode/WindowsInk/Pointer/WinInkAbsolutePointer.cs b/src/OutputMode/WindowsInk/Pointer/WinInkAbsolutePointer.cs index 6985c99..7334c63 100644 --- a/src/OutputMode/WindowsInk/Pointer/WinInkAbsolutePointer.cs +++ b/src/OutputMode/WindowsInk/Pointer/WinInkAbsolutePointer.cs @@ -7,13 +7,11 @@ namespace VoiDPlugins.OutputMode { public unsafe class WinInkAbsolutePointer : WinInkBasePointer, IAbsolutePointer { - private readonly Vector2 _conversionFactor; private Vector2 _prev; public WinInkAbsolutePointer(TabletReference tabletReference, IVirtualScreen screen) : base("Windows Ink", tabletReference, screen) { - _conversionFactor = new Vector2(32767, 32767) / new Vector2(screen.Width, screen.Height); } public void SetPosition(Vector2 pos) @@ -23,7 +21,7 @@ namespace VoiDPlugins.OutputMode SetInternalPosition(pos); Instance.EnableButtonBit((int)WindowsInkButtonFlags.InRange); - pos *= _conversionFactor; + pos = Convert(pos); RawPointer->X = (ushort)pos.X; RawPointer->Y = (ushort)pos.Y; Dirty = true; diff --git a/src/OutputMode/WindowsInk/Pointer/WinInkBasePointer.cs b/src/OutputMode/WindowsInk/Pointer/WinInkBasePointer.cs index 88203b0..dbb9c05 100644 --- a/src/OutputMode/WindowsInk/Pointer/WinInkBasePointer.cs +++ b/src/OutputMode/WindowsInk/Pointer/WinInkBasePointer.cs @@ -12,6 +12,7 @@ namespace VoiDPlugins.OutputMode { public unsafe abstract class WinInkBasePointer : IPressureHandler, ITiltHandler, IEraserHandler, ISynchronousPointer { + private readonly Vector2 _conversionFactor; private readonly IVirtualScreen _screen; private ThinOSPointer? _osPointer; private Vector2 _internalPos; @@ -30,20 +31,22 @@ namespace VoiDPlugins.OutputMode public WinInkBasePointer(string name, TabletReference tabletReference, IVirtualScreen screen) { _screen = screen; - Instance = new VMultiInstance(name, new DigitizerInputReport()); + _conversionFactor = new Vector2(32767, 32767) / new Vector2(screen.Width, screen.Height); SharedStore = SharedStore.GetStore(tabletReference, STORE_KEY); - if (SharedStore.TryAdd(INSTANCE, Instance)) + Instance = SharedStore.GetOrUpdate(INSTANCE, createInstance, out var updated); + RawPointer = Instance.Pointer; + + if (updated) { - SharedStore.TryAdd(POINTER, this); - SharedStore.TryAdd(ERASER_STATE, false); - SharedStore.TryAdd(MANUAL_ERASER, false); - SharedStore.TryAdd(TIP_PRESSED, false); - RawPointer = Instance.Pointer; + SharedStore.SetOrAdd(POINTER, this); + SharedStore.SetOrAdd(ERASER_STATE, false); + SharedStore.SetOrAdd(MANUAL_ERASER, false); + SharedStore.SetOrAdd(TIP_PRESSED, false); } - else + + VMultiInstance createInstance() { - Instance = SharedStore.Get>(INSTANCE); - RawPointer = Instance.Pointer; + return new VMultiInstance(name, new DigitizerInputReport()); } } @@ -87,6 +90,11 @@ namespace VoiDPlugins.OutputMode } } + protected Vector2 Convert(Vector2 pos) + { + return pos * _conversionFactor; + } + protected void SetInternalPosition(Vector2 pos) { _internalPos = pos; diff --git a/src/OutputMode/WindowsInk/Pointer/WinInkRelativePointer.cs b/src/OutputMode/WindowsInk/Pointer/WinInkRelativePointer.cs index a6578f3..1ea1877 100644 --- a/src/OutputMode/WindowsInk/Pointer/WinInkRelativePointer.cs +++ b/src/OutputMode/WindowsInk/Pointer/WinInkRelativePointer.cs @@ -21,16 +21,18 @@ namespace VoiDPlugins.OutputMode public void SetPosition(Vector2 delta) { - if (_prev == Vector2.Zero && delta == Vector2.Zero) + if (delta == Vector2.Zero) return; - Instance.EnableButtonBit((int)WindowsInkButtonFlags.InRange); delta += _error; _error = new Vector2(delta.X % 1, delta.Y % 1); _currentPoint = Vector2.Clamp(_currentPoint + delta, Vector2.Zero, _maxPoint); + SetInternalPosition(_currentPoint); - RawPointer->X = (ushort)_currentPoint.X; - RawPointer->Y = (ushort)_currentPoint.Y; + Instance.EnableButtonBit((int)WindowsInkButtonFlags.InRange); + var pos = Convert(_currentPoint); + RawPointer->X = (ushort)pos.X; + RawPointer->Y = (ushort)pos.Y; Dirty = true; _prev = delta; } diff --git a/src/OutputMode/WindowsInk/WinInkButtonHandler.cs b/src/OutputMode/WindowsInk/WinInkButtonHandler.cs index 65ccb33..a2b8abf 100644 --- a/src/OutputMode/WindowsInk/WinInkButtonHandler.cs +++ b/src/OutputMode/WindowsInk/WinInkButtonHandler.cs @@ -97,7 +97,7 @@ namespace VoiDPlugins.OutputMode _instance.Write(); } - public static void EraserStateTransition(SharedStore store, VMultiInstance instance, bool isEraser) + internal static void EraserStateTransition(SharedStore store, VMultiInstance instance, bool isEraser) { var eraserState = store.Get(ERASER_STATE); if (eraserState != isEraser) diff --git a/src/VoiDPlugins.Library/VoiD/SharedStore.cs b/src/VoiDPlugins.Library/VoiD/SharedStore.cs index c77eb57..402fa5c 100644 --- a/src/VoiDPlugins.Library/VoiD/SharedStore.cs +++ b/src/VoiDPlugins.Library/VoiD/SharedStore.cs @@ -1,23 +1,16 @@ -using System.Collections; +using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using OpenTabletDriver.Plugin.Tablet; namespace VoiDPlugins.Library.VoiD { - public class SharedStore : IDictionary + public class SharedStore { private static readonly Dictionary> _storeMap = new(new Comparer()); private readonly Dictionary _sharedStore = new(); - public object this[int key] { get => ((IDictionary)_sharedStore)[key]; set => ((IDictionary)_sharedStore)[key] = value; } - public ICollection Keys => ((IDictionary)_sharedStore).Keys; - public ICollection Values => ((IDictionary)_sharedStore).Values; - public int Count => ((ICollection>)_sharedStore).Count; - public bool IsReadOnly => ((ICollection>)_sharedStore).IsReadOnly; - public static SharedStore GetStore(TabletReference reference, string storeKey) { lock (_storeMap) @@ -39,69 +32,52 @@ namespace VoiDPlugins.Library.VoiD return (T)_sharedStore[key]; } + public T GetOrUpdate(int key, Func valueFactory, out bool updated) + { + if (_sharedStore.TryGetValue(key, out object? value) && SafeCast(value) is T casted) + { + updated = false; + return casted; + } + + var newValue = valueFactory(); + _sharedStore[key] = newValue!; + updated = true; + return newValue; + } + public void Set(int key, T value) { _sharedStore[key] = value!; } - public void Add(int key, object value) + public void Add(int key, T value) { - ((IDictionary)_sharedStore).Add(key, value); + _sharedStore.Add(key, value!); } - public bool TryAdd(int key, object value) + public void SetOrAdd(int key, T value) { - return _sharedStore.TryAdd(key, value); + if (_sharedStore.ContainsKey(key)) + { + _sharedStore[key] = value!; + } + else + { + _sharedStore.Add(key, value!); + } } - public void Add(KeyValuePair item) + private static T? SafeCast(object value) { - ((ICollection>)_sharedStore).Add(item); - } - - public void Clear() - { - ((ICollection>)_sharedStore).Clear(); - } - - public bool Contains(KeyValuePair item) - { - return ((ICollection>)_sharedStore).Contains(item); - } - - public bool ContainsKey(int key) - { - return ((IDictionary)_sharedStore).ContainsKey(key); - } - - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - ((ICollection>)_sharedStore).CopyTo(array, arrayIndex); - } - - public IEnumerator> GetEnumerator() - { - return ((IEnumerable>)_sharedStore).GetEnumerator(); - } - - public bool Remove(int key) - { - return ((IDictionary)_sharedStore).Remove(key); - } - - public bool Remove(KeyValuePair item) - { - return ((ICollection>)_sharedStore).Remove(item); - } - - public bool TryGetValue(int key, [MaybeNullWhen(false)] out object value) - { - return ((IDictionary)_sharedStore).TryGetValue(key, out value); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return ((IEnumerable)_sharedStore).GetEnumerator(); + try + { + return (T)value; + } + catch + { + return default; + } } private class Comparer : IEqualityComparer