mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Add UpdateResults Functionality
This commit is contained in:
parent
0459d6e4fa
commit
e1deefc1d2
2 changed files with 58 additions and 26 deletions
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Pipelines;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Flow.Launcher.Core.Plugin.JsonRPCV2Models;
|
||||
|
|
@ -10,16 +11,18 @@ using StreamJsonRpc;
|
|||
|
||||
namespace Flow.Launcher.Core.Plugin
|
||||
{
|
||||
internal abstract class JsonRPCPluginV2 : JsonRPCPluginBase, IDisposable
|
||||
internal abstract class JsonRPCPluginV2 : JsonRPCPluginBase, IAsyncDisposable, IAsyncReloadable, IResultUpdated
|
||||
{
|
||||
public abstract string SupportedLanguage { get; set; }
|
||||
|
||||
public const string JsonRpc = "JsonRPC";
|
||||
|
||||
protected abstract JsonRpc RPC { get; set; }
|
||||
protected abstract IDuplexPipe ClientPipe { get; set; }
|
||||
|
||||
protected StreamReader ErrorStream { get; set; }
|
||||
|
||||
private JsonRpc RPC { get; set; }
|
||||
|
||||
|
||||
protected override async Task<bool> ExecuteResultAsync(JsonRPCResult result)
|
||||
{
|
||||
|
|
@ -59,6 +62,8 @@ namespace Flow.Launcher.Core.Plugin
|
|||
{
|
||||
await base.InitAsync(context);
|
||||
|
||||
SetupJsonRPC();
|
||||
|
||||
_ = ReadErrorAsync();
|
||||
|
||||
await RPC.InvokeAsync("initialize", context);
|
||||
|
|
@ -74,10 +79,40 @@ namespace Flow.Launcher.Core.Plugin
|
|||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public event ResultUpdatedEventHandler ResultsUpdated;
|
||||
|
||||
|
||||
private void SetupJsonRPC()
|
||||
{
|
||||
var formatter = new JsonMessageFormatter();
|
||||
var handler = new NewLineDelimitedMessageHandler(ClientPipe,
|
||||
formatter);
|
||||
|
||||
RPC = new JsonRpc(handler, new JsonRPCPublicAPI(Context.API));
|
||||
|
||||
RPC.AddLocalRpcMethod("UpdateResults", new Action<string, JsonRPCQueryResponseModel>((rawQuery, response) =>
|
||||
{
|
||||
var results = ParseResults(response);
|
||||
ResultsUpdated?.Invoke(this, new ResultUpdatedEventArgs { Query = new Query()
|
||||
{
|
||||
RawQuery = rawQuery
|
||||
}, Results = results });
|
||||
}));
|
||||
RPC.SynchronizationContext = null;
|
||||
RPC.StartListening();
|
||||
}
|
||||
|
||||
public virtual Task ReloadDataAsync()
|
||||
{
|
||||
SetupJsonRPC();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public virtual ValueTask DisposeAsync()
|
||||
{
|
||||
RPC?.Dispose();
|
||||
ErrorStream?.Dispose();
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Pipelines;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -10,18 +11,19 @@ using Flow.Launcher.Core.Plugin.JsonRPCV2Models;
|
|||
using Flow.Launcher.Infrastructure;
|
||||
using Flow.Launcher.Plugin;
|
||||
using Microsoft.VisualStudio.Threading;
|
||||
using Nerdbank.Streams;
|
||||
using StreamJsonRpc;
|
||||
|
||||
namespace Flow.Launcher.Core.Plugin
|
||||
{
|
||||
internal class PythonPluginV2 : JsonRPCPluginV2, IReloadable, IDisposable
|
||||
internal class PythonPluginV2 : JsonRPCPluginV2
|
||||
{
|
||||
private readonly ProcessStartInfo _startInfo;
|
||||
private Process _process;
|
||||
|
||||
public override string SupportedLanguage { get; set; } = AllowedLanguage.Python;
|
||||
|
||||
protected override JsonRpc RPC { get; set; }
|
||||
protected override IDuplexPipe ClientPipe { get; set; }
|
||||
|
||||
|
||||
public PythonPluginV2(string filename)
|
||||
|
|
@ -61,43 +63,38 @@ namespace Flow.Launcher.Core.Plugin
|
|||
_startInfo.WorkingDirectory = context.CurrentPluginMetadata.PluginDirectory;
|
||||
|
||||
_process = Process.Start(_startInfo);
|
||||
|
||||
ArgumentNullException.ThrowIfNull(_process);
|
||||
|
||||
SetupJsonRPC(_process, context.API);
|
||||
|
||||
SetupPipe(_process);
|
||||
|
||||
await base.InitAsync(context);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
_process.Kill(true);
|
||||
await _process.WaitForExitAsync();
|
||||
_process.Dispose();
|
||||
base.Dispose();
|
||||
await base.DisposeAsync();
|
||||
}
|
||||
|
||||
public void ReloadData()
|
||||
private void SetupPipe(Process process)
|
||||
{
|
||||
var (reader, writer) = (PipeReader.Create(process.StandardOutput.BaseStream),
|
||||
PipeWriter.Create(process.StandardInput.BaseStream));
|
||||
ClientPipe = new DuplexPipe(reader, writer);
|
||||
}
|
||||
|
||||
public override async Task ReloadDataAsync()
|
||||
{
|
||||
var oldProcess = _process;
|
||||
_process = Process.Start(_startInfo);
|
||||
ArgumentNullException.ThrowIfNull(_process);
|
||||
SetupJsonRPC(_process, Context.API);
|
||||
SetupPipe(_process);
|
||||
await base.ReloadDataAsync();
|
||||
oldProcess.Kill(true);
|
||||
await oldProcess.WaitForExitAsync();
|
||||
oldProcess.Dispose();
|
||||
}
|
||||
|
||||
private void SetupJsonRPC(Process process, IPublicAPI api)
|
||||
{
|
||||
var formatter = new JsonMessageFormatter();
|
||||
var handler = new NewLineDelimitedMessageHandler(process.StandardInput.BaseStream,
|
||||
process.StandardOutput.BaseStream,
|
||||
formatter);
|
||||
|
||||
ErrorStream = _process.StandardError;
|
||||
|
||||
RPC = new JsonRpc(handler, new JsonRPCPublicAPI(api));
|
||||
RPC.SynchronizationContext = null;
|
||||
RPC.StartListening();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue