Fixed an issue where disposing was not working correctly, so using auto-profiles by application was causing the plugin to stop responding

now there is just one event loop for window changing, and instances of the dial action can register to the event
This commit is contained in:
dlprows 2023-09-24 15:01:12 -06:00
parent d89c8b1ffa
commit 5711ace990
3 changed files with 60 additions and 29 deletions

View File

@ -31,16 +31,8 @@ public class DialAction : EncoderBase
} }
} }
private PluginSettings settings; PluginSettings settings;
IntPtr _foregroundWindowChangedEvent;
Native.WinEventDelegate _delegate;
AudioHelper _audioHelper = new AudioHelper(); AudioHelper _audioHelper = new AudioHelper();
Thread _thread;
Dispatcher _dispatcher;
UIState _previousState; UIState _previousState;
public DialAction(ISDConnection connection, InitialPayload payload) : base(connection, payload) public DialAction(ISDConnection connection, InitialPayload payload) : base(connection, payload)
@ -55,19 +47,7 @@ public class DialAction : EncoderBase
settings = payload.Settings.ToObject<PluginSettings>(); settings = payload.Settings.ToObject<PluginSettings>();
} }
_thread = new Thread(() => WindowChangedEventLoop.Instance.WindowChanged += WindowChanged;
{
Logger.Instance.LogMessage(TracingLevel.DEBUG, "Registering for events");
_delegate = new Native.WinEventDelegate(WinEventProc);
_foregroundWindowChangedEvent = Native.RegisterForForegroundWindowChangedEvent(_delegate);
Logger.Instance.LogMessage(TracingLevel.DEBUG, "Starting Dispatcher");
_dispatcher = Dispatcher.CurrentDispatcher;
Dispatcher.Run();
Logger.Instance.LogMessage(TracingLevel.DEBUG, "Dispatcher Stopped");
});
_thread.SetApartmentState(ApartmentState.STA);
_thread.Start();
var session = _audioHelper.GetActiveSession(settings.FallbackBehavior); var session = _audioHelper.GetActiveSession(settings.FallbackBehavior);
_ = UpdateStateIfNeeded(session); _ = UpdateStateIfNeeded(session);
@ -76,11 +56,7 @@ public class DialAction : EncoderBase
public override void Dispose() public override void Dispose()
{ {
Logger.Instance.LogMessage(TracingLevel.DEBUG, "Disposing"); Logger.Instance.LogMessage(TracingLevel.DEBUG, "Disposing");
if (_foregroundWindowChangedEvent != IntPtr.Zero) WindowChangedEventLoop.Instance.WindowChanged -= WindowChanged;
{
Native.UnhookWinEvent(_foregroundWindowChangedEvent);
}
_dispatcher.InvokeShutdown();
} }
public override async void DialDown(DialPayload payload) public override async void DialDown(DialPayload payload)
@ -259,7 +235,7 @@ public class DialAction : EncoderBase
} }
public void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) public void WindowChanged()
{ {
try try
{ {
@ -267,7 +243,7 @@ public class DialAction : EncoderBase
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Instance.LogMessage(TracingLevel.ERROR, $"Unexpected Error in DialDown:\n {ex}"); Logger.Instance.LogMessage(TracingLevel.ERROR, $"Unexpected Error in Window Down:\n {ex}");
} }
} }
} }

View File

@ -70,6 +70,7 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UI\UIState.cs" /> <Compile Include="UI\UIState.cs" />
<Compile Include="UI\ValueWithOpacity.cs" /> <Compile Include="UI\ValueWithOpacity.cs" />
<Compile Include="WindowChangedEventLoop.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="App.config" /> <None Include="App.config" />

View File

@ -0,0 +1,54 @@
using BarRaider.SdTools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
namespace FocusVolumeControl
{
internal class WindowChangedEventLoop
{
private static readonly Lazy<WindowChangedEventLoop> _lazy = new Lazy<WindowChangedEventLoop>(() => new WindowChangedEventLoop());
public static WindowChangedEventLoop Instance => _lazy.Value;
readonly Thread _thread;
Dispatcher _dispatcher;
IntPtr _foregroundWindowChangedEvent;
Native.WinEventDelegate _delegate;
private WindowChangedEventLoop()
{
_thread = new Thread(() =>
{
Logger.Instance.LogMessage(TracingLevel.DEBUG, "Starting Window Changed Event Loop");
_delegate = new Native.WinEventDelegate(WinEventProc);
_foregroundWindowChangedEvent = Native.RegisterForForegroundWindowChangedEvent(_delegate);
_dispatcher = Dispatcher.CurrentDispatcher;
Dispatcher.Run();
Logger.Instance.LogMessage(TracingLevel.DEBUG, "Window Changed Event Loop Stopped");
});
_thread.SetApartmentState(ApartmentState.STA);
_thread.Start();
}
public event Action WindowChanged;
private void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
try
{
WindowChanged?.Invoke();
}
catch (Exception ex)
{
Logger.Instance.LogMessage(TracingLevel.ERROR, $"Unexpected Error in EventHandler:\n {ex}");
}
}
}
}