diff --git a/src/Artemis.Core/DryIoc/Factories/LoggerFactory.cs b/src/Artemis.Core/DryIoc/Factories/LoggerFactory.cs
index ba5e90db7..3aaa23f08 100644
--- a/src/Artemis.Core/DryIoc/Factories/LoggerFactory.cs
+++ b/src/Artemis.Core/DryIoc/Factories/LoggerFactory.cs
@@ -13,7 +13,10 @@ internal class LoggerFactory : ILoggerFactory
internal static readonly ILogger Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.File(Path.Combine(Constants.LogsFolder, "Artemis log-.log"),
+ fileSizeLimitBytes: 5 * 1024 * 1024,
+ rollOnFileSizeLimit: true,
rollingInterval: RollingInterval.Day,
+ retainedFileCountLimit: 14,
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}")
.WriteTo.Console()
#if DEBUG
diff --git a/src/Artemis.UI.Shared/Styles/TextBlock.axaml b/src/Artemis.UI.Shared/Styles/TextBlock.axaml
index 8a5099cde..4ba8d8252 100644
--- a/src/Artemis.UI.Shared/Styles/TextBlock.axaml
+++ b/src/Artemis.UI.Shared/Styles/TextBlock.axaml
@@ -81,4 +81,8 @@
+
+
diff --git a/src/Artemis.UI/Screens/Debugger/DebugViewModel.cs b/src/Artemis.UI/Screens/Debugger/DebugViewModel.cs
index 44f80c8d7..87cc92d7d 100644
--- a/src/Artemis.UI/Screens/Debugger/DebugViewModel.cs
+++ b/src/Artemis.UI/Screens/Debugger/DebugViewModel.cs
@@ -5,6 +5,7 @@ using Artemis.UI.Screens.Debugger.DataModel;
using Artemis.UI.Screens.Debugger.Logs;
using Artemis.UI.Screens.Debugger.Performance;
using Artemis.UI.Screens.Debugger.Render;
+using Artemis.UI.Screens.Debugger.Routing;
using Artemis.UI.Services.Interfaces;
using Artemis.UI.Shared;
using ReactiveUI;
@@ -15,9 +16,9 @@ public class DebugViewModel : ActivatableViewModelBase, IScreen
{
private ViewModelBase _selectedItem;
- public DebugViewModel(IDebugService debugService, RenderDebugViewModel render, DataModelDebugViewModel dataModel, PerformanceDebugViewModel performance, LogsDebugViewModel logs)
+ public DebugViewModel(IDebugService debugService, RenderDebugViewModel render, DataModelDebugViewModel dataModel, PerformanceDebugViewModel performance, RoutingDebugViewModel routing, LogsDebugViewModel logs)
{
- Items = new ObservableCollection {render, dataModel, performance, logs};
+ Items = new ObservableCollection {render, dataModel, performance, routing, logs};
_selectedItem = render;
this.WhenActivated(d => Disposable.Create(debugService.ClearDebugger).DisposeWith(d));
diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Routing/RoutingDebugView.axaml b/src/Artemis.UI/Screens/Debugger/Tabs/Routing/RoutingDebugView.axaml
new file mode 100644
index 000000000..e89fddd28
--- /dev/null
+++ b/src/Artemis.UI/Screens/Debugger/Tabs/Routing/RoutingDebugView.axaml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+ Navigation logs
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Routing/RoutingDebugView.axaml.cs b/src/Artemis.UI/Screens/Debugger/Tabs/Routing/RoutingDebugView.axaml.cs
new file mode 100644
index 000000000..05c2474ea
--- /dev/null
+++ b/src/Artemis.UI/Screens/Debugger/Tabs/Routing/RoutingDebugView.axaml.cs
@@ -0,0 +1,26 @@
+using Avalonia.Controls;
+using Avalonia.ReactiveUI;
+using Avalonia.Threading;
+
+namespace Artemis.UI.Screens.Debugger.Routing;
+
+public partial class RoutingDebugView : ReactiveUserControl
+{
+ public RoutingDebugView()
+ {
+ InitializeComponent();
+ }
+
+ protected override void OnInitialized()
+ {
+ base.OnInitialized();
+ Dispatcher.UIThread.Post(() => LogsScrollViewer.ScrollToEnd(), DispatcherPriority.ApplicationIdle);
+ }
+
+ private void Control_OnSizeChanged(object? sender, SizeChangedEventArgs e)
+ {
+ if (!(LogsScrollViewer.Extent.Height - LogsScrollViewer.Offset.Y - LogsScrollViewer.Bounds.Bottom <= 60))
+ return;
+ Dispatcher.UIThread.Post(() => LogsScrollViewer.ScrollToEnd(), DispatcherPriority.Normal);
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Routing/RoutingDebugViewModel.cs b/src/Artemis.UI/Screens/Debugger/Tabs/Routing/RoutingDebugViewModel.cs
new file mode 100644
index 000000000..63fc7cf10
--- /dev/null
+++ b/src/Artemis.UI/Screens/Debugger/Tabs/Routing/RoutingDebugViewModel.cs
@@ -0,0 +1,108 @@
+using System;
+using System.IO;
+using System.Reactive;
+using System.Reactive.Disposables;
+using System.Reactive.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Artemis.Core;
+using Artemis.UI.Shared;
+using Artemis.UI.Shared.Routing;
+using Avalonia.Controls.Documents;
+using Avalonia.Media;
+using Avalonia.Threading;
+using ReactiveUI;
+using Serilog.Events;
+using Serilog.Formatting.Display;
+
+namespace Artemis.UI.Screens.Debugger.Routing;
+
+public class RoutingDebugViewModel : ActivatableViewModelBase
+{
+ private readonly IRouter _router;
+ private const int MAX_ENTRIES = 1000;
+ private readonly MessageTemplateTextFormatter _formatter;
+ private string? _route;
+
+ public RoutingDebugViewModel(IRouter router)
+ {
+ _router = router;
+ DisplayName = "Routing";
+ Navigate = ReactiveCommand.CreateFromTask(ExecuteNavigate, this.WhenAnyValue(vm => vm.Route).Select(r => !string.IsNullOrWhiteSpace(r)));
+
+ _formatter = new MessageTemplateTextFormatter(
+ "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] [{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}"
+ );
+
+ foreach (LogEvent logEvent in LogStore.Events)
+ AddLogEvent(logEvent);
+
+ this.WhenActivated(disp =>
+ {
+ LogStore.EventAdded += OnLogEventAdded;
+ Disposable.Create(() => LogStore.EventAdded -= OnLogEventAdded).DisposeWith(disp);
+
+ _router.CurrentPath.Subscribe(p => Route = p).DisposeWith(disp);
+ });
+ }
+
+ public InlineCollection Lines { get; } = new();
+ public ReactiveCommand Navigate { get; }
+
+ public string? Route
+ {
+ get => _route;
+ set => RaiseAndSetIfChanged(ref _route, value);
+ }
+
+ private void OnLogEventAdded(object? sender, LogEventEventArgs e)
+ {
+ Dispatcher.UIThread.Post(() => AddLogEvent(e.LogEvent));
+ }
+
+ private void AddLogEvent(LogEvent? logEvent)
+ {
+ if (logEvent is null)
+ return;
+ if (!logEvent.Properties.TryGetValue("SourceContext", out LogEventPropertyValue? sourceContext) || sourceContext.ToString() != "\"Artemis.UI.Shared.Routing.Navigation\"")
+ return;
+
+ using StringWriter writer = new();
+ _formatter.Format(logEvent, writer);
+ string line = writer.ToString();
+
+ Lines.Add(new Run(line.TrimEnd('\r', '\n') + '\n')
+ {
+ Foreground = logEvent.Level switch
+ {
+ LogEventLevel.Verbose => new SolidColorBrush(Colors.White),
+ LogEventLevel.Debug => new SolidColorBrush(Color.FromRgb(216, 216, 216)),
+ LogEventLevel.Information => new SolidColorBrush(Color.FromRgb(93, 201, 255)),
+ LogEventLevel.Warning => new SolidColorBrush(Color.FromRgb(255, 177, 53)),
+ LogEventLevel.Error => new SolidColorBrush(Color.FromRgb(255, 63, 63)),
+ LogEventLevel.Fatal => new SolidColorBrush(Colors.Red),
+ _ => throw new ArgumentOutOfRangeException()
+ }
+ });
+ LimitLines();
+ }
+
+ private void LimitLines()
+ {
+ if (Lines.Count > MAX_ENTRIES)
+ Lines.RemoveRange(0, Lines.Count - MAX_ENTRIES);
+ }
+
+ private async Task ExecuteNavigate(CancellationToken arg)
+ {
+ try
+ {
+ if (Route != null)
+ await _router.Navigate(Route.Trim());
+ }
+ catch (Exception)
+ {
+ // ignored
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Device/Tabs/DeviceGeneralTabViewModel.cs b/src/Artemis.UI/Screens/Device/Tabs/DeviceGeneralTabViewModel.cs
index 40945c443..f8f21599b 100644
--- a/src/Artemis.UI/Screens/Device/Tabs/DeviceGeneralTabViewModel.cs
+++ b/src/Artemis.UI/Screens/Device/Tabs/DeviceGeneralTabViewModel.cs
@@ -66,13 +66,11 @@ public class DeviceGeneralTabViewModel : ActivatableViewModelBase
this.WhenActivated(d =>
{
- Device.PropertyChanged += DeviceOnPropertyChanged;
_coreService.FrameRendering += OnFrameRendering;
Disposable.Create(() =>
{
_coreService.FrameRendering -= OnFrameRendering;
- Device.PropertyChanged -= DeviceOnPropertyChanged;
Apply();
}).DisposeWith(d);
});
@@ -244,10 +242,4 @@ public class DeviceGeneralTabViewModel : ActivatableViewModelBase
using SKPaint overlayPaint = new() { Color = CurrentColor };
e.Canvas.DrawRect(0, 0, e.Canvas.LocalClipBounds.Width, e.Canvas.LocalClipBounds.Height, overlayPaint);
}
-
- private void DeviceOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName == nameof(Device.CustomLayoutPath) || e.PropertyName == nameof(Device.DisableDefaultLayout))
- Task.Run(() => _rgbService.ApplyBestDeviceLayout(Device));
- }
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Device/Tabs/DeviceLayoutTabView.axaml b/src/Artemis.UI/Screens/Device/Tabs/DeviceLayoutTabView.axaml
index 414f63d93..d253e231f 100644
--- a/src/Artemis.UI/Screens/Device/Tabs/DeviceLayoutTabView.axaml
+++ b/src/Artemis.UI/Screens/Device/Tabs/DeviceLayoutTabView.axaml
@@ -21,6 +21,7 @@