Skip to content

Commit

Permalink
Surpress themal mode events when switching power modes manually. (#621)
Browse files Browse the repository at this point in the history
  • Loading branch information
BartoszCichecki authored Mar 18, 2023
1 parent 63d52a7 commit d8cfaf4
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 6 deletions.
23 changes: 17 additions & 6 deletions LenovoLegionToolkit.Lib/Features/PowerModeFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,24 @@ public class PowerModeFeature : AbstractLenovoGamezoneWmiFeature<PowerModeState>
private readonly AIModeController _aiModeController;
private readonly GodModeController _godModeController;
private readonly PowerPlanController _powerPlanController;
private readonly PowerModeListener _listener;
private readonly ThermalModeListener _thermalModeListener;
private readonly PowerModeListener _powerModeListener;

public bool AllowAllPowerModesOnBattery { get; set; }

public PowerModeFeature(AIModeController aiModeController, GodModeController godModeController, PowerPlanController powerPlanController, PowerModeListener listener)
: base("SmartFanMode", 1, "IsSupportSmartFan")
public PowerModeFeature(
AIModeController aiModeController,
GodModeController godModeController,
PowerPlanController powerPlanController,
ThermalModeListener thermalModeListener,
PowerModeListener powerModeListener
) : base("SmartFanMode", 1, "IsSupportSmartFan")
{
_aiModeController = aiModeController ?? throw new ArgumentNullException(nameof(aiModeController));
_godModeController = godModeController ?? throw new ArgumentNullException(nameof(godModeController));
_powerPlanController = powerPlanController ?? throw new ArgumentNullException(nameof(powerPlanController)); ;
_listener = listener ?? throw new ArgumentNullException(nameof(listener));
_powerPlanController = powerPlanController ?? throw new ArgumentNullException(nameof(powerPlanController));
_thermalModeListener = thermalModeListener ?? throw new ArgumentNullException(nameof(thermalModeListener));
_powerModeListener = powerModeListener ?? throw new ArgumentNullException(nameof(powerModeListener));
}

public override async Task<PowerModeState[]> GetAllStatesAsync()
Expand Down Expand Up @@ -52,11 +59,15 @@ public override async Task SetStateAsync(PowerModeState state)

var mi = await Compatibility.GetMachineInformationAsync().ConfigureAwait(false);
if (mi.Properties.HasPerformanceModeSwitchingBug && currentState == PowerModeState.Quiet && state == PowerModeState.Performance)
{
_thermalModeListener.SuppressNext();
await base.SetStateAsync(PowerModeState.Balance).ConfigureAwait(false);
}

_thermalModeListener.SuppressNext();
await base.SetStateAsync(state).ConfigureAwait(false);

await _listener.NotifyAsync(state).ConfigureAwait(false);
await _powerModeListener.NotifyAsync(state).ConfigureAwait(false);

if (state == PowerModeState.GodMode)
await _godModeController.ApplyStateAsync().ConfigureAwait(false);
Expand Down
23 changes: 23 additions & 0 deletions LenovoLegionToolkit.Lib/Listeners/ThermalModeListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
using System.Management;
using System.Threading.Tasks;
using LenovoLegionToolkit.Lib.Controllers;
using LenovoLegionToolkit.Lib.Utils;

namespace LenovoLegionToolkit.Lib.Listeners;

public class ThermalModeListener : AbstractWMIListener<ThermalModeState>
{
private readonly ThreadSafeCounter _suppressCounter = new();

private readonly PowerPlanController _powerPlanController;

public ThermalModeListener(PowerPlanController powerPlanController) : base("ROOT\\WMI", "LENOVO_GAMEZONE_THERMAL_MODE_EVENT")
Expand All @@ -21,13 +24,25 @@ protected override ThermalModeState GetValue(PropertyDataCollection properties)
var value = (ThermalModeState)(object)propertyValue;

if (!Enum.IsDefined(value))
{
if (Log.Instance.IsTraceEnabled)
Log.Instance.Trace($"Unknown value received: {propertyValue}");

value = ThermalModeState.Unknown;
}

return value;
}

protected override async Task OnChangedAsync(ThermalModeState state)
{
if (!_suppressCounter.Decrement())
{
if (Log.Instance.IsTraceEnabled)
Log.Instance.Trace($"Suppressed.");
return;
}

if (state == ThermalModeState.Unknown)
return;

Expand All @@ -47,4 +62,12 @@ protected override async Task OnChangedAsync(ThermalModeState state)
break;
}
}

public void SuppressNext()
{
if (Log.Instance.IsTraceEnabled)
Log.Instance.Trace($"Suppressing next...");

_suppressCounter.Increment();
}
}
28 changes: 28 additions & 0 deletions LenovoLegionToolkit.Lib/Utils/ThreadSafeCounter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;

namespace LenovoLegionToolkit.Lib.Utils;

public class ThreadSafeCounter
{
private readonly object _lock = new();

private int _counter;

public bool Decrement()
{
lock (_lock)
{
var value = _counter < 1;
_counter = Math.Max(0, _counter - 1);
return value;
}
}

public void Increment()
{
lock (_lock)
{
_counter++;
}
}
}

0 comments on commit d8cfaf4

Please sign in to comment.