diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index ee57c4987..67138efdd 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -42,9 +42,9 @@ - - - + + + diff --git a/src/Artemis.Core/Exceptions/ArtemisPluginLockException.cs b/src/Artemis.Core/Exceptions/ArtemisPluginLockException.cs index e601e6e26..f1b5d2e71 100644 --- a/src/Artemis.Core/Exceptions/ArtemisPluginLockException.cs +++ b/src/Artemis.Core/Exceptions/ArtemisPluginLockException.cs @@ -14,7 +14,7 @@ public class ArtemisPluginLockException : Exception private static string CreateExceptionMessage(Exception? innerException) { return innerException != null - ? "Found a lock file, skipping load, see inner exception for last known exception." - : "Found a lock file, skipping load."; + ? "Found a lock file, skipping automatic load, see inner exception for last known exception. Please manually re-enable the plugin." + : "Found a lock file, skipping automatic load. Please manually re-enable the plugin."; } } \ No newline at end of file diff --git a/src/Artemis.Core/MVVM/CorePropertyChanged.cs b/src/Artemis.Core/MVVM/CorePropertyChanged.cs index 8ab50083a..5e7b6b417 100644 --- a/src/Artemis.Core/MVVM/CorePropertyChanged.cs +++ b/src/Artemis.Core/MVVM/CorePropertyChanged.cs @@ -1,4 +1,5 @@ -using System.ComponentModel; +using System.Collections.Generic; +using System.ComponentModel; using System.Runtime.CompilerServices; using Artemis.Core.Properties; @@ -26,7 +27,7 @@ public abstract class CorePropertyChanged : INotifyPropertyChanged [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool RequiresUpdate(ref T storage, T value) { - return !Equals(storage, value); + return !EqualityComparer.Default.Equals(storage, value); } /// diff --git a/src/Artemis.Core/Plugins/LayerBrushes/PerLedLayerBrush.cs b/src/Artemis.Core/Plugins/LayerBrushes/PerLedLayerBrush.cs index e1623b3fc..f0ace6a43 100644 --- a/src/Artemis.Core/Plugins/LayerBrushes/PerLedLayerBrush.cs +++ b/src/Artemis.Core/Plugins/LayerBrushes/PerLedLayerBrush.cs @@ -28,6 +28,8 @@ public abstract class PerLedLayerBrush : PropertiesLayerBrush where T : La /// The color the LED will receive public abstract SKColor GetColor(ArtemisLed led, SKPoint renderPoint); + private readonly SKPoint[] _points = new SKPoint[2]; + internal override void InternalRender(SKCanvas canvas, SKRect bounds, SKPaint paint) { // We don't want rotation on this canvas because that'll displace the LEDs, translations are applied to the points of each LED instead @@ -37,25 +39,21 @@ public abstract class PerLedLayerBrush : PropertiesLayerBrush where T : La using SKPath pointsPath = new(); foreach (ArtemisLed artemisLed in Layer.Leds) { - pointsPath.AddPoly(new[] - { - new SKPoint(0, 0), - new SKPoint(artemisLed.AbsoluteRectangle.Left - Layer.Bounds.Left, artemisLed.AbsoluteRectangle.Top - Layer.Bounds.Top) - }); + _points[0] = new SKPoint(0, 0); + _points[1] = new SKPoint(artemisLed.AbsoluteRectangle.Left - Layer.Bounds.Left, artemisLed.AbsoluteRectangle.Top - Layer.Bounds.Top); + pointsPath.AddPoly(_points); } // Apply the translation to the points of each LED instead if (Layer.General.TransformMode.CurrentValue == LayerTransformMode.Normal && SupportsTransformation) pointsPath.Transform(Layer.GetTransformMatrix(true, true, true, true).Invert()); - SKPoint[] points = pointsPath.Points; - TryOrBreak(() => { for (int index = 0; index < Layer.Leds.Count; index++) { ArtemisLed artemisLed = Layer.Leds[index]; - SKPoint renderPoint = points[index * 2 + 1]; + SKPoint renderPoint = pointsPath.GetPoint(index * 2 + 1); if (!float.IsFinite(renderPoint.X) || !float.IsFinite(renderPoint.Y)) continue; diff --git a/src/Artemis.Core/Stores/LogStore.cs b/src/Artemis.Core/Stores/LogStore.cs index de459357d..a4a3e66ed 100644 --- a/src/Artemis.Core/Stores/LogStore.cs +++ b/src/Artemis.Core/Stores/LogStore.cs @@ -10,12 +10,25 @@ namespace Artemis.Core; /// public static class LogStore { + private static readonly object _lock = new(); + private static readonly LinkedList LinkedList = new(); /// /// Gets a list containing the last 500 log events. /// - public static List Events => LinkedList.ToList(); + public static List Events + { + get + { + List events; + + lock (_lock) + events = LinkedList.ToList(); + + return events; + } + } /// /// Occurs when a new was received. @@ -24,9 +37,13 @@ public static class LogStore internal static void Emit(LogEvent logEvent) { - LinkedList.AddLast(logEvent); - while (LinkedList.Count > 500) - LinkedList.RemoveFirst(); + lock (_lock) + { + LinkedList.AddLast(logEvent); + while (LinkedList.Count > 500) + LinkedList.RemoveFirst(); + } + OnEventAdded(new LogEventEventArgs(logEvent)); } diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj index c8f440c29..047d9906f 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -20,7 +20,7 @@ - + diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index 258b00486..e2619345d 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -34,8 +34,8 @@ - - + + diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugViewModel.cs b/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugViewModel.cs index ca067a392..c1860b01a 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugViewModel.cs +++ b/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugViewModel.cs @@ -48,8 +48,11 @@ public class LogsDebugViewModel : ActivatableViewModelBase }); } - private void AddLogEvent(LogEvent logEvent) + private void AddLogEvent(LogEvent? logEvent) { + if (logEvent is null) + return; + using StringWriter writer = new(); _formatter.Format(logEvent, writer); string line = writer.ToString(); @@ -60,7 +63,7 @@ public class LogsDebugViewModel : ActivatableViewModelBase private void RemoveOldestLine() { - int firstNewLine = Document.Text.IndexOf('\n'); + int firstNewLine = Document.IndexOf('\n', 0, Document.TextLength); if (firstNewLine == -1) { //this should never happen. diff --git a/src/Artemis.UI/Screens/StartupWizard/StartupWizardViewModel.cs b/src/Artemis.UI/Screens/StartupWizard/StartupWizardViewModel.cs index 5008f559a..4ef72e32f 100644 --- a/src/Artemis.UI/Screens/StartupWizard/StartupWizardViewModel.cs +++ b/src/Artemis.UI/Screens/StartupWizard/StartupWizardViewModel.cs @@ -53,7 +53,7 @@ public class StartupWizardViewModel : DialogViewModelBase DeviceProviders = new ObservableCollection(pluginManagementService.GetAllPlugins() .Where(p => p.Info.IsCompatible && p.Features.Any(f => f.AlwaysEnabled && f.FeatureType.IsAssignableTo(typeof(DeviceProvider)))) .OrderBy(p => p.Info.Name) - .Select(p => settingsVmFactory.PluginViewModel(p, null))); + .Select(p => settingsVmFactory.PluginViewModel(p, ReactiveCommand.Create(() => new Unit())))); CurrentStep = 1; SetupButtons();