Skip to content

Commit e1deefc

Browse files
committed
Add UpdateResults Functionality
1 parent 0459d6e commit e1deefc

File tree

2 files changed

+58
-26
lines changed

2 files changed

+58
-26
lines changed

Flow.Launcher.Core/Plugin/JsonRPCPluginV2.cs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.IO;
4+
using System.IO.Pipelines;
45
using System.Threading;
56
using System.Threading.Tasks;
67
using Flow.Launcher.Core.Plugin.JsonRPCV2Models;
@@ -10,16 +11,18 @@
1011

1112
namespace Flow.Launcher.Core.Plugin
1213
{
13-
internal abstract class JsonRPCPluginV2 : JsonRPCPluginBase, IDisposable
14+
internal abstract class JsonRPCPluginV2 : JsonRPCPluginBase, IAsyncDisposable, IAsyncReloadable, IResultUpdated
1415
{
1516
public abstract string SupportedLanguage { get; set; }
1617

1718
public const string JsonRpc = "JsonRPC";
1819

19-
protected abstract JsonRpc RPC { get; set; }
20+
protected abstract IDuplexPipe ClientPipe { get; set; }
2021

2122
protected StreamReader ErrorStream { get; set; }
2223

24+
private JsonRpc RPC { get; set; }
25+
2326

2427
protected override async Task<bool> ExecuteResultAsync(JsonRPCResult result)
2528
{
@@ -59,6 +62,8 @@ public override async Task InitAsync(PluginInitContext context)
5962
{
6063
await base.InitAsync(context);
6164

65+
SetupJsonRPC();
66+
6267
_ = ReadErrorAsync();
6368

6469
await RPC.InvokeAsync("initialize", context);
@@ -74,10 +79,40 @@ async Task ReadErrorAsync()
7479
}
7580
}
7681

77-
public void Dispose()
82+
public event ResultUpdatedEventHandler ResultsUpdated;
83+
84+
85+
private void SetupJsonRPC()
86+
{
87+
var formatter = new JsonMessageFormatter();
88+
var handler = new NewLineDelimitedMessageHandler(ClientPipe,
89+
formatter);
90+
91+
RPC = new JsonRpc(handler, new JsonRPCPublicAPI(Context.API));
92+
93+
RPC.AddLocalRpcMethod("UpdateResults", new Action<string, JsonRPCQueryResponseModel>((rawQuery, response) =>
94+
{
95+
var results = ParseResults(response);
96+
ResultsUpdated?.Invoke(this, new ResultUpdatedEventArgs { Query = new Query()
97+
{
98+
RawQuery = rawQuery
99+
}, Results = results });
100+
}));
101+
RPC.SynchronizationContext = null;
102+
RPC.StartListening();
103+
}
104+
105+
public virtual Task ReloadDataAsync()
106+
{
107+
SetupJsonRPC();
108+
return Task.CompletedTask;
109+
}
110+
111+
public virtual ValueTask DisposeAsync()
78112
{
79113
RPC?.Dispose();
80114
ErrorStream?.Dispose();
115+
return ValueTask.CompletedTask;
81116
}
82117
}
83118
}

Flow.Launcher.Core/Plugin/PythonPluginV2.cs

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Diagnostics;
44
using System.IO;
5+
using System.IO.Pipelines;
56
using System.Text;
67
using System.Threading;
78
using System.Threading.Tasks;
@@ -10,18 +11,19 @@
1011
using Flow.Launcher.Infrastructure;
1112
using Flow.Launcher.Plugin;
1213
using Microsoft.VisualStudio.Threading;
14+
using Nerdbank.Streams;
1315
using StreamJsonRpc;
1416

1517
namespace Flow.Launcher.Core.Plugin
1618
{
17-
internal class PythonPluginV2 : JsonRPCPluginV2, IReloadable, IDisposable
19+
internal class PythonPluginV2 : JsonRPCPluginV2
1820
{
1921
private readonly ProcessStartInfo _startInfo;
2022
private Process _process;
2123

2224
public override string SupportedLanguage { get; set; } = AllowedLanguage.Python;
2325

24-
protected override JsonRpc RPC { get; set; }
26+
protected override IDuplexPipe ClientPipe { get; set; }
2527

2628

2729
public PythonPluginV2(string filename)
@@ -61,43 +63,38 @@ public override async Task InitAsync(PluginInitContext context)
6163
_startInfo.WorkingDirectory = context.CurrentPluginMetadata.PluginDirectory;
6264

6365
_process = Process.Start(_startInfo);
64-
6566
ArgumentNullException.ThrowIfNull(_process);
66-
67-
SetupJsonRPC(_process, context.API);
67+
68+
SetupPipe(_process);
6869

6970
await base.InitAsync(context);
7071
}
7172

72-
public void Dispose()
73+
public override async ValueTask DisposeAsync()
7374
{
7475
_process.Kill(true);
76+
await _process.WaitForExitAsync();
7577
_process.Dispose();
76-
base.Dispose();
78+
await base.DisposeAsync();
7779
}
7880

79-
public void ReloadData()
81+
private void SetupPipe(Process process)
82+
{
83+
var (reader, writer) = (PipeReader.Create(process.StandardOutput.BaseStream),
84+
PipeWriter.Create(process.StandardInput.BaseStream));
85+
ClientPipe = new DuplexPipe(reader, writer);
86+
}
87+
88+
public override async Task ReloadDataAsync()
8089
{
8190
var oldProcess = _process;
8291
_process = Process.Start(_startInfo);
8392
ArgumentNullException.ThrowIfNull(_process);
84-
SetupJsonRPC(_process, Context.API);
93+
SetupPipe(_process);
94+
await base.ReloadDataAsync();
8595
oldProcess.Kill(true);
96+
await oldProcess.WaitForExitAsync();
8697
oldProcess.Dispose();
8798
}
88-
89-
private void SetupJsonRPC(Process process, IPublicAPI api)
90-
{
91-
var formatter = new JsonMessageFormatter();
92-
var handler = new NewLineDelimitedMessageHandler(process.StandardInput.BaseStream,
93-
process.StandardOutput.BaseStream,
94-
formatter);
95-
96-
ErrorStream = _process.StandardError;
97-
98-
RPC = new JsonRpc(handler, new JsonRPCPublicAPI(api));
99-
RPC.SynchronizationContext = null;
100-
RPC.StartListening();
101-
}
10299
}
103100
}

0 commit comments

Comments
 (0)