Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
Yoooi0 committed Jan 27, 2024
2 parents 1b8795e + 9a053f2 commit 49e1089
Show file tree
Hide file tree
Showing 173 changed files with 9,878 additions and 7,344 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ jobs:
- name: Install dependencies
run: dotnet restore
- name: Build ${{ matrix.build_type }}
run: dotnet publish --configuration ${{ matrix.build_type }} /p:AssemblyVersion=${{ steps.gitversion.outputs.assemblySemVer }} /p:FileVersion=${{ steps.gitversion.outputs.assemblySemFileVer }} /p:InformationalVersion=${{ steps.gitversion.outputs.fullSemVer }}.${{ steps.gitversion.outputs.shortSha }}
run: dotnet publish --configuration ${{ matrix.build_type }}
- name: Upload ${{ matrix.build_type }} artifact
uses: actions/upload-artifact@v3
with:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ jobs:
- name: Install Dependencies
run: dotnet restore
- name: Build Framework Dependent
run: dotnet publish --self-contained false --configuration Release --property:PublishDir=.\bin\Release\win-x64\publish\framework-dependent /p:AssemblyVersion=${{ steps.gitversion.outputs.assemblySemVer }} /p:FileVersion=${{ steps.gitversion.outputs.assemblySemFileVer }} /p:InformationalVersion=${{ steps.gitversion.outputs.fullSemVer }}.${{ steps.gitversion.outputs.shortSha }}
run: dotnet publish --self-contained false --configuration Release --property:PublishDir=.\bin\Release\win-x64\publish\framework-dependent
- name: Build Self Contained
run: dotnet publish --self-contained true --configuration Release --property:PublishDir=.\bin\Release\win-x64\publish\self-contained /p:AssemblyVersion=${{ steps.gitversion.outputs.assemblySemVer }} /p:FileVersion=${{ steps.gitversion.outputs.assemblySemFileVer }} /p:InformationalVersion=${{ steps.gitversion.outputs.fullSemVer }}.${{ steps.gitversion.outputs.shortSha }}
run: dotnet publish --self-contained true --configuration Release --property:PublishDir=.\bin\Release\win-x64\publish\self-contained
- name: Setup NetBeauty
run: dotnet tool install --global nulastudio.nbeauty
- name: Run NetBeauty
Expand Down
1 change: 1 addition & 0 deletions GitVersion.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
assembly-informational-format: '{FullSemVer}.{ShortSha}'
1 change: 1 addition & 0 deletions MultiFunPlayer.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.github\workflows\ci.yml = .github\workflows\ci.yml
GitVersion.yml = GitVersion.yml
LICENSE.md = LICENSE.md
.github\workflows\publish.yml = .github\workflows\publish.yml
README.md = README.md
Expand Down
59 changes: 30 additions & 29 deletions Source/MultiFunPlayer/App.xaml
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
<Application x:Class="MultiFunPlayer.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:converters="clr-namespace:MultiFunPlayer.UI.Converters"
xmlns:local="clr-namespace:MultiFunPlayer"
xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:converters="clr-namespace:MultiFunPlayer.UI.Converters"
xmlns:s="https://github.com/canton7/Stylet"
x:ClassModifier="internal">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Steel.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Steel.xaml"/>

<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PopupBox.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.BlueGrey.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PopupBox.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.BlueGrey.xaml"/>

<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.MahApps;component/Themes/MaterialDesignTheme.MahApps.Defaults.xaml"/>

Expand All @@ -27,31 +27,32 @@

<converters:DisplayNameConverter x:Key="DisplayNameConverter"/>
<converters:DescriptionConverter x:Key="DescriptionConverter"/>
<converters:NullableToBooleanConverter x:Key="NullableToBooleanConverter" />
<converters:InvertedNullableToBooleanConverter x:Key="InvertedNullableToBooleanConverter" />
<converters:BooleanAndConverter x:Key="BooleanAndConverter" />
<converters:BooleanOrConverter x:Key="BooleanOrConverter" />
<converters:NullableToBooleanConverter x:Key="NullableToBooleanConverter"/>
<converters:InvertedNullableToBooleanConverter x:Key="InvertedNullableToBooleanConverter"/>
<converters:BooleanAndConverter x:Key="BooleanAndConverter"/>
<converters:BooleanOrConverter x:Key="BooleanOrConverter"/>
<converters:MsToHzConverter x:Key="MsToHzConverter"/>

<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<material:NotConverter x:Key="NotConverter"/>
</ResourceDictionary>

<ResourceDictionary Source="pack://application:,,,/UI/Themes/Color.Light.xaml" />
<ResourceDictionary Source="pack://application:,,,/UI/Themes/Color.xaml" />

<ResourceDictionary Source="pack://application:,,,/UI/Themes/Button.xaml" />
<ResourceDictionary Source="pack://application:,,,/UI/Themes/Expander.xaml" />
<ResourceDictionary Source="pack://application:,,,/UI/Themes/FocusVisual.xaml" />
<ResourceDictionary Source="pack://application:,,,/UI/Themes/Menu.xaml" />
<ResourceDictionary Source="pack://application:,,,/UI/Themes/PopupBox.xaml" />
<ResourceDictionary Source="pack://application:,,,/UI/Themes/RangeSlider.xaml" />
<ResourceDictionary Source="pack://application:,,,/UI/Themes/ScrollViewer.xaml" />
<ResourceDictionary Source="pack://application:,,,/UI/Themes/TabControl.xaml" />
<ResourceDictionary Source="pack://application:,,,/UI/Themes/Slider.xaml" />
<ResourceDictionary Source="pack://application:,,,/UI/Themes/TextBlock.xaml" />
<ResourceDictionary Source="pack://application:,,,/UI/Themes/ToolTip.xaml" />
<ResourceDictionary Source="pack://application:,,,/UI/Themes/Window.xaml" />
<ResourceDictionary Source="pack://application:,,,/UI/Themes/Color.Light.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UI/Themes/Color.xaml"/>

<ResourceDictionary Source="pack://application:,,,/UI/Themes/Button.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UI/Themes/Card.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UI/Themes/Expander.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UI/Themes/FocusVisual.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UI/Themes/Menu.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UI/Themes/PopupBox.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UI/Themes/RangeSlider.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UI/Themes/ScrollViewer.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UI/Themes/TabControl.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UI/Themes/Slider.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UI/Themes/TextBlock.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UI/Themes/ToolTip.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UI/Themes/Window.xaml"/>

<s:ApplicationLoader>
<s:ApplicationLoader.Bootstrapper>
Expand Down
4 changes: 1 addition & 3 deletions Source/MultiFunPlayer/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,4 @@ namespace MultiFunPlayer;
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
internal sealed partial class App : Application
{
}
internal sealed partial class App : Application;
15 changes: 10 additions & 5 deletions Source/MultiFunPlayer/Bootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using MultiFunPlayer.Script.Repository;
using MultiFunPlayer.Script.Repository.ViewModels;
using MultiFunPlayer.Settings;
using MultiFunPlayer.Shortcut;
using MultiFunPlayer.UI;
using MultiFunPlayer.UI.Controls.ViewModels;
using Newtonsoft.Json;
Expand Down Expand Up @@ -63,8 +64,7 @@ protected override void ConfigureIoC(IStyletIoCBuilder builder)

builder.Bind<IStyletLoggerManager>().To<StyletLoggerManager>().InSingletonScope();
builder.Bind<IOutputTargetFactory>().To<OutputTargetFactory>().InSingletonScope();
builder.Bind<IShortcutManager>().To<ShortcutManager>().InSingletonScope();
builder.Bind<IShortcutBinder>().To<ShortcutBinder>().InSingletonScope();
builder.Bind<IShortcutManager>().And<IShortcutActionResolver>().To<ShortcutManager>().InSingletonScope();
builder.Bind<IInputProcessorManager>().To<InputProcessorManager>().InSingletonScope();
builder.Bind<IPropertyManager>().To<PropertyManager>().InSingletonScope();
builder.Bind<IMotionProviderFactory>().To<MotionProviderFactory>().InSingletonScope();
Expand All @@ -86,6 +86,12 @@ protected override void Configure()
var dirty = ConfigureLoging(settings);

var logger = LogManager.GetLogger(nameof(MultiFunPlayer));
var shortcutManager = Container.Get<IShortcutManager>();
shortcutManager.RegisterAction<LogLevel, string>("Debug::Log",
s => s.WithLabel("Log level").WithDefaultValue(LogLevel.Info).WithItemsSource(LogLevel.AllLoggingLevels),
s => s.WithLabel("Message"),
logger.Log);

AppDomain.CurrentDomain.UnhandledException += (s, e) =>
{
logger.Fatal(e.ExceptionObject as Exception);
Expand All @@ -101,7 +107,7 @@ protected override void Configure()
SettingsHelper.Write(settings);

logger.Info("Environment [OSVersion: {0}, CLRVersion: {1}]", Environment.OSVersion, Environment.Version);
logger.Info("Assembly [Version: {0}, FileVersion: {1}, InformationalVersion: {2}]", ReflectionUtils.AssemblyVersion, ReflectionUtils.AssemblyFileVersion, ReflectionUtils.AssemblyInformationalVersion);
logger.Info("Assembly [Version: {0}-{1}+{2}]", GitVersionInformation.MajorMinorPatch, GitVersionInformation.PreReleaseTag, GitVersionInformation.FullBuildMetaData);
logger.Info("Timer [IsHighResolution: {0}, Frequency: {1}]", Stopwatch.IsHighResolution, Stopwatch.Frequency);
logger.Info("Set working directory to \"{0}\"", workingDirectory);
}
Expand Down Expand Up @@ -272,8 +278,7 @@ private bool ConfigureLoging(JObject settings)
settings["LogBlacklist"] = JObject.FromObject(new Dictionary<string, LogLevel>()
{
[$"{typeof(RawInputProcessor).Namespace}.*"] = LogLevel.Trace,
[$"{typeof(XInputProcessor).Namespace}.*"] = LogLevel.Trace,
[$"{typeof(ShortcutSettingsViewModel).FullName}"] = LogLevel.Trace
[$"{typeof(XInputProcessor).Namespace}.*"] = LogLevel.Trace
});
dirty = true;
}
Expand Down
95 changes: 95 additions & 0 deletions Source/MultiFunPlayer/Common/BroadcastEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System.Collections.Concurrent;
using System.Diagnostics;

namespace MultiFunPlayer.Common;

internal sealed class BroadcastEvent<T> where T : class
{
private readonly ConcurrentDictionary<object, ManualResetEvent> _waitHandles = [];
private readonly ConcurrentDictionary<object, Task<bool>> _tasks = [];
private volatile T _value;

public void Set(T value)
{
_value = value;
foreach (var (_, waitHandle) in _waitHandles)
waitHandle.Set();
}

public void RegisterContext(object context)
{
if (!_waitHandles.TryAdd(context, new ManualResetEvent(false)))
throw new InvalidOperationException("Context can only be registered once");
}

public void UnregisterContext(object context)
{
if (_waitHandles.TryRemove(context, out var waitHandle))
waitHandle.Dispose();
_ = _tasks.TryRemove(context, out var _);
}

public (bool Success, T Value) WaitOne(object context, CancellationToken cancellationToken)
{
var waitHandle = _waitHandles[context];
if (!waitHandle.WaitOne(cancellationToken))
return (false, default);

cancellationToken.ThrowIfCancellationRequested();
return (true, CleanupAndGetValue(context));
}

public async ValueTask<(bool Success, T Value)> WaitOneAsync(object context, CancellationToken cancellationToken)
{
var waitHandle = _waitHandles[context];
if (waitHandle.WaitOne(0))
return (true, CleanupAndGetValue(context));

if (!await GetWaitHandleTask(context, cancellationToken))
return (false, default);

cancellationToken.ThrowIfCancellationRequested();
return (true, CleanupAndGetValue(context));
}

private T CleanupAndGetValue(object context)
{
if (!_waitHandles.TryRemove(context, out var waitHandle))
throw new UnreachableException();

_ = _tasks.TryRemove(context, out var _);
waitHandle.Dispose();

if (!_waitHandles.TryAdd(context, new ManualResetEvent(false)))
throw new UnreachableException();

return _value;
}

private Task<bool> GetWaitHandleTask(object context, CancellationToken cancellationToken)
=> _tasks.GetOrAdd(context, c => _waitHandles[c].WaitOneAsync(cancellationToken));

public static (int Index, T Value) WaitAny(BroadcastEvent<T>[] events, object context, CancellationToken cancellationToken)
{
var waitHandles = events.Select(e => e._waitHandles[context]).Append(cancellationToken.WaitHandle).ToArray();
var index = WaitHandle.WaitAny(waitHandles);

cancellationToken.ThrowIfCancellationRequested();
return (index, events[index].CleanupAndGetValue(context));
}

public static async ValueTask<(int Index, T Value)> WaitAnyAsync(BroadcastEvent<T>[] events, object context, CancellationToken cancellationToken)
{
var waitHandles = events.Select(e => e._waitHandles[context]).Append(cancellationToken.WaitHandle).ToArray();
var index = WaitHandle.WaitAny(waitHandles, 0);
if (index == WaitHandle.WaitTimeout)
{
var tasks = events.Select(e => e.GetWaitHandleTask(context, cancellationToken)).ToList();
var task = await Task.WhenAny(tasks);
index = tasks.IndexOf(task);
}

cancellationToken.ThrowIfCancellationRequested();
return (index, events[index].CleanupAndGetValue(context));
}
}
9 changes: 6 additions & 3 deletions Source/MultiFunPlayer/Common/DeviceAxis.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using MultiFunPlayer.Settings.Converters;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Frozen;
using System.Collections.Immutable;
using System.ComponentModel;
using System.Runtime.Serialization;

Expand All @@ -27,8 +29,8 @@ public sealed class DeviceAxis
private static int _count;
private static int _outputMaximum;
private static string _outputFormat;
private static Dictionary<string, DeviceAxis> _axes;
public static IReadOnlyCollection<DeviceAxis> All => _axes.Values;
private static FrozenDictionary<string, DeviceAxis> _axes;
public static ImmutableArray<DeviceAxis> All { get; private set; }

public static DeviceAxis Parse(string name) => _axes.GetValueOrDefault(name, null);
public static bool TryParse(string name, out DeviceAxis axis)
Expand Down Expand Up @@ -59,6 +61,7 @@ internal static void LoadSettings(JObject settings, JsonSerializer serializer)

_outputMaximum = (int)(Math.Pow(10, precision) - 1);
_outputFormat = $"{{0:{new string('0', precision)}}}";
_axes = axes.ToDictionary(a => a.Name, a => a);
_axes = axes.ToFrozenDictionary(a => a.Name, a => a);
All = [.. axes];
}
}
Loading

0 comments on commit 49e1089

Please sign in to comment.