diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj
index a97a823b3..13907072e 100644
--- a/Artemis/Artemis/Artemis.csproj
+++ b/Artemis/Artemis/Artemis.csproj
@@ -148,6 +148,10 @@
..\packages\CUE.NET.1.0.3\lib\net45\CUE.NET.dll
True
+
+ ..\packages\DynamicExpresso.Core.1.3.1.0\lib\net40\DynamicExpresso.Core.dll
+ True
+
..\packages\gong-wpf-dragdrop.0.1.4.3\lib\net40\GongSolutions.Wpf.DragDrop.dll
True
@@ -205,10 +209,6 @@
-
- ..\packages\System.Linq.Dynamic.1.0.6\lib\net40\System.Linq.Dynamic.dll
- True
-
diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadsets.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadsets.cs
index 8090d1dcb..fdedd3c49 100644
--- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadsets.cs
+++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadsets.cs
@@ -46,18 +46,20 @@ namespace Artemis.DeviceProviders.Corsair
var visual = new DrawingVisual();
using (var c = visual.RenderOpen())
c.DrawRectangle(brush, null, rect);
- var img = ImageUtilities.DrawinVisualToBitmap(visual, rect);
- var ledIndex = 0;
- // Color each LED according to one of the pixels
- foreach (var corsairLed in CueSDK.HeadsetSDK.Leds)
+ using (var img = ImageUtilities.DrawinVisualToBitmap(visual, rect))
{
- corsairLed.Color = ledIndex == 0
- ? img.GetPixel(0, 0)
- : img.GetPixel((ledIndex + 1)*20 - 1, (ledIndex + 1)*20 - 1);
- ledIndex++;
- }
+ var ledIndex = 0;
+ // Color each LED according to one of the pixels
+ foreach (var corsairLed in CueSDK.HeadsetSDK.Leds)
+ {
+ corsairLed.Color = ledIndex == 0
+ ? img.GetPixel(0, 0)
+ : img.GetPixel((ledIndex + 1)*20 - 1, (ledIndex + 1)*20 - 1);
+ ledIndex++;
+ }
+ }
// Flush is required for headset to work reliably on CUE2 for some reason
CueSDK.HeadsetSDK.Update(true);
}
diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs
index 9d4763851..3e08f941c 100644
--- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs
+++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs
@@ -46,18 +46,19 @@ namespace Artemis.DeviceProviders.Corsair
var visual = new DrawingVisual();
using (var c = visual.RenderOpen())
c.DrawRectangle(brush, null, rect);
- var img = ImageUtilities.DrawinVisualToBitmap(visual, rect);
- var ledIndex = 0;
- // Color each LED according to one of the pixels
- foreach (var corsairLed in CueSDK.MouseSDK.Leds)
+ using (var img = ImageUtilities.DrawinVisualToBitmap(visual, rect))
{
- corsairLed.Color = ledIndex == 0
- ? img.GetPixel(0, 0)
- : img.GetPixel((ledIndex + 1)*20 - 1, (ledIndex + 1)*20 - 1);
- ledIndex++;
+ var ledIndex = 0;
+ // Color each LED according to one of the pixels
+ foreach (var corsairLed in CueSDK.MouseSDK.Leds)
+ {
+ corsairLed.Color = ledIndex == 0
+ ? img.GetPixel(0, 0)
+ : img.GetPixel((ledIndex + 1)*20 - 1, (ledIndex + 1)*20 - 1);
+ ledIndex++;
+ }
}
-
CueSDK.MouseSDK.Update();
}
diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairRGB.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairRGB.cs
index 9308d6d86..87ead0241 100644
--- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairRGB.cs
+++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairRGB.cs
@@ -1,5 +1,4 @@
using System.Drawing;
-using System.Threading;
using System.Windows;
using Artemis.Properties;
using Artemis.Utilities;
@@ -14,7 +13,6 @@ namespace Artemis.DeviceProviders.Corsair
{
public class CorsairRGB : KeyboardProvider
{
- public ILogger Logger { get; set; }
private CorsairKeyboard _keyboard;
private ImageBrush _keyboardBrush;
@@ -28,19 +26,11 @@ namespace Artemis.DeviceProviders.Corsair
"If needed, you can select a different keyboard in Artemis under settings.";
}
+ public ILogger Logger { get; set; }
+
public override bool CanEnable()
{
- // This will skip the check-loop if the SDK is initialized
- if (CueSDK.IsInitialized)
- return CueSDK.IsSDKAvailable(CorsairDeviceType.Keyboard);
-
- for (var tries = 0; tries < 9; tries++)
- {
- if (CueSDK.IsSDKAvailable(CorsairDeviceType.Keyboard))
- return true;
- Thread.Sleep(2000);
- }
- return false;
+ return CueSDK.IsSDKAvailable(CorsairDeviceType.Keyboard);
}
///
diff --git a/Artemis/Artemis/DeviceProviders/DeviceProvider.cs b/Artemis/Artemis/DeviceProviders/DeviceProvider.cs
index f86ee2e64..c244eb73a 100644
--- a/Artemis/Artemis/DeviceProviders/DeviceProvider.cs
+++ b/Artemis/Artemis/DeviceProviders/DeviceProvider.cs
@@ -1,4 +1,5 @@
-using System.Windows.Media;
+using System.Threading.Tasks;
+using System.Windows.Media;
namespace Artemis.DeviceProviders
{
@@ -29,6 +30,15 @@ namespace Artemis.DeviceProviders
/// Disables the device
///
public abstract void Disable();
+
+ ///
+ /// Tries to enable the device and updates CanUse accordingly asynchronously
+ ///
+ ///
+ public Task TryEnableAsync()
+ {
+ return Task.Run(() => TryEnable());
+ }
}
public enum DeviceType
diff --git a/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs b/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs
index 54a157b60..ab0984904 100644
--- a/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs
+++ b/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs
@@ -1,6 +1,9 @@
using System;
using System.Drawing;
+using System.Threading;
+using System.Threading.Tasks;
using System.Windows;
+using MahApps.Metro.Controls.Dialogs;
using Brush = System.Windows.Media.Brush;
using Size = System.Windows.Size;
@@ -18,7 +21,6 @@ namespace Artemis.DeviceProviders
public int Height { get; set; }
public int Width { get; set; }
public string CantEnableText { get; set; }
-
public PreviewSettings PreviewSettings { get; set; }
public abstract bool CanEnable();
@@ -39,6 +41,52 @@ namespace Artemis.DeviceProviders
public Rect KeyboardRectangle(int scale) => new Rect(new Size(Width*scale, Height*scale));
+ ///
+ /// Runs CanEnable asynchronously multiple times until successful, cancelled or max tries reached
+ ///
+ ///
+ ///
+ public Task CanEnableAsync(ProgressDialogController dialog)
+ {
+ return Task.Run(() =>
+ {
+ for (var tries = 1; tries <= 10; tries++)
+ {
+ // Dialog interaction
+ if (dialog != null)
+ {
+ // Stop if cancelled by user
+ if (dialog.IsCanceled)
+ {
+ dialog.SetIndeterminate();
+ return false;
+ }
+ // Updated progress to indicate how much tries are left
+ dialog.SetProgress(0.1*tries);
+ }
+
+ if (CanEnable())
+ {
+ dialog?.SetIndeterminate();
+ return true;
+ }
+ Thread.Sleep(2000);
+ }
+ dialog?.SetIndeterminate();
+ return false;
+ });
+ }
+
+ ///
+ /// Runs CanEnable asynchronously
+ ///
+ ///
+ ///
+ public Task EnableAsync(ProgressDialogController dialog)
+ {
+ return Task.Run(() => Enable());
+ }
+
public override void UpdateDevice(Brush brush)
{
throw new NotImplementedException("KeyboardProvider doesn't implement UpdateDevice, use DrawBitmap instead.");
@@ -46,7 +94,8 @@ namespace Artemis.DeviceProviders
public override bool TryEnable()
{
- throw new NotImplementedException("KeyboardProvider doesn't implement TryEnable, use CanEnable instead.");
+ throw new NotImplementedException(
+ "KeyboardProvider doesn't implement TryEnable, use CanEnableAsync instead.");
}
}
diff --git a/Artemis/Artemis/Managers/DeviceManager.cs b/Artemis/Artemis/Managers/DeviceManager.cs
index 88f9637b6..b3eba9ba9 100644
--- a/Artemis/Artemis/Managers/DeviceManager.cs
+++ b/Artemis/Artemis/Managers/DeviceManager.cs
@@ -1,11 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
using Artemis.DeviceProviders;
using Artemis.Events;
using Artemis.Services;
using Artemis.Settings;
using Caliburn.Micro;
+using MahApps.Metro.Controls.Dialogs;
using Ninject;
using Ninject.Extensions.Logging;
@@ -64,8 +67,14 @@ namespace Artemis.Managers
/// Enables the given keyboard
///
///
- public void EnableKeyboard(KeyboardProvider keyboardProvider)
+ public async void EnableKeyboard(KeyboardProvider keyboardProvider)
{
+ if (ChangingKeyboard)
+ return;
+
+ // Store the old keyboard so it can be used in the event we're raising later
+ var oldKeyboard = ActiveKeyboard;
+
lock (this)
{
ChangingKeyboard = true;
@@ -79,9 +88,6 @@ namespace Artemis.Managers
return;
}
- // Store the old keyboard so it can be used in the event we're raising later
- var oldKeyboard = ActiveKeyboard;
-
var wasNull = false;
if (ActiveKeyboard == null)
{
@@ -89,43 +95,62 @@ namespace Artemis.Managers
ActiveKeyboard = keyboardProvider;
}
- _logger.Debug("Enabling keyboard: {0}", keyboardProvider.Name);
-
if (!wasNull)
ReleaseActiveKeyboard();
-
- // Disable everything if there's no active keyboard found
- if (!keyboardProvider.CanEnable())
- {
- DialogService.ShowErrorMessageBox(keyboardProvider.CantEnableText);
- ActiveKeyboard = null;
- General.Default.LastKeyboard = null;
- General.Default.Save();
- _logger.Warn("Failed enabling keyboard: {0}", keyboardProvider.Name);
- ChangingKeyboard = false;
- return;
- }
-
- ActiveKeyboard = keyboardProvider;
- ActiveKeyboard.Enable();
-
- General.Default.LastKeyboard = ActiveKeyboard.Name;
- General.Default.Save();
-
- EnableUsableDevices();
-
- ChangingKeyboard = false;
- _events.PublishOnUIThread(new ActiveKeyboardChanged(oldKeyboard, ActiveKeyboard));
- _logger.Debug("Enabled keyboard: {0}", keyboardProvider.Name);
}
+
+ _logger.Debug("Enabling keyboard: {0}", keyboardProvider.Name);
+
+ // Create a dialog to let the user know Artemis hasn't frozen
+ ProgressDialogController dialog = null;
+ if (DialogService.GetActiveWindow() != null)
+ {
+ dialog = await DialogService.ShowProgressDialog("Enabling keyboard",
+ $"Checking if keyboard '{keyboardProvider.Name}' can be enabled...", true);
+
+ // May seem a bit cheesy, but it's tidier to have the animation finish
+ await Task.Delay(500);
+ }
+ dialog?.SetIndeterminate();
+
+ var canEnable = await keyboardProvider.CanEnableAsync(dialog);
+ if (!canEnable)
+ {
+ if (dialog != null)
+ await dialog.CloseAsync();
+
+ DialogService.ShowErrorMessageBox(keyboardProvider.CantEnableText);
+ ActiveKeyboard = null;
+ General.Default.LastKeyboard = null;
+ General.Default.Save();
+ _logger.Warn("Failed enabling keyboard: {0}", keyboardProvider.Name);
+ ChangingKeyboard = false;
+ return;
+ }
+
+ dialog?.SetMessage($"Enabling keyboard: {keyboardProvider.Name}...");
+ ActiveKeyboard = keyboardProvider;
+ await ActiveKeyboard.EnableAsync(dialog);
+
+ General.Default.LastKeyboard = ActiveKeyboard.Name;
+ General.Default.Save();
+
+ EnableUsableDevices();
+ _events.PublishOnUIThread(new ActiveKeyboardChanged(oldKeyboard, ActiveKeyboard));
+ _logger.Debug("Enabled keyboard: {0}", keyboardProvider.Name);
+
+ if (dialog != null)
+ await dialog.CloseAsync();
+
+ ChangingKeyboard = false;
}
private void EnableUsableDevices()
{
foreach (var mouseProvider in MiceProviders)
- mouseProvider.TryEnable();
+ mouseProvider.TryEnableAsync();
foreach (var headsetProvider in HeadsetProviders)
- headsetProvider.TryEnable();
+ headsetProvider.TryEnableAsync();
}
///
diff --git a/Artemis/Artemis/Managers/EffectManager.cs b/Artemis/Artemis/Managers/EffectManager.cs
index a7143e039..0605ac372 100644
--- a/Artemis/Artemis/Managers/EffectManager.cs
+++ b/Artemis/Artemis/Managers/EffectManager.cs
@@ -134,7 +134,7 @@ namespace Artemis.Managers
if (loopManager != null && !loopManager.Running)
{
_logger.Debug("Starting LoopManager for effect change");
- loopManager.Start();
+ loopManager.StartAsync();
}
_logger.Debug("Changed active effect to: {0}", effectModel.Name);
diff --git a/Artemis/Artemis/Managers/LoopManager.cs b/Artemis/Artemis/Managers/LoopManager.cs
index 5056e6f94..0ba6f8f61 100644
--- a/Artemis/Artemis/Managers/LoopManager.cs
+++ b/Artemis/Artemis/Managers/LoopManager.cs
@@ -1,6 +1,7 @@
using System;
using System.Drawing;
using System.Linq;
+using System.Threading.Tasks;
using System.Timers;
using Ninject.Extensions.Logging;
using Brush = System.Windows.Media.Brush;
@@ -42,7 +43,12 @@ namespace Artemis.Managers
_keyboardBitmap?.Dispose();
}
- public void Start()
+ public Task StartAsync()
+ {
+ return Task.Run(() => Start());
+ }
+
+ private void Start()
{
if (Running)
return;
diff --git a/Artemis/Artemis/Managers/MainManager.cs b/Artemis/Artemis/Managers/MainManager.cs
index c2c8ca63d..3d612aa7b 100644
--- a/Artemis/Artemis/Managers/MainManager.cs
+++ b/Artemis/Artemis/Managers/MainManager.cs
@@ -46,7 +46,6 @@ namespace Artemis.Managers
ProgramEnabled = false;
Running = false;
-
// TODO: Dependency inject utilities?
KeyboardHook = new KeyboardHook();
@@ -79,12 +78,12 @@ namespace Artemis.Managers
{
_logger.Debug("Shutting down MainManager");
- _processTimer.Stop();
- _processTimer.Dispose();
- LoopManager.Stop();
- EffectManager.ActiveEffect.Dispose();
- GameStateWebServer.Stop();
- PipeServer.Stop();
+ _processTimer?.Stop();
+ _processTimer?.Dispose();
+ LoopManager?.Stop();
+ EffectManager?.ActiveEffect?.Dispose();
+ GameStateWebServer?.Stop();
+ PipeServer?.Stop();
}
///
@@ -94,7 +93,7 @@ namespace Artemis.Managers
{
_logger.Debug("Enabling program");
ProgramEnabled = true;
- LoopManager.Start();
+ LoopManager.StartAsync();
_events.PublishOnUIThread(new ToggleEnabled(ProgramEnabled));
}
diff --git a/Artemis/Artemis/Managers/ProfileManager.cs b/Artemis/Artemis/Managers/ProfileManager.cs
index ed30fc18e..637743b75 100644
--- a/Artemis/Artemis/Managers/ProfileManager.cs
+++ b/Artemis/Artemis/Managers/ProfileManager.cs
@@ -68,7 +68,7 @@ namespace Artemis.Managers
}
// LoopManager might be running, this method won't do any harm in that case.
- _loopManager.Start();
+ _loopManager.StartAsync();
if (!ReferenceEquals(ProfilePreviewModel.Profile, activePreview.ProfileEditor.SelectedProfile))
ProfilePreviewModel.Profile = activePreview.ProfileEditor.SelectedProfile;
diff --git a/Artemis/Artemis/Models/Profiles/LayerConditionModel.cs b/Artemis/Artemis/Models/Profiles/LayerConditionModel.cs
index 7b6fc0fb1..ee659913e 100644
--- a/Artemis/Artemis/Models/Profiles/LayerConditionModel.cs
+++ b/Artemis/Artemis/Models/Profiles/LayerConditionModel.cs
@@ -1,12 +1,19 @@
-using System.Collections.Generic;
-using System.Linq.Dynamic;
+using System;
using Artemis.Models.Interfaces;
using Artemis.Utilities;
+using DynamicExpresso;
namespace Artemis.Models.Profiles
{
public class LayerConditionModel
{
+ private readonly Interpreter _interpreter;
+
+ public LayerConditionModel()
+ {
+ _interpreter = new Interpreter();
+ }
+
public string Field { get; set; }
public string Value { get; set; }
public string Operator { get; set; }
@@ -22,15 +29,29 @@ namespace Artemis.Models.Profiles
return false;
// Put the subject in a list, allowing Dynamic Linq to be used.
- var subjectList = new List {(T) subject};
- bool res;
if (Type == "String")
- res = subjectList.Where($"{Field}.ToLower() {Operator} @0", Value.ToLower()).Any();
- else if (Type == "Enum")
- res = subjectList.Where($"{Field} {Operator} \"{Value}\"").Any();
- else
- res = subjectList.Where($"{Field} {Operator} {Value}").Any();
- return res;
+ {
+ return _interpreter.Eval($"subject.{Field}.ToLower() {Operator} value",
+ new Parameter("subject", typeof(T), subject),
+ new Parameter("value", Value.ToLower()));
+ }
+
+ Parameter rightParam = null;
+ switch (Type)
+ {
+ case "Enum":
+ var enumType = _interpreter.Eval($"subject.{Field}.GetType()", new Parameter("subject", typeof(T), subject));
+ rightParam = new Parameter("value", Enum.Parse(enumType, Value));
+ break;
+ case "Boolean":
+ rightParam = new Parameter("value", bool.Parse(Value));
+ break;
+ case "Int32":
+ rightParam = new Parameter("value", int.Parse(Value));
+ break;
+ }
+
+ return _interpreter.Eval($"subject.{Field} {Operator} value", new Parameter("subject", typeof(T), subject), rightParam);
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileDataModel.cs b/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileDataModel.cs
index de9bc9206..be27cad22 100644
--- a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileDataModel.cs
+++ b/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileDataModel.cs
@@ -8,14 +8,17 @@ namespace Artemis.Modules.Effects.WindowsProfile
{
Spotify = new Spotify();
Cpu = new CpuDataModel();
+ Performance = new PerformanceDataModel();
}
public CpuDataModel Cpu { get; set; }
+ public PerformanceDataModel Performance { get; set; }
public Spotify Spotify { get; set; }
}
public class CpuDataModel
{
+ public int TotalUsage { get; set; }
public int Core1Usage { get; set; }
public int Core2Usage { get; set; }
public int Core3Usage { get; set; }
@@ -26,6 +29,11 @@ namespace Artemis.Modules.Effects.WindowsProfile
public int Core8Usage { get; set; }
}
+ public class PerformanceDataModel
+ {
+ public int RAMUsage { get; set; }
+ }
+
public class Spotify
{
public bool Running { get; set; }
diff --git a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileModel.cs b/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileModel.cs
index b709dcde3..03d1843ee 100644
--- a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileModel.cs
+++ b/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileModel.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Artemis.Managers;
@@ -11,14 +12,60 @@ using SpotifyAPI.Local;
namespace Artemis.Modules.Effects.WindowsProfile
{
+ internal static class PerformanceInfo
+ {
+ [DllImport("psapi.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool GetPerformanceInfo([Out] out PerformanceInformation performanceInformation, [In] int size);
+
+ public static long GetPhysicalAvailableMemoryInMiB()
+ {
+ var pi = new PerformanceInformation();
+ if (GetPerformanceInfo(out pi, Marshal.SizeOf(pi)))
+ {
+ return Convert.ToInt64(pi.PhysicalAvailable.ToInt64()*pi.PageSize.ToInt64()/1048576);
+ }
+ return -1;
+ }
+
+ public static long GetTotalMemoryInMiB()
+ {
+ var pi = new PerformanceInformation();
+ if (GetPerformanceInfo(out pi, Marshal.SizeOf(pi)))
+ {
+ return Convert.ToInt64(pi.PhysicalTotal.ToInt64()*pi.PageSize.ToInt64()/1048576);
+ }
+ return -1;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct PerformanceInformation
+ {
+ public int Size;
+ public IntPtr CommitTotal;
+ public IntPtr CommitLimit;
+ public IntPtr CommitPeak;
+ public IntPtr PhysicalTotal;
+ public IntPtr PhysicalAvailable;
+ public IntPtr SystemCache;
+ public IntPtr KernelTotal;
+ public IntPtr KernelPaged;
+ public IntPtr KernelNonPaged;
+ public IntPtr PageSize;
+ public int HandlesCount;
+ public int ProcessCount;
+ public int ThreadCount;
+ }
+ }
+
public class WindowsProfileModel : EffectModel
{
private readonly ILogger _logger;
private List _cores;
private int _cpuFrames;
+ private PerformanceCounter _overallCpu;
private SpotifyLocalAPI _spotify;
private bool _spotifySetupBusy;
- private bool _triedCpuFix;
public WindowsProfileModel(ILogger logger, MainManager mainManager, WindowsProfileSettings settings)
: base(mainManager, new WindowsProfileDataModel())
@@ -63,19 +110,19 @@ namespace Artemis.Modules.Effects.WindowsProfile
_cores.Add(null);
coreCount++;
}
+ _overallCpu = GetOverallPerformanceCounter();
}
catch (InvalidOperationException)
{
_logger.Warn("Failed to setup CPU information, try running \"lodctr /R\" as administrator.");
}
-
}
private void UpdateCpu(WindowsProfileDataModel dataModel)
{
- if (_cores == null)
+ if (_cores == null || _overallCpu == null)
return;
-
+
// CPU is only updated every 15 frames, the performance counter gives 0 if updated too often
_cpuFrames++;
if (_cpuFrames < 16)
@@ -100,6 +147,16 @@ namespace Artemis.Modules.Effects.WindowsProfile
dataModel.Cpu.Core7Usage = (int) _cores[6].NextValue();
if (_cores[7] != null)
dataModel.Cpu.Core8Usage = (int) _cores[7].NextValue();
+
+ //From Ted - Let's get overall RAM and CPU usage here
+ dataModel.Cpu.TotalUsage = (int) _overallCpu.NextValue();
+
+ var phav = PerformanceInfo.GetPhysicalAvailableMemoryInMiB();
+ var tot = PerformanceInfo.GetTotalMemoryInMiB();
+ var percentFree = phav/(decimal) tot*100;
+ var percentOccupied = 100 - percentFree;
+
+ dataModel.Performance.RAMUsage = (int) percentOccupied;
}
public override List GetRenderLayers(bool renderMice, bool renderHeadsets)
@@ -107,6 +164,18 @@ namespace Artemis.Modules.Effects.WindowsProfile
return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets, false);
}
+ public static PerformanceCounter GetOverallPerformanceCounter()
+ {
+ var cpuCounter = new PerformanceCounter
+ {
+ CategoryName = "Processor",
+ CounterName = "% Processor Time",
+ InstanceName = "_Total"
+ };
+
+ return cpuCounter;
+ }
+
public static List GetPerformanceCounters()
{
var performanceCounters = new List();
diff --git a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs
index 5ee938957..7a2af183c 100644
--- a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs
+++ b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs
@@ -81,7 +81,7 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
public override void RenderOverlay(Graphics keyboard, ref Brush mouse, ref Brush headset, bool renderMice,
bool renderHeadsets)
{
- if (VolumeDisplay != null && VolumeDisplay.Ttl >= 1)
+ if (MainManager.DeviceManager.ActiveKeyboard != null && VolumeDisplay != null && VolumeDisplay.Ttl >= 1)
VolumeDisplay.Draw(keyboard);
}
}
diff --git a/Artemis/Artemis/Services/MetroDialogService.cs b/Artemis/Artemis/Services/MetroDialogService.cs
index 10954f6bc..04465596e 100644
--- a/Artemis/Artemis/Services/MetroDialogService.cs
+++ b/Artemis/Artemis/Services/MetroDialogService.cs
@@ -32,7 +32,7 @@ namespace Artemis.Services
{
public class MetroDialogService : DialogService
{
- private MetroWindow GetActiveWindow()
+ public MetroWindow GetActiveWindow()
{
MetroWindow window = null;
@@ -102,31 +102,29 @@ namespace Artemis.Services
};
if (initialDir != null)
- {
ofd.InitialDirectory = initialDir;
- }
- if (Application.Current.MainWindow != null)
- {
- res = ofd.ShowDialog(Application.Current.MainWindow);
- }
- else
- {
- res = ofd.ShowDialog();
- }
+ res = Application.Current.MainWindow != null
+ ? ofd.ShowDialog(Application.Current.MainWindow)
+ : ofd.ShowDialog();
+
if (res == true)
- {
lPath = ofd.FileName;
- }
else
- {
res = false;
- }
});
path = lPath;
return res.Value;
}
+
+ public Task ShowProgressDialog(string title, string message, bool isCancelable = false,
+ MetroDialogSettings settings = null)
+ {
+ var activeWindow = GetActiveWindow();
+ return activeWindow?.Dispatcher.Invoke(
+ () => activeWindow.ShowProgressAsync(title, message, isCancelable, settings));
+ }
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs
index 30178eb03..e4a5f8a85 100644
--- a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs
@@ -167,7 +167,7 @@ namespace Artemis.ViewModels.Flyouts
if (keyboard != null)
{
MainManager.DeviceManager.EnableKeyboard(keyboard);
- MainManager.LoopManager.Start();
+ MainManager.LoopManager.StartAsync();
}
else
MainManager.DeviceManager.ReleaseActiveKeyboard(true);
diff --git a/Artemis/Artemis/ViewModels/ShellViewModel.cs b/Artemis/Artemis/ViewModels/ShellViewModel.cs
index b04887ff6..e7a6f4fba 100644
--- a/Artemis/Artemis/ViewModels/ShellViewModel.cs
+++ b/Artemis/Artemis/ViewModels/ShellViewModel.cs
@@ -1,4 +1,7 @@
using System.Linq;
+using System.Threading.Tasks;
+using Artemis.Managers;
+using Artemis.Services;
using Artemis.ViewModels.Abstract;
using Artemis.ViewModels.Flyouts;
using Caliburn.Micro;
@@ -8,11 +11,16 @@ namespace Artemis.ViewModels
{
public sealed class ShellViewModel : Conductor.Collection.OneActive
{
+ private readonly DeviceManager _deviceManager;
+ private readonly MetroDialogService _dialogService;
private readonly BaseViewModel[] _viewModels;
- public ShellViewModel(IKernel kernel, IEventAggregator events, BaseViewModel[] viewModels)
+ public ShellViewModel(IKernel kernel, IEventAggregator events, BaseViewModel[] viewModels,
+ DeviceManager deviceManager, MetroDialogService dialogService)
{
_viewModels = viewModels;
+ _deviceManager = deviceManager;
+ _dialogService = dialogService;
events.Subscribe(this);
@@ -34,7 +42,7 @@ namespace Artemis.ViewModels
ActiveItem = _viewModels.FirstOrDefault();
}
-
+
public void Settings()
{
Flyouts.First().IsOpen = !Flyouts.First().IsOpen;
diff --git a/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs b/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs
index dd5cc716d..33cdc0fca 100644
--- a/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs
+++ b/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs
@@ -1,4 +1,7 @@
-using System.Windows;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
using Artemis.Events;
using Artemis.Managers;
using Artemis.Services;
@@ -18,13 +21,14 @@ namespace Artemis.ViewModels
private bool _enabled;
private string _toggleText;
- public SystemTrayViewModel(IWindowManager windowManager, IEventAggregator events, ShellViewModel shellViewModel,
+ public SystemTrayViewModel(IWindowManager windowManager, IEventAggregator events, MetroDialogService dialogService, ShellViewModel shellViewModel,
MainManager mainManager)
{
_windowManager = windowManager;
_shellViewModel = shellViewModel;
_checkedForUpdate = false;
+ DialogService = dialogService;
MainManager = mainManager;
events.Subscribe(this);
@@ -34,14 +38,14 @@ namespace Artemis.ViewModels
ShowWindow();
}
- [Inject]
public MetroDialogService DialogService { get; set; }
public MainManager MainManager { get; set; }
public bool CanShowWindow => !_shellViewModel.IsActive;
- public bool CanHideWindow => _shellViewModel.IsActive;
+ public bool CanHideWindow => _shellViewModel.IsActive && !MainManager.DeviceManager.ChangingKeyboard;
+ public bool CanToggleEnabled => !MainManager.DeviceManager.ChangingKeyboard;
public bool Enabled
{
@@ -114,9 +118,39 @@ namespace Artemis.ViewModels
return;
_checkedForUpdate = true;
+
+ ShowKeyboardDialog();
Updater.CheckForUpdate(DialogService);
}
+ private async void ShowKeyboardDialog()
+ {
+ while(!_shellViewModel.IsActive)
+ await Task.Delay(200);
+
+ NotifyOfPropertyChange(() => CanHideWindow);
+ NotifyOfPropertyChange(() => CanToggleEnabled);
+
+ var dialog = await DialogService.ShowProgressDialog("Enabling keyboard",
+ "Artemis is still busy trying to enable your last used keyboard. " +
+ "Please wait while the progress completes");
+ dialog.SetIndeterminate();
+
+ while (MainManager.DeviceManager.ChangingKeyboard)
+ await Task.Delay(10);
+
+ NotifyOfPropertyChange(() => CanHideWindow);
+ NotifyOfPropertyChange(() => CanToggleEnabled);
+
+ try
+ {
+ await dialog.CloseAsync();
+ }
+ catch (InvalidOperationException)
+ {
+ // Occurs when window is closed again, can't find a proper check for this
+ }
+ }
public void HideWindow()
{
diff --git a/Artemis/Artemis/packages.config b/Artemis/Artemis/packages.config
index 48f0b98da..9c566c400 100644
--- a/Artemis/Artemis/packages.config
+++ b/Artemis/Artemis/packages.config
@@ -5,6 +5,7 @@
+
@@ -20,7 +21,6 @@
-
\ No newline at end of file