Skip to content

Commit

Permalink
Merge pull request #21 from FaithBeam/reactive-instead-of-events
Browse files Browse the repository at this point in the history
Reactive instead of events
  • Loading branch information
FaithBeam authored Sep 29, 2024
2 parents 828e04b + 8ae97f9 commit d62b937
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 103 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading;
using Serilog;
using SharpHook;
Expand All @@ -15,10 +16,10 @@ namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations;

public interface IMouseListener : IDisposable
{
event EventHandler<NewMouseHookMoveEventArgs> OnMouseMovedEventHandler;
event EventHandler<NewMouseHookEventArgs> OnMousePressedEventHandler;
event EventHandler<NewMouseHookEventArgs> OnMouseReleasedEventHandler;
event EventHandler<NewMouseWheelEventArgs> OnMouseWheelEventHandler;
IObservable<NewMouseHookMoveEventArgs> OnMouseMovedChanged { get; }
IObservable<NewMouseHookEventArgs> OnMousePressedChanged { get; }
IObservable<NewMouseHookEventArgs> OnMouseReleasedChanged { get; }
IObservable<NewMouseWheelEventArgs> OnMouseWheelChanged { get; }
void Run();
}

Expand All @@ -33,10 +34,14 @@ public class MouseListener : IMouseListener
private readonly ICurrentWindowService _currentWindowService;
private readonly ILogger _log = Log.Logger.ForContext<MouseListener>();
private Thread? _thread;
private IDisposable? _mouseMovedDisposable;
private IDisposable? _mousePressedDisposable;
private IDisposable? _mouseReleasedDisposable;
private IDisposable? _mouseWheelDisposable;
private readonly IDisposable? _mouseMovedDisposable;
private readonly IDisposable? _mousePressedDisposable;
private readonly IDisposable? _mouseReleasedDisposable;
private readonly IDisposable? _mouseWheelDisposable;
private readonly Subject<NewMouseHookEventArgs> _mousePressedSubject;
private readonly Subject<NewMouseHookEventArgs> _mouseReleasedSubject;
private readonly Subject<NewMouseHookMoveEventArgs> _mouseMovedSubject;
private readonly Subject<NewMouseWheelEventArgs> _mouseWheelSubject;

public MouseListener(
IReactiveGlobalHook hook,
Expand All @@ -47,14 +52,27 @@ ICurrentWindowService currentWindowService
_hook = hook;
_profilesService = profilesService;
_currentWindowService = currentWindowService;
_mousePressedSubject = new Subject<NewMouseHookEventArgs>();
_mouseReleasedSubject = new Subject<NewMouseHookEventArgs>();
_mouseMovedSubject = new Subject<NewMouseHookMoveEventArgs>();
_mouseWheelSubject = new Subject<NewMouseWheelEventArgs>();

SubscribeToEvents();
_mouseMovedDisposable = _hook
.MouseMoved.Sample(TimeSpan.FromMilliseconds(100))
.Subscribe(ConvertMouseMovedEvent);
_mousePressedDisposable = _hook.MousePressed.Subscribe(ConvertMousePressedEvent);
_mouseReleasedDisposable = _hook.MouseReleased.Subscribe(ConvertMouseReleasedEvent);
_mouseWheelDisposable = _hook.MouseWheel.Subscribe(ConvertMouseWheelEvent);
}

public event EventHandler<NewMouseHookEventArgs>? OnMousePressedEventHandler;
public event EventHandler<NewMouseHookMoveEventArgs>? OnMouseMovedEventHandler;
public event EventHandler<NewMouseHookEventArgs>? OnMouseReleasedEventHandler;
public event EventHandler<NewMouseWheelEventArgs>? OnMouseWheelEventHandler;
public IObservable<NewMouseHookEventArgs> OnMousePressedChanged =>
_mousePressedSubject.AsObservable();
public IObservable<NewMouseHookEventArgs> OnMouseReleasedChanged =>
_mouseReleasedSubject.AsObservable();
public IObservable<NewMouseHookMoveEventArgs> OnMouseMovedChanged =>
_mouseMovedSubject.AsObservable();
public IObservable<NewMouseWheelEventArgs> OnMouseWheelChanged =>
_mouseWheelSubject.AsObservable();

public void Run()
{
Expand All @@ -66,24 +84,6 @@ public void Run()
_thread.Start();
}

private void OnMouseReleased(NewMouseHookEventArgs args)
{
var handler = OnMouseReleasedEventHandler;
handler?.Invoke(this, args);
}

private void OnMousePressed(NewMouseHookEventArgs args)
{
var handler = OnMousePressedEventHandler;
handler?.Invoke(this, args);
}

private void OnMouseWheel(NewMouseWheelEventArgs args)
{
var handler = OnMouseWheelEventHandler;
handler?.Invoke(this, args);
}

/// <summary>
/// Whether to suppress the original mouse event from propagating
/// </summary>
Expand Down Expand Up @@ -132,16 +132,6 @@ private bool ShouldSuppressEvent(NewMouseHookEventArgs args) =>
_ => throw new ArgumentOutOfRangeException(),
};

private void SubscribeToEvents()
{
_mouseMovedDisposable = _hook
.MouseMoved.Sample(TimeSpan.FromMilliseconds(100))
.Subscribe(ConvertMouseMovedEvent);
_mousePressedDisposable = _hook.MousePressed.Subscribe(ConvertMousePressedEvent);
_mouseReleasedDisposable = _hook.MouseReleased.Subscribe(ConvertMouseReleasedEvent);
_mouseWheelDisposable = _hook.MouseWheel.Subscribe(ConvertMouseWheelEvent);
}

private void ConvertMouseWheelEvent(MouseWheelHookEventArgs e)
{
if (e is null)
Expand All @@ -151,18 +141,26 @@ private void ConvertMouseWheelEvent(MouseWheelHookEventArgs e)
switch (e.Data.Direction)
{
case MouseWheelScrollDirection.Vertical when e.Data.Rotation > 0:
OnMouseWheel(new NewMouseWheelEventArgs(WheelScrollDirection.VerticalUp));
_mouseWheelSubject.OnNext(
new NewMouseWheelEventArgs(WheelScrollDirection.VerticalUp)
);
break;
case MouseWheelScrollDirection.Vertical when e.Data.Rotation < 0:
OnMouseWheel(new NewMouseWheelEventArgs(WheelScrollDirection.VerticalDown));
_mouseWheelSubject.OnNext(
new NewMouseWheelEventArgs(WheelScrollDirection.VerticalDown)
);
break;
case MouseWheelScrollDirection.Vertical:
throw new ArgumentOutOfRangeException($"{e.Data.Direction}\t{e.Data.Rotation}");
case MouseWheelScrollDirection.Horizontal when e.Data.Rotation > 0:
OnMouseWheel(new NewMouseWheelEventArgs(WheelScrollDirection.HorizontalRight));
_mouseWheelSubject.OnNext(
new NewMouseWheelEventArgs(WheelScrollDirection.HorizontalRight)
);
break;
case MouseWheelScrollDirection.Horizontal when e.Data.Rotation < 0:
OnMouseWheel(new NewMouseWheelEventArgs(WheelScrollDirection.HorizontalLeft));
_mouseWheelSubject.OnNext(
new NewMouseWheelEventArgs(WheelScrollDirection.HorizontalLeft)
);
break;
case MouseWheelScrollDirection.Horizontal:
throw new ArgumentOutOfRangeException($"{e.Data.Direction}\t{e.Data.Rotation}");
Expand Down Expand Up @@ -194,7 +192,7 @@ private void ConvertMouseReleasedEvent(MouseHookEventArgs e)
{
_log.Information("Not suppressing {Button}: Release", e.Data.Button);
}
OnMouseReleased(args);
_mouseReleasedSubject.OnNext(args);
}

private void ConvertMousePressedEvent(MouseHookEventArgs e)
Expand All @@ -221,7 +219,7 @@ private void ConvertMousePressedEvent(MouseHookEventArgs e)
{
_log.Information("Not suppressing {Button}: Press", e.Data.Button);
}
OnMousePressed(args);
_mousePressedSubject.OnNext(args);
}

private void ConvertMouseMovedEvent(MouseHookEventArgs e)
Expand All @@ -230,27 +228,15 @@ private void ConvertMouseMovedEvent(MouseHookEventArgs e)
{
return;
}
var args = new NewMouseHookMoveEventArgs(e.Data.X, e.Data.Y);
OnMouseMoved(args);
_mouseMovedSubject.OnNext(new NewMouseHookMoveEventArgs(e.Data.X, e.Data.Y));
}

private void OnMouseMoved(NewMouseHookMoveEventArgs args)
{
var handler = OnMouseMovedEventHandler;
handler?.Invoke(this, args);
}

private void UnsubscribeFromEvents()
public void Dispose()
{
_mouseMovedDisposable?.Dispose();
_mousePressedDisposable?.Dispose();
_mouseReleasedDisposable?.Dispose();
_mouseWheelDisposable?.Dispose();
}

public void Dispose()
{
UnsubscribeFromEvents();

_hook.Dispose();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,39 +25,27 @@ IRightClick rightClick
) : IDisposable
{
private readonly ILogger _log = Log.Logger.ForContext<KeyboardSimulatorWorker>();
private IDisposable? _onMousePressedDisposable;
private IDisposable? _onMouseReleasedDisposable;
private IDisposable? _onMouseWheelDisposable;

public void Run()
{
SubscribeToEvents();
_onMousePressedDisposable = mouseListener.OnMousePressedChanged.Subscribe(OnMousePressed);
_onMouseReleasedDisposable = mouseListener.OnMouseReleasedChanged.Subscribe(
OnMouseReleased
);
_onMouseWheelDisposable = mouseListener.OnMouseWheelChanged.Subscribe(OnMouseWheel);
}

public void Dispose()
{
UnsubscribeFromEvents();
_onMousePressedDisposable?.Dispose();
_onMouseReleasedDisposable?.Dispose();
_onMouseWheelDisposable?.Dispose();
}

private void SubscribeToEvents()
{
// mouseListener.OnMouseMovedEventHandler += OnMouseMoved;
mouseListener.OnMousePressedEventHandler += OnMousePressed;
mouseListener.OnMouseReleasedEventHandler += OnMouseReleased;
mouseListener.OnMouseWheelEventHandler += OnMouseWheel;
}

// private void OnMouseMoved(object? sender, NewMouseHookMoveEventArgs e)
// {
// _log.Information("{X}:{Y}", e.X, e.Y);
// }

private void UnsubscribeFromEvents()
{
// mouseListener.OnMouseMovedEventHandler -= OnMouseMoved;
mouseListener.OnMousePressedEventHandler -= OnMousePressed;
mouseListener.OnMouseReleasedEventHandler -= OnMouseReleased;
mouseListener.OnMouseWheelEventHandler -= OnMouseWheel;
}

private void OnMousePressed(object? sender, NewMouseHookEventArgs e)
private void OnMousePressed(NewMouseHookEventArgs e)
{
foreach (var p in profilesService.Profiles)
{
Expand All @@ -72,7 +60,7 @@ private void OnMousePressed(object? sender, NewMouseHookEventArgs e)
}
}

private void OnMouseReleased(object? sender, NewMouseHookEventArgs e)
private void OnMouseReleased(NewMouseHookEventArgs e)
{
foreach (var p in profilesService.Profiles)
{
Expand Down Expand Up @@ -162,5 +150,5 @@ MouseButtonState state
}
}

private void OnMouseWheel(object? sender, NewMouseWheelEventArgs e) { }
private void OnMouseWheel(NewMouseWheelEventArgs e) { }
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@ namespace YMouseButtonControl.Core.ViewModels.LayerViewModel;

public interface ILayerViewModel;

public class LayerViewModel : ViewModelBase, ILayerViewModel
public class LayerViewModel : ViewModelBase, ILayerViewModel, IDisposable
{
private IProfilesService _profilesService;
private readonly IThemeService _themeService;
private readonly ISettingsService _settingsService;
private readonly IMouseListener _mouseListener;
private readonly IDisposable _onMousePressed;
private readonly IDisposable _onMouseReleased;
private readonly IDisposable _onMouseWheel;

private int _mb1Index;
private int _mb2Index;
Expand Down Expand Up @@ -183,9 +186,10 @@ IShowSimulatedKeystrokesDialogService showSimulatedKeystrokesDialogService
.DistinctUntilChanged()
.Subscribe(OnSelectedCurrentProfileChanged);
_mouseListener = mouseListener;
_mouseListener.OnMousePressedEventHandler += OnMouseClicked;
_mouseListener.OnMouseReleasedEventHandler += OnMouseReleased;
_mouseListener.OnMouseWheelEventHandler += OnWheelScroll;
_onMousePressed = _mouseListener.OnMousePressedChanged.Subscribe(OnMouseClicked);
_onMouseReleased = _mouseListener.OnMouseReleasedChanged.Subscribe(OnMouseReleased);
_onMouseWheel = _mouseListener.OnMouseWheelChanged.Subscribe(OnWheelScroll);

_wheelUpTimer.Elapsed += delegate
{
WheelUpBackgroundColor = themeService.CurBackground;
Expand Down Expand Up @@ -862,7 +866,7 @@ private void OnSelectedCurrentProfileChanged(ProfileVm newProfile)
MwrIndex = newProfile.MouseWheelRight.Index;
}

private void OnWheelScroll(object? sender, NewMouseWheelEventArgs e)
private void OnWheelScroll(NewMouseWheelEventArgs e)
{
switch (e.Direction)
{
Expand Down Expand Up @@ -903,7 +907,7 @@ private void OnWheelScroll(object? sender, NewMouseWheelEventArgs e)
}
}

private void OnMouseReleased(object? sender, NewMouseHookEventArgs e)
private void OnMouseReleased(NewMouseHookEventArgs e)
{
switch (e.Button)
{
Expand Down Expand Up @@ -935,7 +939,7 @@ private void OnMouseReleased(object? sender, NewMouseHookEventArgs e)
}
}

private void OnMouseClicked(object? sender, NewMouseHookEventArgs e)
private void OnMouseClicked(NewMouseHookEventArgs e)
{
switch (e.Button)
{
Expand Down Expand Up @@ -1001,4 +1005,25 @@ private enum ButtonMappings
SimulatedKeystrokes,
RightClick,
}

public void Dispose()
{
_onMousePressed?.Dispose();
_onMouseReleased.Dispose();
_onMouseWheel.Dispose();
_mouseListener.Dispose();
_wheelUpTimer.Dispose();
_wheelDownTimer.Dispose();
_wheelLeftTimer.Dispose();
_wheelRightTimer.Dispose();
MouseButton1ComboSettingCommand.Dispose();
MouseButton2ComboSettingCommand.Dispose();
MouseButton3ComboSettingCommand.Dispose();
MouseButton4ComboSettingCommand.Dispose();
MouseButton5ComboSettingCommand.Dispose();
MouseWheelUpComboSettingCommand.Dispose();
MouseWheelDownComboSettingCommand.Dispose();
MouseWheelLeftComboSettingCommand.Dispose();
MouseWheelRightComboSettingCommand.Dispose();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace YMouseButtonControl.Core.ViewModels.LayerViewModel;

public class SimulatedKeystrokesDialogViewModel : DialogBase
public class SimulatedKeystrokesDialogViewModel : DialogBase, IDisposable
{
private static readonly Dictionary<string, string> CombinedKeyDict = ModifierKeys
.Concat(StandardKeys)
Expand Down Expand Up @@ -48,8 +48,8 @@ public SimulatedKeystrokesDialogViewModel(
_title = $"SimulatedKeystrokes - {buttonName}";
_mouseListener = mouseListener;
currentMapping ??= new SimulatedKeystrokeVm();
_mouseListener.OnMouseMovedEventHandler += MouseListenerOnOnMouseMovedEventHandler;
_description = currentMapping?.PriorityDescription ?? string.Empty;
_mouseListener.OnMouseMovedChanged.Subscribe(MouseListenerOnOnMouseMovedEventHandler);
_description = currentMapping.PriorityDescription ?? string.Empty;
_customKeys = currentMapping?.Keys ?? string.Empty;
SimulatedKeystrokesType =
currentMapping?.SimulatedKeystrokeType ?? new MouseButtonPressedActionTypeVm();
Expand Down Expand Up @@ -90,10 +90,7 @@ public SimulatedKeystrokesDialogViewModel(
});
}

private void MouseListenerOnOnMouseMovedEventHandler(
object? sender,
NewMouseHookMoveEventArgs e
)
private void MouseListenerOnOnMouseMovedEventHandler(NewMouseHookMoveEventArgs e)
{
X = e.X;
Y = e.Y;
Expand Down Expand Up @@ -332,4 +329,11 @@ public BaseButtonMappingVm? CurrentMapping

private static IEnumerable<BaseSimulatedKeystrokeTypeVm> GetSimulatedKeystrokesTypes() =>
SimulatedKeystrokeTypesList.Select(x => x());

public void Dispose()
{
_mouseListener.Dispose();
OkCommand.Dispose();
SplitButtonCommand.Dispose();
}
}
Loading

0 comments on commit d62b937

Please sign in to comment.