Skip to content

Commit

Permalink
split ArgProcesser
Browse files Browse the repository at this point in the history
  • Loading branch information
MikiraSora committed Oct 21, 2024
1 parent 94d33d3 commit 77f6b1a
Show file tree
Hide file tree
Showing 13 changed files with 450 additions and 347 deletions.
5 changes: 4 additions & 1 deletion OngekiFumenEditor/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ namespace OngekiFumenEditor
/// </summary>
public partial class App : Application
{
public App()
public bool IsGUIMode { get; }

public App(bool isGUIMode = true)
{
AppDomain.CurrentDomain.AssemblyResolve += OnSatelliteAssemblyResolve;
// 设置工作目录为执行文件所在的目录
Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
IsGUIMode = isGUIMode;
}

private Assembly OnSatelliteAssemblyResolve(object sender, ResolveEventArgs args)
Expand Down
61 changes: 44 additions & 17 deletions OngekiFumenEditor/AppBootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Security.Principal;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
Expand All @@ -19,6 +20,7 @@
using Gemini.Modules.Output;
using OngekiFumenEditor.Kernel.ArgProcesser;
using OngekiFumenEditor.Kernel.Audio;
using OngekiFumenEditor.Kernel.CommandExecutor;
using OngekiFumenEditor.Kernel.EditorLayout;
using OngekiFumenEditor.Kernel.Scheduler;
using OngekiFumenEditor.Modules.AudioPlayerToolViewer;
Expand Down Expand Up @@ -158,17 +160,52 @@ private bool CheckIfAdminPermission()
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}

protected override async void OnStartup(object sender, StartupEventArgs e)
protected override void OnStartup(object sender, StartupEventArgs e)
{
var isGUIMode = (App.Current as App)?.IsGUIMode ?? false;

if (isGUIMode)
{
OnStartupForGUI(sender, e);
}
else
{
OnStartupForCMD(sender, e);
}
}

private async void OnStartupForCMD(object sender, StartupEventArgs e)
{
await IoC.Get<ISchedulerManager>().Init();

var executor = IoC.Get<ICommandExecutor>();

try
{
Application.Current.Shutdown(await executor.Execute(e.Args));
}
catch (Exception ex)
{
Log.LogError($"Unhandled exception processing arguments:\n{ex.Message}");
Application.Current.Shutdown(1);
}
}

private async void OnStartupForGUI(object sender, StartupEventArgs e)
{
InitExceptionCatcher();
LogBaseInfos();
InitIPCServer();

await IoC.Get<ISchedulerManager>().Init();

try {
try
{
//process command args
await IoC.Get<IProgramArgProcessManager>().ProcessArgs(e.Args);
} catch (Exception ex) {
}
catch (Exception ex)
{
await Console.Error.WriteLineAsync($"Unhandled exception processing arguments:\n{ex.Message}");
Application.Current.Shutdown(-1);
return;
Expand All @@ -186,11 +223,6 @@ protected override async void OnStartup(object sender, StartupEventArgs e)
curProc.PriorityBoostEnabled = true;
}

ShowStartupGUI();
}

private void OnStartupForGUI()
{
//overwrite ViewLocator
var locateForModel = ViewLocator.LocateForModel;
ViewLocator.LocateForModel = (model, hostControl, ctx) =>
Expand Down Expand Up @@ -227,11 +259,6 @@ private void OnStartupForGUI()
window.AllowDrop = true;
window.Drop += MainWindow_Drop;
}
}

public async void ShowStartupGUI()
{
OnStartupForGUI();

await DisplayRootViewForAsync<IMainWindow>();
var showSplashWindow = IoC.Get<IShell>().Documents.IsEmpty() &&
Expand All @@ -257,14 +284,14 @@ private void InitIPCServer()
{
//if (ProgramSetting.Default.EnableMultiInstances)
// return;
ipcThread = new AbortableThread(async cancelToken =>
ipcThread = new AbortableThread(cancelToken =>
{
while (!cancelToken.IsCancellationRequested)
{
if (!IPCHelper.IsSelfHost())
{
//如果自己不是host那就检查另一个host死了没,来个随机sleep那样的话可以避免多个实例撞车
await Task.Delay(MathUtils.Random(0, 1000));
Thread.Sleep(MathUtils.Random(0, 1000));
if (!IPCHelper.IsHostAlive())
{
//似了就继承大业
Expand All @@ -275,14 +302,14 @@ private void InitIPCServer()

try
{
var line = IPCHelper.ReadLineAsync(cancelToken)?.Trim();
var line = IPCHelper.ReadLine(cancelToken)?.Trim();
if (string.IsNullOrWhiteSpace(line))
continue;
Log.LogDebug($"Recv line by IPC:{line}");
if (line.StartsWith("CMD:"))
{
var args = JsonSerializer.Deserialize<IPCHelper.ArgsWrapper>(line[4..]).Args;
await Application.Current.Dispatcher.InvokeAsync(() =>
Application.Current.Dispatcher.Invoke(() =>
IoC.Get<IProgramArgProcessManager>().ProcessArgs(args));
}
}
Expand Down
54 changes: 54 additions & 0 deletions OngekiFumenEditor/Kernel/ArgProcesser/DefaultArgProcessManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Caliburn.Micro;
using OngekiFumenEditor.Base;
using OngekiFumenEditor.Kernel.Audio;
using OngekiFumenEditor.Modules.FumenVisualEditor;
using OngekiFumenEditor.Modules.PreviewSvgGenerator;
using OngekiFumenEditor.Parser;
using OngekiFumenEditor.Properties;
using OngekiFumenEditor.Utils;
using OngekiFumenEditor.Utils.Logs.DefaultImpls;
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Parsing;
using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
using OngekiFumenEditor.Modules.FumenConverter;
using OngekiFumenEditor.Modules.FumenConverter.Kernel;
using OngekiFumenEditor.Modules.OptionGeneratorTools.Base;
using OngekiFumenEditor.Modules.OptionGeneratorTools.Kernel;
using OngekiFumenEditor.Modules.OptionGeneratorTools.Models;
using Expression = System.Linq.Expressions.Expression;
using OngekiFumenEditor.Kernel.CommandExecutor.Attributes;

namespace OngekiFumenEditor.Kernel.ArgProcesser
{
[Export(typeof(IProgramArgProcessManager))]
internal class DefaultArgProcessManager : IProgramArgProcessManager
{
public async Task ProcessArgs(string[] args)
{
if (args.Length == 0)
return;

//if args[0] is openable file likes .ogkr/.nyagekiProj/.nyageki ...
if (args.IsOnlyOne(out var filePath))
{
if (File.Exists(filePath))
{
Log.LogInfo($"arg.filePath: {filePath}");

_ = Application.Current.Dispatcher.Invoke(async () =>
{
if (await DocumentOpenHelper.TryOpenAsDocument(filePath))
Application.Current?.MainWindow?.Focus();
});
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ namespace OngekiFumenEditor.Kernel.ArgProcesser
public interface IProgramArgProcessManager
{
Task ProcessArgs(string[] args);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,52 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Resources;
using System.Text;
using System.Threading.Tasks;
using OngekiFumenEditor.Properties;
using OngekiFumenEditor.Utils;

namespace OngekiFumenEditor.Kernel.ArgProcesser.Attributes
{
public abstract class OptionBindingAttrbuteBase : Attribute
{
public OptionBindingAttrbuteBase(string name, string description, object defaultValue, Type type)
{
Name = name;
Description = description;
DefaultValue = defaultValue;
Type = type;
}

public string Name { get; set; }
public string Description { get; set; }
public object DefaultValue { get; set; }
public Type Type { get; }
public bool Require { get; set; }
}

[AttributeUsage(AttributeTargets.Property)]
public class OptionBindingAttrbute<T> : OptionBindingAttrbuteBase
{
public OptionBindingAttrbute(string name, string description, T defaultValue) : base(name, description, defaultValue, typeof(T))
{

}
}

[AttributeUsage(AttributeTargets.Property)]
public class LocalizableOptionBindingAttribute<T> : OptionBindingAttrbute<T>
{
public LocalizableOptionBindingAttribute(string name, string resourceKey, T defaultValue, bool require = false)
: base(name, Resources.ResourceManager.GetString(resourceKey) ?? string.Empty, defaultValue)
{
Require = require;
#if DEBUG
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
if (string.IsNullOrWhiteSpace(Description))
Log.LogDebug($"Invalid resource key '{resourceKey}' for option '{name}'");
#endif
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Resources;
using System.Text;
using System.Threading.Tasks;
using OngekiFumenEditor.Properties;
using OngekiFumenEditor.Utils;

namespace OngekiFumenEditor.Kernel.CommandExecutor.Attributes
{
public abstract class OptionBindingAttrbuteBase : Attribute
{
public OptionBindingAttrbuteBase(string name, string description, object defaultValue, Type type)
{
Name = name;
Description = description;
DefaultValue = defaultValue;
Type = type;
}

public string Name { get; set; }
public string Description { get; set; }
public object DefaultValue { get; set; }
public Type Type { get; }
public bool Require { get; set; }
}

[AttributeUsage(AttributeTargets.Property)]
public class OptionBindingAttrbute<T> : OptionBindingAttrbuteBase
{
public OptionBindingAttrbute(string name, string description, T defaultValue) : base(name, description, defaultValue, typeof(T))
{

}
}

[AttributeUsage(AttributeTargets.Property)]
public class LocalizableOptionBindingAttribute<T> : OptionBindingAttrbute<T>
{
public LocalizableOptionBindingAttribute(string name, string resourceKey, T defaultValue, bool require = false)
: base(name, Resources.ResourceManager.GetString(resourceKey) ?? string.Empty, defaultValue)
{
Require = require;
#if DEBUG
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
if (string.IsNullOrWhiteSpace(Description))
Log.LogDebug($"Invalid resource key '{resourceKey}' for option '{name}'");
#endif
}
}
}
Loading

0 comments on commit 77f6b1a

Please sign in to comment.