Skip to content

Commit

Permalink
fix: remove EventHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
arkfinn committed May 11, 2023
1 parent 063a1a1 commit 37aeaeb
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 69 deletions.
48 changes: 39 additions & 9 deletions OpenUtau.Core/Classic/PluginRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,47 @@

namespace OpenUtau.Classic {
public class PluginRunner {
public event EventHandler<ReplaceNoteEventArgs>? OnReplaceNote;
public event EventHandler<PluginErrorEventArgs>? OnError;
private readonly PathManager manager;
private readonly Action<ReplaceNoteEventArgs> OnReplaceNote;
private readonly Action<PluginErrorEventArgs> OnError;
private readonly PathManager PathManager;

public PluginRunner(PathManager manager) {
this.manager = manager;
public static PluginRunner from(PathManager pathManager, DocManager docManager) {
return new PluginRunner(pathManager, ReplaceNoteMethod(docManager), ShowErrorMessageMEthod(docManager));
}

private static Action<ReplaceNoteEventArgs> ReplaceNoteMethod(DocManager docManager) {
return new Action<ReplaceNoteEventArgs>((args) => {
docManager.StartUndoGroup();
docManager.ExecuteCmd(new RemoveNoteCommand(args.Part, args.ToRemove));
docManager.ExecuteCmd(new AddNoteCommand(args.Part, args.ToAdd));
docManager.EndUndoGroup();
});
}

private static Action<PluginErrorEventArgs> ShowErrorMessageMEthod(DocManager docManager) {
return new Action<PluginErrorEventArgs>((args) => {
docManager.ExecuteCmd(new ErrorMessageNotification(args.Message, args.Exception));
});
}

/// <summary>
/// for test
/// </summary>
/// <param name="pathManager"></param>
/// <param name="onReplaceNote"></param>
/// <param name="onError"></param>
public PluginRunner(PathManager pathManager, Action<ReplaceNoteEventArgs> onReplaceNote, Action<PluginErrorEventArgs> onError) {
PathManager = pathManager;
OnReplaceNote = onReplaceNote;
OnError = onError;
}

public void Execute(UProject project, UVoicePart part, UNote? first, UNote? last, IPlugin plugin) {
if (first == null || last == null) {
return;
}
try {
var tempFile = Path.Combine(manager.CachePath, "temp.tmp");
var tempFile = Path.Combine(PathManager.CachePath, "temp.tmp");
var sequence = Ust.WritePlugin(project, part, first, last, tempFile, encoding: plugin.Encoding);
byte[]? beforeHash = HashFile(tempFile);
plugin.Run(tempFile);
Expand All @@ -33,12 +60,13 @@ public void Execute(UProject project, UVoicePart part, UNote? first, UNote? last
}
Log.Information("Legacy plugin temp file has changed.");
var (toRemove, toAdd) = Ust.ParsePlugin(project, part, first, last, sequence, tempFile, encoding: plugin.Encoding);
OnReplaceNote?.Invoke(this, new ReplaceNoteEventArgs(toRemove, toAdd));
OnReplaceNote(new ReplaceNoteEventArgs(part, toRemove, toAdd));
} catch (Exception e) {
OnError?.Invoke(this, new PluginErrorEventArgs("Failed to execute plugin", e));
OnError(new PluginErrorEventArgs("Failed to execute plugin", e));
}
}


private byte[]? HashFile(string filePath) {
using (var md5 = MD5.Create()) {
using (var stream = File.OpenRead(filePath)) {
Expand All @@ -48,10 +76,12 @@ public void Execute(UProject project, UVoicePart part, UNote? first, UNote? last
}

public class ReplaceNoteEventArgs : EventArgs {
public readonly UVoicePart Part;
public readonly List<UNote> ToRemove;
public readonly List<UNote> ToAdd;

public ReplaceNoteEventArgs(List<UNote> toRemove, List<UNote> toAdd) {
public ReplaceNoteEventArgs(UVoicePart part, List<UNote> toRemove, List<UNote> toAdd) {
Part = part;
ToRemove = toRemove;
ToAdd = toAdd;
}
Expand Down
72 changes: 22 additions & 50 deletions OpenUtau.Test/Classic/PluginRunnerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using Avalonia.Media;
using OpenUtau.Core;
using OpenUtau.Core.Ustx;
using Xunit;
Expand All @@ -17,14 +18,14 @@ class ExecuteTestData : IEnumerable<object[]> {
private readonly List<object[]> testData = new();

public ExecuteTestData() {
testData.Add(new object[] { BasicUProject(), IncludeNullResponse(), IncludeNullAssertion() });
testData.Add(new object[] { BasicUProject(), IncludeNullResponse(), IncludeNullAssertion(), EmptyErrorMEthod() });
}

public IEnumerator<object[]> GetEnumerator() => testData.GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

private static ExecuteArgument BasicUProject() {
public static ExecuteArgument BasicUProject() {
var project = new UProject();
project.tracks.Add(new UTrack {
TrackNo = 0,
Expand Down Expand Up @@ -91,8 +92,8 @@ private static Action<StreamWriter> IncludeNullResponse() {
};
}

private static EventHandler<ReplaceNoteEventArgs> IncludeNullAssertion() {
return (sender, args) => {
private static Action<ReplaceNoteEventArgs> IncludeNullAssertion() {
return (args) => {
Assert.Equal(4, args.ToRemove.Count);
Assert.Equal(3, args.ToAdd.Count);
Assert.Equal(480, args.ToAdd[0].duration);
Expand All @@ -103,71 +104,50 @@ private static EventHandler<ReplaceNoteEventArgs> IncludeNullAssertion() {
Assert.Equal("me", args.ToAdd[2].lyric);
};
}

private static Action<PluginErrorEventArgs> EmptyErrorMEthod() {
return (args) => {
// do nothing
};
}
}

[Theory]
[ClassData(typeof(ExecuteTestData))]
public void ExecuteTest(ExecuteArgument given, Action<StreamWriter> when, EventHandler<ReplaceNoteEventArgs> then) {
// This test same as ParsePluginParseNoteTest
// In future, replace to this test
// This test covers more

public void ExecuteTest(ExecuteArgument given, Action<StreamWriter> when, Action<ReplaceNoteEventArgs> then, Action<PluginErrorEventArgs> error) {
// When
var runner = new PluginRunner(PathManager.Inst);
var action = new Action(() => {
var action = new Action<PluginRunner>((runner) => {
runner.Execute(given.Project, given.Part, given.First, given.Last, new PluginStub(when));
});

// Then (Assert in ClassData)
runner.OnReplaceNote += then;
action();
action(new PluginRunner(PathManager.Inst, then, error));
}

[Fact]
public void ExecuteErrorTest() {
// Given
var project = new UProject();
project.tracks.Add(new UTrack {
TrackNo = 0,
});
var part = new UVoicePart() {
trackNo = 0,
position = 0,
};
project.parts.Add(part);

var first = UNote.Create();
first.lyric = "ka";
first.duration = 20;

var last = UNote.Create();
last.lyric = "na";
last.duration = 50;

part.notes.Add(first);
part.notes.Add(last);
var given = ExecuteTestData.BasicUProject();

// When
var runner = new PluginRunner(PathManager.Inst);
var action = new Action(() => {
runner.Execute(project, part, first, last, new PluginStub((writer) => {
// return empty text
var action = new Action<PluginRunner>((runner) => {
runner.Execute(given.Project, given.Part, given.First, given.Last, new PluginStub((writer) => {
// return empty text (invoke error)
}));
});

// Then
runner.OnReplaceNote += ((sender, args) => {
var then = new Action<ReplaceNoteEventArgs>(( args) => {
Assert.Fail("");
});
runner.OnError += ((sender, args) => {
var error = new Action<PluginErrorEventArgs> ((args) => {
Assert.True(true);
});
action();
action(new PluginRunner(PathManager.Inst, then,error));
}
}


public class PluginStub : IPlugin {
class PluginStub : IPlugin {
public PluginStub(Action<StreamWriter> action) {
this.action = action;
}
Expand Down Expand Up @@ -197,12 +177,4 @@ public ExecuteArgument(UProject project, UVoicePart part, UNote first, UNote las
Last = last;
}
}

public class ErrorPluginStub : IPlugin {
public string Encoding => "shift_jis";

public void Run(string tempFile) {
throw new Exception("test");
}
}
}
11 changes: 1 addition & 10 deletions OpenUtau/ViewModels/PianoRollViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,7 @@ public PianoRollViewModel() {
first = NotesViewModel.Selection.FirstOrDefault();
last = NotesViewModel.Selection.LastOrDefault();
}
var runner = new PluginRunner(PathManager.Inst);
runner.OnReplaceNote += ((sender, args) => {
DocManager.Inst.StartUndoGroup();
DocManager.Inst.ExecuteCmd(new RemoveNoteCommand(part, args.ToRemove));
DocManager.Inst.ExecuteCmd(new AddNoteCommand(part, args.ToAdd));
DocManager.Inst.EndUndoGroup();
});
runner.OnError += ((sender, args) => {
DocManager.Inst.ExecuteCmd(new ErrorMessageNotification(args.Message, args.Exception));
});
var runner = PluginRunner.from(PathManager.Inst, DocManager.Inst);
runner.Execute(NotesViewModel.Project, part, first, last, plugin);
});
LegacyPlugins.AddRange(DocManager.Inst.Plugins.Select(plugin => new MenuItemViewModel() {
Expand Down

0 comments on commit 37aeaeb

Please sign in to comment.