-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #17 from diogotr7/feature/chroma-reader
Replace old RazerSdkWrapper with RazerSdkReader
- Loading branch information
Showing
6 changed files
with
120 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
159 changes: 87 additions & 72 deletions
159
src/Artemis.Plugins.LayerBrushes.Chroma/Services/ChromaService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,129 +1,144 @@ | ||
using Artemis.Core.Services; | ||
using RazerSdkWrapper; | ||
using RazerSdkWrapper.Data; | ||
using Serilog; | ||
using SkiaSharp; | ||
using System; | ||
using System.Collections.Concurrent; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Artemis.Core; | ||
using RazerSdkReader; | ||
using RazerSdkReader.Structures; | ||
|
||
namespace Artemis.Plugins.LayerBrushes.Chroma.Services; | ||
|
||
public class ChromaService : IPluginService, IDisposable | ||
{ | ||
private readonly ILogger _logger; | ||
private readonly RzSdkManager _manager; | ||
private readonly ChromaReader _reader; | ||
private readonly Profiler _profiler; | ||
private readonly Dictionary<RzDeviceType, string> _enumNames; | ||
|
||
public event EventHandler<RzDeviceType>? MatrixUpdated; | ||
public event EventHandler? AppListUpdated; | ||
|
||
public string? CurrentApp { get; private set; } = string.Empty; | ||
public int? CurrentAppId { get; private set; } = null; | ||
public string? CurrentApp { get; private set; } = null; | ||
public List<string> Apps { get; } = new(); | ||
public List<int> Pids { get; } = new(); | ||
public ConcurrentDictionary<RzDeviceType, SKColor[,]> Matrices { get; } = new(); | ||
|
||
public ChromaService(ILogger logger) | ||
public ChromaService(ILogger logger, Plugin plugin) | ||
{ | ||
_logger = logger; | ||
|
||
_logger.Verbose("Starting RzSDKManager..."); | ||
_manager = new RzSdkManager() | ||
{ | ||
AppListEnabled = true, | ||
MousepadEnabled = true, | ||
MouseEnabled = true, | ||
KeypadEnabled = true, | ||
KeyboardEnabled = true, | ||
HeadsetEnabled = true, | ||
ChromaLinkEnabled = true | ||
}; | ||
_logger.Verbose("Started RzSdkManager successfully"); | ||
_manager.DataUpdated += OnDataUpdated; | ||
_logger.Verbose("Starting RazerSdkReader..."); | ||
_profiler = plugin.GetProfiler("Chroma Service"); | ||
|
||
_enumNames = Enum.GetValues<RzDeviceType>().ToDictionary(t => t, t => $"Update {Enum.GetName(typeof(RzDeviceType), t) ?? throw new Exception()}"); | ||
|
||
_reader = new(); | ||
_reader.KeyboardUpdated += RazerEmulatorReaderOnKeyboardUpdated; | ||
_reader.MouseUpdated += RazerEmulatorReaderOnMouseUpdated; | ||
_reader.MousepadUpdated += RazerEmulatorReaderOnMousepadUpdated; | ||
_reader.KeypadUpdated += RazerEmulatorReaderOnKeypadUpdated; | ||
_reader.HeadsetUpdated += RazerEmulatorReaderOnHeadsetUpdated; | ||
_reader.ChromaLinkUpdated += RazerEmulatorReaderOnChromaLinkUpdated; | ||
_reader.AppDataUpdated += RazerEmulatorReaderOnAppDataUpdated; | ||
_reader.Start(); | ||
_logger.Verbose("Started RazerSdkReader successfully"); | ||
|
||
UpdateAppList(true); | ||
} | ||
|
||
internal void UpdateAppList(bool forced = false) | ||
private void RazerEmulatorReaderOnAppDataUpdated(object? sender, in ChromaAppData e) | ||
{ | ||
if (CurrentApp == null && !forced) | ||
return; | ||
UpdateAppListData(in e); | ||
} | ||
|
||
RzAppListDataProvider applist = _manager.GetDataProvider<RzAppListDataProvider>(); | ||
applist.Update(); | ||
UpdateAppListData(applist); | ||
private void RazerEmulatorReaderOnChromaLinkUpdated(object? sender, in ChromaLink e) | ||
{ | ||
UpdateMatrix(RzDeviceType.ChromaLink,in e); | ||
} | ||
|
||
private void OnDataUpdated(object? sender, EventArgs e) | ||
private void RazerEmulatorReaderOnHeadsetUpdated(object? sender, in ChromaHeadset e) | ||
{ | ||
if (sender is not AbstractDataProvider provider) | ||
return; | ||
UpdateMatrix(RzDeviceType.Headset,in e); | ||
} | ||
|
||
provider.Update(); | ||
private void RazerEmulatorReaderOnKeypadUpdated(object? sender, in ChromaKeypad e) | ||
{ | ||
UpdateMatrix(RzDeviceType.Keypad,in e); | ||
} | ||
|
||
if (provider is RzAppListDataProvider app) | ||
{ | ||
UpdateAppListData(app); | ||
_logger.Verbose("Updated AppList: CurrentApp: {currentApp} | Apps: {apps} | Pids: {pids}", CurrentApp ?? "None", Apps, Pids); | ||
} | ||
else if (provider is AbstractColorDataProvider colorProvider) | ||
{ | ||
UpdateMatrix(colorProvider); | ||
_logger.Verbose("Updated {provider}. Zone zero: {color}", _deviceTypeDict[colorProvider.GetType()], colorProvider.GetZoneColor(0)); | ||
} | ||
private void RazerEmulatorReaderOnMousepadUpdated(object? sender, in ChromaMousepad e) | ||
{ | ||
UpdateMatrix(RzDeviceType.Mousepad,in e); | ||
} | ||
|
||
private void UpdateMatrix(AbstractColorDataProvider colorProvider) | ||
private void RazerEmulatorReaderOnMouseUpdated(object? sender, in ChromaMouse e) | ||
{ | ||
RzDeviceType matrixDeviceType = _deviceTypeDict[colorProvider.GetType()]; | ||
GridSize grid = colorProvider.Grids[0]; | ||
UpdateMatrix(RzDeviceType.Mouse,in e); | ||
} | ||
|
||
SKColor[,] matrix = Matrices.GetOrAdd(matrixDeviceType, static (id,g) => new SKColor[g.Height, g.Width], grid); | ||
private void RazerEmulatorReaderOnKeyboardUpdated(object? sender, in ChromaKeyboard e) | ||
{ | ||
UpdateMatrix(RzDeviceType.Keyboard, e); | ||
} | ||
|
||
for (int i = 0; i < grid.Height; i++) | ||
internal void UpdateAppList(bool forced = false) | ||
{ | ||
//TODO: Is this needed anymore? | ||
return; | ||
} | ||
|
||
private void UpdateMatrix<T>(RzDeviceType deviceType, in T data) where T : unmanaged, IColorProvider | ||
{ | ||
var profilerName = _enumNames[deviceType]; | ||
|
||
_profiler.StartMeasurement(profilerName); | ||
var matrix = Matrices.GetOrAdd(deviceType, static (id, t) => new SKColor[t.Height, t.Width], data); | ||
|
||
for (var i = 0; i < data.Height; i++) | ||
{ | ||
for (int j = 0; j < grid.Width; j++) | ||
for (var j = 0; j < data.Width; j++) | ||
{ | ||
(byte r, byte g, byte b) = colorProvider.GetZoneColor((int)(i * grid.Width + j)); | ||
matrix[i, j] = new SKColor(r, g, b); | ||
// ReSharper disable once PossiblyImpureMethodCallOnReadonlyVariable | ||
var clr = data.GetColor(i * data.Width + j); | ||
matrix[i, j] = new SKColor(clr.R, clr.G, clr.B); | ||
} | ||
} | ||
|
||
MatrixUpdated?.Invoke(this, matrixDeviceType); | ||
MatrixUpdated?.Invoke(this, deviceType); | ||
_profiler.StopMeasurement(profilerName); | ||
} | ||
|
||
private void UpdateAppListData(RzAppListDataProvider app) | ||
private void UpdateAppListData(in ChromaAppData app) | ||
{ | ||
Apps.Clear(); | ||
Pids.Clear(); | ||
CurrentApp = app.CurrentAppExecutable; | ||
for (int i = 0; i < app.AppCount; i++) | ||
CurrentAppId = app.CurrentAppId == 0 ? null : (int)app.CurrentAppId; | ||
CurrentApp = null; | ||
for (var i = 0; i < app.AppCount; i++) | ||
{ | ||
Apps.Add(app.GetExecutableName(i)); | ||
Pids.Add(app.GetPid(i)); | ||
Apps.Add(app.AppInfo[i].AppName); | ||
Pids.Add((int)app.AppInfo[i].AppId); | ||
|
||
if (app.AppInfo[i].AppId == app.CurrentAppId) | ||
CurrentApp = app.AppInfo[i].AppName; | ||
} | ||
|
||
AppListUpdated?.Invoke(this, EventArgs.Empty); | ||
_logger.Verbose("Updated Chroma app list"); | ||
} | ||
|
||
private readonly Dictionary<Type, RzDeviceType> _deviceTypeDict = new() | ||
{ | ||
[typeof(RzMousepadDataProvider)] = RzDeviceType.Mousepad, | ||
[typeof(RzMouseDataProvider)] = RzDeviceType.Mouse, | ||
[typeof(RzKeypadDataProvider)] = RzDeviceType.Keypad, | ||
[typeof(RzKeyboardDataProvider)] = RzDeviceType.Keyboard, | ||
[typeof(RzHeadsetDataProvider)] = RzDeviceType.Headset, | ||
[typeof(RzChromaLinkDataProvider)] = RzDeviceType.ChromaLink | ||
}; | ||
|
||
#region IDisposable | ||
public void Dispose() | ||
{ | ||
_manager.DataUpdated -= OnDataUpdated; | ||
//TODO: disposing this throws this: | ||
//System.ApplicationException: Object synchronization method was called from an unsynchronized block of code. | ||
//idk what to do about it | ||
//_manager?.Dispose(); | ||
GC.SuppressFinalize(this); | ||
_reader.KeyboardUpdated -= RazerEmulatorReaderOnKeyboardUpdated; | ||
_reader.MouseUpdated -= RazerEmulatorReaderOnMouseUpdated; | ||
_reader.MousepadUpdated -= RazerEmulatorReaderOnMousepadUpdated; | ||
_reader.KeypadUpdated -= RazerEmulatorReaderOnKeypadUpdated; | ||
_reader.HeadsetUpdated -= RazerEmulatorReaderOnHeadsetUpdated; | ||
_reader.ChromaLinkUpdated -= RazerEmulatorReaderOnChromaLinkUpdated; | ||
_reader.AppDataUpdated -= RazerEmulatorReaderOnAppDataUpdated; | ||
_reader.Dispose(); | ||
} | ||
#endregion | ||
} | ||
} |