Fix relative mode issues

This commit is contained in:
X9VoiD 2022-11-30 02:26:47 +08:00
parent aa6c011fd8
commit 59eed1faa5
9 changed files with 84 additions and 90 deletions

View file

@ -20,13 +20,17 @@ namespace VoiDPlugins.OutputMode
public VMultiAbsolutePointer(TabletReference tabletReference, IVirtualScreen virtualScreen)
{
_instance = new VMultiInstance<AbsoluteInputReport>("VMultiAbs", new AbsoluteInputReport());
var sharedStore = SharedStore.GetStore(tabletReference, STORE_KEY);
if (!sharedStore.TryAdd(INSTANCE, _instance))
_instance = sharedStore.Get<VMultiInstance<AbsoluteInputReport>>(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<AbsoluteInputReport> createInstance()
{
return new VMultiInstance<AbsoluteInputReport>("VMultiAbs", new AbsoluteInputReport());
}
}
public void SetPosition(Vector2 pos)

View file

@ -18,20 +18,22 @@ namespace VoiDPlugins.OutputMode
public VMultiRelativePointer(TabletReference tabletReference)
{
_instance = new VMultiInstance<RelativeInputReport>("VMultiRel", new RelativeInputReport());
var sharedStore = SharedStore.GetStore(tabletReference, STORE_KEY);
if (!sharedStore.TryAdd(INSTANCE, _instance))
_instance = sharedStore.Get<VMultiInstance<RelativeInputReport>>(INSTANCE);
_instance = sharedStore.GetOrUpdate(REL_INSTANCE, createInstance, out var updated);
_rawPointer = _instance.Pointer;
sharedStore.SetOrAdd(MODE, REL_INSTANCE);
static VMultiInstance<RelativeInputReport> createInstance()
{
return new VMultiInstance<RelativeInputReport>("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);

View file

@ -33,7 +33,9 @@ namespace VoiDPlugins.OutputMode
{
try
{
_instance = SharedStore.GetStore(tabletReference, STORE_KEY).Get<VMultiInstance>(INSTANCE);
var sharedStore = SharedStore.GetStore(tabletReference, STORE_KEY);
var mode = sharedStore.Get<int>(MODE);
_instance = sharedStore.Get<VMultiInstance>(mode);
}
catch
{

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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<DigitizerInputReport>(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<DigitizerInputReport> createInstance()
{
Instance = SharedStore.Get<VMultiInstance<DigitizerInputReport>>(INSTANCE);
RawPointer = Instance.Pointer;
return new VMultiInstance<DigitizerInputReport>(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;

View file

@ -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;
}

View file

@ -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<bool>(ERASER_STATE);
if (eraserState != isEraser)

View file

@ -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<int, object>
public class SharedStore
{
private static readonly Dictionary<TabletReference, Dictionary<string, SharedStore>> _storeMap = new(new Comparer());
private readonly Dictionary<int, object> _sharedStore = new();
public object this[int key] { get => ((IDictionary<int, object>)_sharedStore)[key]; set => ((IDictionary<int, object>)_sharedStore)[key] = value; }
public ICollection<int> Keys => ((IDictionary<int, object>)_sharedStore).Keys;
public ICollection<object> Values => ((IDictionary<int, object>)_sharedStore).Values;
public int Count => ((ICollection<KeyValuePair<int, object>>)_sharedStore).Count;
public bool IsReadOnly => ((ICollection<KeyValuePair<int, object>>)_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<T>(int key, Func<T> valueFactory, out bool updated)
{
if (_sharedStore.TryGetValue(key, out object? value) && SafeCast<T>(value) is T casted)
{
updated = false;
return casted;
}
var newValue = valueFactory();
_sharedStore[key] = newValue!;
updated = true;
return newValue;
}
public void Set<T>(int key, T value)
{
_sharedStore[key] = value!;
}
public void Add(int key, object value)
public void Add<T>(int key, T value)
{
((IDictionary<int, object>)_sharedStore).Add(key, value);
_sharedStore.Add(key, value!);
}
public bool TryAdd(int key, object value)
public void SetOrAdd<T>(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<int, object> item)
private static T? SafeCast<T>(object value)
{
((ICollection<KeyValuePair<int, object>>)_sharedStore).Add(item);
}
public void Clear()
{
((ICollection<KeyValuePair<int, object>>)_sharedStore).Clear();
}
public bool Contains(KeyValuePair<int, object> item)
{
return ((ICollection<KeyValuePair<int, object>>)_sharedStore).Contains(item);
}
public bool ContainsKey(int key)
{
return ((IDictionary<int, object>)_sharedStore).ContainsKey(key);
}
public void CopyTo(KeyValuePair<int, object>[] array, int arrayIndex)
{
((ICollection<KeyValuePair<int, object>>)_sharedStore).CopyTo(array, arrayIndex);
}
public IEnumerator<KeyValuePair<int, object>> GetEnumerator()
{
return ((IEnumerable<KeyValuePair<int, object>>)_sharedStore).GetEnumerator();
}
public bool Remove(int key)
{
return ((IDictionary<int, object>)_sharedStore).Remove(key);
}
public bool Remove(KeyValuePair<int, object> item)
{
return ((ICollection<KeyValuePair<int, object>>)_sharedStore).Remove(item);
}
public bool TryGetValue(int key, [MaybeNullWhen(false)] out object value)
{
return ((IDictionary<int, object>)_sharedStore).TryGetValue(key, out value);
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)_sharedStore).GetEnumerator();
try
{
return (T)value;
}
catch
{
return default;
}
}
private class Comparer : IEqualityComparer<TabletReference>