From 4d1e7c2692a1a74e0942ef601c181a7bd6ca1399 Mon Sep 17 00:00:00 2001 From: Amos Date: Mon, 5 Aug 2024 16:09:50 +0100 Subject: [PATCH] Refactor PromptClientInput to accept string array for prompt (#336) * Refactor PromptClientInput to accept string array for prompt Updated the `PromptClientInput` method to accept a string array instead of a single string. This change ensures that multiple prompts can be handled, improving input flexibility and client communication. Additionally, modified related method calls to maintain consistency with the new input type. * Refactor PromptClientInput to support parsed result and errors Updated PromptClientInput to handle parsed input results and return error messages instead of raw strings. Introduced ParsedInputResult class to encapsulate parsing results and errors, enhancing client validation and feedback mechanism. --- .../Helpers/ParsedInputResult.cs | 16 ++++++++++ SharedLibraryCore/Utilities.cs | 29 +++++++++++-------- 2 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 SharedLibraryCore/Helpers/ParsedInputResult.cs diff --git a/SharedLibraryCore/Helpers/ParsedInputResult.cs b/SharedLibraryCore/Helpers/ParsedInputResult.cs new file mode 100644 index 00000000..3c590f59 --- /dev/null +++ b/SharedLibraryCore/Helpers/ParsedInputResult.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace SharedLibraryCore.Helpers; + +public class ParsedInputResult +{ + public TResult? Result { get; set; } + public string? RawInput { get; set; } + public List ErrorMessages { get; set; } = []; + + public ParsedInputResult WithError(string errorMessage) + { + ErrorMessages.Add(errorMessage); + return this; + } +} diff --git a/SharedLibraryCore/Utilities.cs b/SharedLibraryCore/Utilities.cs index 34843cab..ee47a773 100644 --- a/SharedLibraryCore/Utilities.cs +++ b/SharedLibraryCore/Utilities.cs @@ -1375,28 +1375,32 @@ namespace SharedLibraryCore public static void ExecuteAfterDelay(this Func action, int delayMs, CancellationToken token = default) => ExecuteAfterDelay(delayMs, action, token); - public static async Task PromptClientInput(this EFClient client, string prompt, Func> validator, - CancellationToken token = default) + public static async Task> PromptClientInput(this EFClient client, string[] prompts, + Func>> parser, string tokenExpiredMessage, CancellationToken token = default) { var clientResponse = new ManualResetEventSlim(false); - string response = null; + ParsedInputResult? response = null; try { IGameEventSubscriptions.ClientMessaged += OnResponse; - await client.TellAsync([prompt], token); + await client.TellAsync(prompts, token); using var tokenSource = new CancellationTokenSource(DefaultCommandTimeout); using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(tokenSource.Token, token); - clientResponse.Wait(linkedTokenSource.Token); + try + { + clientResponse.Wait(linkedTokenSource.Token); + } + catch (OperationCanceledException) + { + await client.TellAsync([tokenExpiredMessage], token); + return new ParsedInputResult { ErrorMessages = [tokenExpiredMessage] }; + } return response; } - catch (OperationCanceledException) - { - return null; - } finally { IGameEventSubscriptions.ClientMessaged -= OnResponse; @@ -1410,16 +1414,17 @@ namespace SharedLibraryCore return; } - response = messageEvent.Message; + response = await parser(messageEvent.Message); + response.RawInput = messageEvent.Message; - if (await validator(response)) + if (response.ErrorMessages.Count is 0) { // ReSharper disable once AccessToDisposedClosure clientResponse.Set(); } else { - await client.TellAsync([prompt], cancellationToken); + await client.TellAsync(response.ErrorMessages.Concat(prompts), cancellationToken); } } }