mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Merge branch 'development' into vulkan
This commit is contained in:
commit
fc9476247f
112
azure-pipelines-pr.yml
Normal file
112
azure-pipelines-pr.yml
Normal file
@ -0,0 +1,112 @@
|
||||
# .NET Desktop
|
||||
# Build and run tests for .NET Desktop or Windows classic desktop solutions.
|
||||
# Add steps that publish symbols, save build artifacts, and more:
|
||||
# https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net
|
||||
|
||||
trigger: none
|
||||
pr:
|
||||
- master
|
||||
- Development
|
||||
|
||||
resources:
|
||||
repositories:
|
||||
- repository: RGBNET
|
||||
type: github
|
||||
endpoint: github.com_SpoinkyNL
|
||||
name: DarthAffe/RGB.NET
|
||||
ref: Development
|
||||
- repository: Plugins
|
||||
type: github
|
||||
endpoint: github.com_SpoinkyNL
|
||||
name: Artemis-RGB/Artemis.Plugins
|
||||
ref: master
|
||||
|
||||
pool:
|
||||
vmImage: 'windows-latest'
|
||||
|
||||
variables:
|
||||
artemisSolution: '**/Artemis.sln'
|
||||
rgbSolution: '**/RGB.NET.sln'
|
||||
pluginProjects: '**/Artemis.Plugins.*.csproj'
|
||||
BuildId: $(Build.BuildId)
|
||||
BuildNumber: $(Build.BuildNumber)
|
||||
SourceBranch: $(Build.SourceBranch)
|
||||
SourceVersion: $(Build.SourceVersion)
|
||||
|
||||
steps:
|
||||
- checkout: RGBNET
|
||||
path: s/RGB.NET
|
||||
- checkout: self
|
||||
path: s/Artemis
|
||||
- checkout: Plugins
|
||||
path: s/Artemis.Plugins
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'RGB.NET - Build'
|
||||
inputs:
|
||||
command: 'build'
|
||||
projects: '$(rgbSolution)'
|
||||
arguments: '--configuration Release'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'Artemis - Publish'
|
||||
inputs:
|
||||
command: 'publish'
|
||||
publishWebProjects: false
|
||||
projects: '$(artemisSolution)'
|
||||
arguments: '--runtime win-x64 --self-contained false --output $(Build.ArtifactStagingDirectory)/build /nowarn:cs1591'
|
||||
zipAfterPublish: false
|
||||
modifyOutputPath: false
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Artemis - Create buildinfo.json'
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: |
|
||||
$OFS = "`r`n"
|
||||
SET-Content -Path 'buildinfo.json' -Value ('{' + $OFS + ' "BuildId": 0,' + $OFS + ' "BuildNumber": 0.0,' + $OFS + ' "SourceBranch": "",' + $OFS + ' "SourceVersion": ""' + $OFS + '}')
|
||||
workingDirectory: '$(Build.ArtifactStagingDirectory)/build'
|
||||
|
||||
- task: FileTransform@1
|
||||
displayName: 'Artemis - Populate buildinfo.json'
|
||||
inputs:
|
||||
folderPath: '$(Build.ArtifactStagingDirectory)/build'
|
||||
fileType: 'json'
|
||||
targetFiles: '**/buildinfo.json'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Plugins - Prepare Artemis binaries'
|
||||
inputs:
|
||||
SourceFolder: '$(Build.ArtifactStagingDirectory)/build'
|
||||
Contents: '**'
|
||||
TargetFolder: 'Artemis/src/Artemis.UI/bin/x64/Debug/net5.0-windows'
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Plugins - Insert build number into plugin.json'
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: |
|
||||
Get-ChildItem -Recurse -Filter plugin.json |
|
||||
Foreach-Object {
|
||||
$buidNumber = "1.0.1." + $Env:BUILD_BUILDID;
|
||||
$a = Get-Content $_.FullName | ConvertFrom-Json
|
||||
$a.Version = $buidNumber;
|
||||
$a | ConvertTo-Json | Set-Content $_.FullName
|
||||
}
|
||||
workingDirectory: 'Artemis.Plugins'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'Plugins - Publish'
|
||||
inputs:
|
||||
command: 'publish'
|
||||
publishWebProjects: false
|
||||
arguments: '--runtime win-x64 --self-contained false --output $(Build.ArtifactStagingDirectory)/build/Plugins'
|
||||
projects: '$(pluginProjects)'
|
||||
zipAfterPublish: true
|
||||
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: 'Upload build to Azure Pipelines'
|
||||
inputs:
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)/build'
|
||||
artifact: 'Artemis build'
|
||||
publishLocation: 'pipeline'
|
||||
@ -7,24 +7,38 @@ trigger:
|
||||
- master
|
||||
pr: none
|
||||
|
||||
resources:
|
||||
repositories:
|
||||
- repository: RGBNET
|
||||
type: github
|
||||
endpoint: github.com_SpoinkyNL
|
||||
name: DarthAffe/RGB.NET
|
||||
ref: Development
|
||||
|
||||
pool:
|
||||
vmImage: 'windows-latest'
|
||||
|
||||
variables:
|
||||
artemisSolution: '**/Artemis.sln'
|
||||
|
||||
rgbSolution: '**/RGB.NET.sln'
|
||||
pluginProjects: '**/Artemis.Plugins.*.csproj'
|
||||
BuildId: $(Build.BuildId)
|
||||
BuildNumber: $(Build.BuildNumber)
|
||||
SourceBranch: $(Build.SourceBranch)
|
||||
SourceVersion: $(Build.SourceVersion)
|
||||
|
||||
steps:
|
||||
- checkout: RGBNET
|
||||
path: s/RGB.NET
|
||||
- checkout: self
|
||||
path: s/Artemis
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'RGB.NET - Build'
|
||||
inputs:
|
||||
buildType: 'specific'
|
||||
project: '882fdc71-c09c-4923-8ab0-2cd9fcf0656d'
|
||||
definition: '3'
|
||||
buildVersionToDownload: 'latest'
|
||||
artifactName: 'RGB.NET development build'
|
||||
targetPath: '$(Pipeline.Workspace)/s/RGB.NET/bin/netstandard2.0'
|
||||
command: 'build'
|
||||
projects: '$(rgbSolution)'
|
||||
arguments: '--configuration Release'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'dotnet restore Artemis'
|
||||
|
||||
@ -5,41 +5,50 @@
|
||||
|
||||
trigger:
|
||||
- master
|
||||
pr: none
|
||||
|
||||
resources:
|
||||
repositories:
|
||||
- repository: RGBNET
|
||||
type: github
|
||||
endpoint: github.com_SpoinkyNL
|
||||
name: DarthAffe/RGB.NET
|
||||
ref: Development
|
||||
- repository: Plugins
|
||||
type: github
|
||||
endpoint: github.com_SpoinkyNL
|
||||
name: Artemis-RGB/Artemis.Plugins
|
||||
ref: master
|
||||
|
||||
pool:
|
||||
vmImage: 'windows-latest'
|
||||
|
||||
variables:
|
||||
artemisSolution: '**/Artemis.sln'
|
||||
NUGET_PACKAGES: $(Pipeline.Workspace)/.nuget/packages
|
||||
rgbSolution: '**/RGB.NET.sln'
|
||||
pluginProjects: '**/Artemis.Plugins.*.csproj'
|
||||
BuildId: $(Build.BuildId)
|
||||
BuildNumber: $(Build.BuildNumber)
|
||||
SourceBranch: $(Build.SourceBranch)
|
||||
SourceVersion: $(Build.SourceVersion)
|
||||
|
||||
steps:
|
||||
- checkout: RGBNET
|
||||
path: s/RGB.NET
|
||||
- checkout: self
|
||||
path: s/Artemis
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
inputs:
|
||||
buildType: 'specific'
|
||||
project: '882fdc71-c09c-4923-8ab0-2cd9fcf0656d'
|
||||
definition: '3'
|
||||
buildVersionToDownload: 'latest'
|
||||
artifactName: 'RGB.NET development build'
|
||||
targetPath: '$(Pipeline.Workspace)/s/RGB.NET/bin/net5.0'
|
||||
- checkout: Plugins
|
||||
path: s/Artemis.Plugins
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'dotnet restore Artemis'
|
||||
displayName: 'RGB.NET - Build'
|
||||
inputs:
|
||||
command: 'restore'
|
||||
projects: '$(artemisSolution)'
|
||||
feedsToUse: 'config'
|
||||
nugetConfigPath: '$(Pipeline.Workspace)/s/Artemis/src/NuGet.Config'
|
||||
command: 'build'
|
||||
projects: '$(rgbSolution)'
|
||||
arguments: '--configuration Release'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'Publish Artemis'
|
||||
displayName: 'Artemis - Publish'
|
||||
inputs:
|
||||
command: 'publish'
|
||||
publishWebProjects: false
|
||||
@ -48,22 +57,52 @@ steps:
|
||||
zipAfterPublish: false
|
||||
modifyOutputPath: false
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
- task: PowerShell@2
|
||||
displayName: 'Artemis - Create buildinfo.json'
|
||||
inputs:
|
||||
buildType: 'specific'
|
||||
project: '882fdc71-c09c-4923-8ab0-2cd9fcf0656d'
|
||||
definition: '2'
|
||||
buildVersionToDownload: 'latest'
|
||||
artifactName: 'Artemis build'
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)/build'
|
||||
targetType: 'inline'
|
||||
script: |
|
||||
$OFS = "`r`n"
|
||||
SET-Content -Path 'buildinfo.json' -Value ('{' + $OFS + ' "BuildId": 0,' + $OFS + ' "BuildNumber": 0.0,' + $OFS + ' "SourceBranch": "",' + $OFS + ' "SourceVersion": ""' + $OFS + '}')
|
||||
workingDirectory: '$(Build.ArtifactStagingDirectory)/build'
|
||||
|
||||
- task: FileTransform@1
|
||||
displayName: 'Populate buildinfo.json'
|
||||
displayName: 'Artemis - Populate buildinfo.json'
|
||||
inputs:
|
||||
folderPath: '$(Build.ArtifactStagingDirectory)/build'
|
||||
fileType: 'json'
|
||||
targetFiles: '**/buildinfo.json'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Plugins - Prepare Artemis binaries'
|
||||
inputs:
|
||||
SourceFolder: '$(Build.ArtifactStagingDirectory)/build'
|
||||
Contents: '**'
|
||||
TargetFolder: 'Artemis/src/Artemis.UI/bin/x64/Debug/net5.0-windows'
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Plugins - Insert build number into plugin.json'
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: |
|
||||
Get-ChildItem -Recurse -Filter plugin.json |
|
||||
Foreach-Object {
|
||||
$buidNumber = "1.0.1." + $Env:BUILD_BUILDID;
|
||||
$a = Get-Content $_.FullName | ConvertFrom-Json
|
||||
$a.Version = $buidNumber;
|
||||
$a | ConvertTo-Json | Set-Content $_.FullName
|
||||
}
|
||||
workingDirectory: 'Artemis.Plugins'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'Plugins - Publish'
|
||||
inputs:
|
||||
command: 'publish'
|
||||
publishWebProjects: false
|
||||
arguments: '--runtime win-x64 --self-contained false --output $(Build.ArtifactStagingDirectory)/build/Plugins'
|
||||
projects: '$(pluginProjects)'
|
||||
zipAfterPublish: true
|
||||
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: 'Upload build to Azure Pipelines'
|
||||
inputs:
|
||||
@ -72,6 +111,7 @@ steps:
|
||||
publishLocation: 'pipeline'
|
||||
|
||||
- task: ArchiveFiles@2
|
||||
displayName: 'ZIP binaries'
|
||||
inputs:
|
||||
rootFolderOrFile: '$(Build.ArtifactStagingDirectory)/build'
|
||||
includeRootFolder: false
|
||||
@ -80,13 +120,14 @@ steps:
|
||||
replaceExistingArchive: true
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Calculate ZIP hash'
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: '(Get-FileHash .\artemis-build.zip).Hash | Out-File -FilePath .\hash.txt'
|
||||
workingDirectory: '$(Build.ArtifactStagingDirectory)/archive'
|
||||
|
||||
- task: FtpUpload@2
|
||||
displayName: "Binaries FTP upload"
|
||||
displayName: 'Upload binaries to FTP'
|
||||
inputs:
|
||||
credentialsOption: 'inputs'
|
||||
serverUrl: 'ftp://artemis-rgb.com'
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Ninject.Activation;
|
||||
using Serilog;
|
||||
using Serilog.Core;
|
||||
@ -17,6 +18,7 @@ namespace Artemis.Core.Ninject
|
||||
rollingInterval: RollingInterval.Day,
|
||||
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}")
|
||||
.WriteTo.Debug()
|
||||
.WriteTo.Sink<ArtemisSink>()
|
||||
.MinimumLevel.ControlledBy(LoggingLevelSwitch)
|
||||
.CreateLogger();
|
||||
|
||||
@ -28,4 +30,13 @@ namespace Artemis.Core.Ninject
|
||||
return Logger;
|
||||
}
|
||||
}
|
||||
|
||||
internal class ArtemisSink : ILogEventSink
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public void Emit(LogEvent logEvent)
|
||||
{
|
||||
LogStore.Emit(logEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
55
src/Artemis.Core/Stores/LogStore.cs
Normal file
55
src/Artemis.Core/Stores/LogStore.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A static store containing the last 500 logging events
|
||||
/// </summary>
|
||||
public static class LogStore
|
||||
{
|
||||
private static readonly LinkedList<LogEvent> LinkedList = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list containing the last 500 log events.
|
||||
/// </summary>
|
||||
public static List<LogEvent> Events => LinkedList.ToList();
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a new <see cref="LogEvent" /> was received.
|
||||
/// </summary>
|
||||
public static event EventHandler<LogEventEventArgs>? EventAdded;
|
||||
|
||||
internal static void Emit(LogEvent logEvent)
|
||||
{
|
||||
LinkedList.AddLast(logEvent);
|
||||
if (LinkedList.Count > 500)
|
||||
LinkedList.RemoveFirst();
|
||||
|
||||
OnEventAdded(new LogEventEventArgs(logEvent));
|
||||
}
|
||||
|
||||
private static void OnEventAdded(LogEventEventArgs e)
|
||||
{
|
||||
EventAdded?.Invoke(null, e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains log event related data
|
||||
/// </summary>
|
||||
public class LogEventEventArgs : EventArgs
|
||||
{
|
||||
internal LogEventEventArgs(LogEvent logEvent)
|
||||
{
|
||||
LogEvent = logEvent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the log event
|
||||
/// </summary>
|
||||
public LogEvent LogEvent { get; }
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
"profiles": {
|
||||
"Artemis.UI": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "--force-elevation --logging=debug"
|
||||
"commandLineArgs": "--force-elevation"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -15,70 +15,74 @@
|
||||
FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"
|
||||
UseLayoutRounding="True"
|
||||
FadeContentIfInactive="False"
|
||||
Width="800"
|
||||
Width="1200"
|
||||
Height="800"
|
||||
d:DesignHeight="800" d:DesignWidth="800" d:DataContext="{d:DesignInstance debug:DebugViewModel}"
|
||||
Icon="/Resources/Images/Logo/logo-512.png"
|
||||
Topmost="{Binding StayOnTopSetting.Value}">
|
||||
<DockPanel>
|
||||
<mde:AppBar Type="Dense"
|
||||
Title="Debugger"
|
||||
DockPanel.Dock="Top"
|
||||
Margin="-18 0 0 0">
|
||||
<mde:AppBar.AppIcon>
|
||||
<materialDesign:PackIcon Kind="Matrix" Width="20" Height="28" />
|
||||
</mde:AppBar.AppIcon>
|
||||
<materialDesign:DialogHost IsTabStop="False"
|
||||
Focusable="False"
|
||||
Identifier="DebuggerDialog"
|
||||
DialogTheme="Inherit">
|
||||
<DockPanel>
|
||||
<mde:AppBar Type="Dense"
|
||||
Title="Debugger"
|
||||
DockPanel.Dock="Top"
|
||||
Margin="-18 0 0 0">
|
||||
<mde:AppBar.AppIcon>
|
||||
<materialDesign:PackIcon Kind="Matrix" Width="20" Height="28" />
|
||||
</mde:AppBar.AppIcon>
|
||||
|
||||
<materialDesign:PopupBox DockPanel.Dock="Right" PlacementMode="BottomAndAlignRightEdges" StaysOpen="False">
|
||||
<StackPanel>
|
||||
<Button Command="{s:Action ToggleStayOnTop}">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
|
||||
<ToggleButton Style="{StaticResource MaterialDesignSwitchToggleButton}"
|
||||
Margin="0 0 10 0"
|
||||
IsChecked="{Binding StayOnTopSetting.Value}"/>
|
||||
<TextBlock>Stay on top</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Command="{s:Action ForceGarbageCollection}">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
|
||||
<materialDesign:PackIcon Kind="DeleteEmpty"/>
|
||||
<TextBlock Margin="10 0">Force garbage collection</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Command="{s:Action Elevate}">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
|
||||
<materialDesign:PackIcon Kind="ShieldHalfFull" />
|
||||
<TextBlock Margin="10 0">Elevate permissions</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Command="{s:Action Drop}">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
|
||||
<materialDesign:PackIcon Kind="ChevronDoubleDown" />
|
||||
<TextBlock Margin="10 0">Drop permissions</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Command="{s:Action Restart}">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
|
||||
<materialDesign:PackIcon Kind="Restart" />
|
||||
<TextBlock Margin="10 0">Restart</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</materialDesign:PopupBox>
|
||||
</mde:AppBar>
|
||||
|
||||
<TabControl ItemsSource="{Binding Items}"
|
||||
SelectedItem="{Binding ActiveItem}"
|
||||
DisplayMemberPath="DisplayName"
|
||||
Style="{StaticResource MaterialDesignTabControl}">
|
||||
<TabControl.ContentTemplate>
|
||||
<DataTemplate>
|
||||
<materialDesign:TransitioningContent OpeningEffect="{materialDesign:TransitionEffect FadeIn}">
|
||||
<ContentControl s:View.Model="{Binding}" TextElement.Foreground="{DynamicResource MaterialDesignBody}" Margin="10" />
|
||||
</materialDesign:TransitioningContent>
|
||||
</DataTemplate>
|
||||
</TabControl.ContentTemplate>
|
||||
</TabControl>
|
||||
</DockPanel>
|
||||
<materialDesign:PopupBox DockPanel.Dock="Right" PlacementMode="BottomAndAlignRightEdges" StaysOpen="False">
|
||||
<StackPanel>
|
||||
<Button Command="{s:Action ToggleStayOnTop}">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
|
||||
<ToggleButton Style="{StaticResource MaterialDesignSwitchToggleButton}"
|
||||
Margin="0 0 10 0"
|
||||
IsChecked="{Binding StayOnTopSetting.Value}" />
|
||||
<TextBlock>Stay on top</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Command="{s:Action ForceGarbageCollection}">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
|
||||
<materialDesign:PackIcon Kind="DeleteEmpty" />
|
||||
<TextBlock Margin="10 0">Force garbage collection</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Command="{s:Action Elevate}">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
|
||||
<materialDesign:PackIcon Kind="ShieldHalfFull" />
|
||||
<TextBlock Margin="10 0">Elevate permissions</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Command="{s:Action Drop}">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
|
||||
<materialDesign:PackIcon Kind="ChevronDoubleDown" />
|
||||
<TextBlock Margin="10 0">Drop permissions</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Command="{s:Action Restart}">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
|
||||
<materialDesign:PackIcon Kind="Restart" />
|
||||
<TextBlock Margin="10 0">Restart</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</materialDesign:PopupBox>
|
||||
</mde:AppBar>
|
||||
|
||||
<TabControl ItemsSource="{Binding Items}"
|
||||
SelectedItem="{Binding ActiveItem}"
|
||||
DisplayMemberPath="DisplayName"
|
||||
Style="{StaticResource MaterialDesignTabControl}">
|
||||
<TabControl.ContentTemplate>
|
||||
<DataTemplate>
|
||||
<materialDesign:TransitioningContent OpeningEffect="{materialDesign:TransitionEffect FadeIn}">
|
||||
<ContentControl s:View.Model="{Binding}" TextElement.Foreground="{DynamicResource MaterialDesignBody}" Margin="10" />
|
||||
</materialDesign:TransitioningContent>
|
||||
</DataTemplate>
|
||||
</TabControl.ContentTemplate>
|
||||
</TabControl>
|
||||
</DockPanel>
|
||||
</materialDesign:DialogHost>
|
||||
</mde:MaterialWindow>
|
||||
@ -24,11 +24,11 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||
|
||||
public DataModelDebugViewModel(IDataModelUIService dataModelUIService, IPluginManagementService pluginManagementService)
|
||||
{
|
||||
DisplayName = "DATA MODEL";
|
||||
_dataModelUIService = dataModelUIService;
|
||||
_pluginManagementService = pluginManagementService;
|
||||
_updateTimer = new Timer(25);
|
||||
|
||||
DisplayName = "Data model";
|
||||
Modules = new BindableCollection<Module>();
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,44 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Artemis.UI.Screens.Settings.Debug.Tabs"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance local:LogsDebugViewModel}">
|
||||
<Grid />
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<materialDesign:Card Grid.Row="0" Grid.ColumnSpan="2" Margin="0 0 0 5" Background="#FF424242">
|
||||
<FlowDocumentScrollViewer Document="{Binding LogsDocument}" FontFamily="Consolas" HorizontalScrollBarVisibility="Auto">
|
||||
<FlowDocumentScrollViewer.Resources>
|
||||
<Style TargetType="FlowDocument">
|
||||
<Setter Property="TextElement.FontFamily" Value="Consolas" />
|
||||
<Setter Property="TextElement.FontSize" Value="12" />
|
||||
<Setter Property="PageWidth" Value="2024" />
|
||||
</Style>
|
||||
<Style TargetType="Paragraph">
|
||||
<Setter Property="Margin" Value="0 1" />
|
||||
</Style>
|
||||
</FlowDocumentScrollViewer.Resources>
|
||||
</FlowDocumentScrollViewer>
|
||||
</materialDesign:Card>
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" TextWrapping="Wrap" Margin="0 0 5 0" VerticalAlignment="Center">
|
||||
<materialDesign:PackIcon Kind="Text" Margin="0 0 0 -3"></materialDesign:PackIcon>
|
||||
When reporting errors please don't take a screenshot of the logs, instead upload the full log or select & copy a part of it, thanks!
|
||||
</TextBlock>
|
||||
<StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0 5">
|
||||
<Button Style="{StaticResource MaterialDesignRaisedButton}" Command="{s:Action UploadLogs}" Width="150" Margin="0 0 5 0">
|
||||
UPLOAD LOGS
|
||||
</Button>
|
||||
<Button Style="{StaticResource MaterialDesignOutlinedButton}" Command="{s:Action ShowLogsFolder}" Width="150" Margin="5 0 0 0">
|
||||
SHOW LOGS
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@ -1,12 +1,127 @@
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Serilog.Events;
|
||||
using Serilog.Formatting.Display;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||
{
|
||||
public class LogsDebugViewModel : Screen
|
||||
{
|
||||
public LogsDebugViewModel()
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly MessageTemplateTextFormatter _formatter;
|
||||
private ScrollViewer _scrollViewer;
|
||||
|
||||
public LogsDebugViewModel(IDialogService dialogService)
|
||||
{
|
||||
DisplayName = "Logs";
|
||||
DisplayName = "LOGS";
|
||||
_dialogService = dialogService;
|
||||
_formatter = new MessageTemplateTextFormatter(
|
||||
"{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}"
|
||||
);
|
||||
}
|
||||
|
||||
public FlowDocument LogsDocument { get; } = new();
|
||||
|
||||
public void ShowLogsFolder()
|
||||
{
|
||||
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Path.Combine(Constants.DataFolder, "Logs"));
|
||||
}
|
||||
|
||||
public async Task UploadLogs()
|
||||
{
|
||||
bool confirmed = await _dialogService.ShowConfirmDialogAt(
|
||||
"DebuggerDialog",
|
||||
"Upload logs",
|
||||
"Automatically uploading logs is not yet implemented.\r\n\r\n" +
|
||||
"To manually upload a log simply drag the log file from the logs folder\r\n" +
|
||||
"into Discord or the GitHub issue textbox, depending on what you're using.",
|
||||
"OPEN LOGS FOLDER",
|
||||
"CANCEL");
|
||||
|
||||
if (confirmed)
|
||||
ShowLogsFolder();
|
||||
}
|
||||
|
||||
private Paragraph CreateLogEventParagraph(LogEvent logEvent)
|
||||
{
|
||||
Paragraph paragraph = new(new Run(RenderLogEvent(logEvent)))
|
||||
{
|
||||
// But mah MVVM
|
||||
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()
|
||||
}
|
||||
};
|
||||
|
||||
return paragraph;
|
||||
}
|
||||
|
||||
private string RenderLogEvent(LogEvent logEvent)
|
||||
{
|
||||
using StringWriter writer = new();
|
||||
_formatter.Format(logEvent, writer);
|
||||
return writer.ToString().Trim();
|
||||
}
|
||||
|
||||
#region Overrides of Screen
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnActivate()
|
||||
{
|
||||
LogsDocument.Blocks.AddRange(LogStore.Events.Select(e => CreateLogEventParagraph(e)));
|
||||
LogStore.EventAdded += LogStoreOnEventAdded;
|
||||
|
||||
base.OnActivate();
|
||||
}
|
||||
|
||||
private void LogStoreOnEventAdded(object sender, LogEventEventArgs e)
|
||||
{
|
||||
Execute.PostToUIThread(() =>
|
||||
{
|
||||
LogsDocument.Blocks.Add(CreateLogEventParagraph(e.LogEvent));
|
||||
while (LogsDocument.Blocks.Count > 500)
|
||||
LogsDocument.Blocks.Remove(LogsDocument.Blocks.FirstBlock);
|
||||
|
||||
if (_scrollViewer != null && Math.Abs(_scrollViewer.VerticalOffset - _scrollViewer.ScrollableHeight) < 10)
|
||||
_scrollViewer.ScrollToBottom();
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnDeactivate()
|
||||
{
|
||||
LogStore.EventAdded -= LogStoreOnEventAdded;
|
||||
LogsDocument.Blocks.Clear();
|
||||
|
||||
base.OnDeactivate();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnViewLoaded()
|
||||
{
|
||||
ScrollViewer scrollViewer = VisualTreeUtilities.FindChild<ScrollViewer>(View, null);
|
||||
_scrollViewer = scrollViewer;
|
||||
_scrollViewer?.ScrollToBottom();
|
||||
|
||||
base.OnViewLoaded();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -10,10 +10,10 @@
|
||||
d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance local:RenderDebugViewModel}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" TextWrapping="Wrap">
|
||||
In this window you can view the inner workings of Artemis.
|
||||
@ -30,19 +30,20 @@
|
||||
This image shows what is being rendered and dispatched to RGB.NET
|
||||
</TextBlock>
|
||||
<TextBlock Grid.Column="1" HorizontalAlignment="Right" Margin="0,0,5,0">
|
||||
<Run Text="FPS: "></Run>
|
||||
<Run FontWeight="Bold" Text="{Binding CurrentFps}"></Run>
|
||||
<Run Text=" at "></Run>
|
||||
<Run Text="{Binding RenderWidth}"/><Run Text="x"></Run><Run Text="{Binding RenderHeight}"/>
|
||||
<Run Text="FPS: " />
|
||||
<Run FontWeight="Bold" Text="{Binding CurrentFps}" />
|
||||
<Run Text=" at " />
|
||||
<Run Text="{Binding RenderWidth}" /><Run Text="x" />
|
||||
<Run Text="{Binding RenderHeight}" />
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
|
||||
<materialDesign:Card Grid.Row="2" Margin="0,5,0,0" Background="{StaticResource Checkerboard}">
|
||||
<Image Source="{Binding CurrentFrame}" />
|
||||
<materialDesign:Card Grid.Row="2" Margin="0 5" Background="{StaticResource Checkerboard}">
|
||||
<Image Source="{Binding CurrentFrame}" />
|
||||
</materialDesign:Card>
|
||||
|
||||
<StackPanel Grid.Row="3" Margin="0 5 0 0">
|
||||
<Button HorizontalAlignment="Left" Command="{s:Action SaveFrame}">SAVE FRAME</Button>
|
||||
<StackPanel Grid.Row="3" HorizontalAlignment="Right" Margin="0 5">
|
||||
<Button Style="{StaticResource MaterialDesignOutlinedButton}" Command="{s:Action SaveFrame}">SAVE FRAME</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@ -23,8 +23,8 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||
|
||||
public RenderDebugViewModel(ICoreService coreService)
|
||||
{
|
||||
DisplayName = "RENDERING";
|
||||
_coreService = coreService;
|
||||
DisplayName = "Rendering";
|
||||
}
|
||||
|
||||
public ImageSource CurrentFrame
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user