From 7d561242e17f82b891ea1fcedc2a77d3999ec1c7 Mon Sep 17 00:00:00 2001 From: Jerker Dahlblom Date: Sun, 15 Oct 2023 15:00:43 +0300 Subject: [PATCH] Looping in range testing and option to show only changes --- src/client/DCSInsight/JSON/DCSAPI.cs | 1 + src/client/DCSInsight/MainWindow.xaml.cs | 21 -- src/client/DCSInsight/Misc/Extensions.cs | 49 +++++ .../DCSInsight/Misc/ResultComparator.cs | 95 +++++++++ .../DCSInsight/Windows/WindowRangeTest.xaml | 10 +- .../Windows/WindowRangeTest.xaml.cs | 194 ++++++++++++------ 6 files changed, 288 insertions(+), 82 deletions(-) create mode 100644 src/client/DCSInsight/Misc/Extensions.cs create mode 100644 src/client/DCSInsight/Misc/ResultComparator.cs diff --git a/src/client/DCSInsight/JSON/DCSAPI.cs b/src/client/DCSInsight/JSON/DCSAPI.cs index 793646a..03124c7 100644 --- a/src/client/DCSInsight/JSON/DCSAPI.cs +++ b/src/client/DCSInsight/JSON/DCSAPI.cs @@ -4,6 +4,7 @@ namespace DCSInsight.JSON { + [Serializable] public class DCSAPI { /// diff --git a/src/client/DCSInsight/MainWindow.xaml.cs b/src/client/DCSInsight/MainWindow.xaml.cs index 85b9a87..3daa19d 100644 --- a/src/client/DCSInsight/MainWindow.xaml.cs +++ b/src/client/DCSInsight/MainWindow.xaml.cs @@ -242,27 +242,6 @@ private void ButtonConnect_OnClick(object sender, RoutedEventArgs e) } } - /* - private static List ReadControlsFromDocJson(string inputPath) - { - // input is a map from category string to a map from key string to control definition - // we read it all then flatten the grand children (the control definitions) - var input = File.ReadAllText(inputPath); - try - { - return JsonConvert.DeserializeObject>>(input)! - .Values - .SelectMany(category => category.Values) - .ToList(); - } - catch (Exception e) - { - Logger.Error(e, "ReadControlsFromDocJson : Failed to read DCS-BIOS JSON."); - } - - return null; - }*/ - private void MainWindow_OnClosing(object sender, CancelEventArgs e) { try diff --git a/src/client/DCSInsight/Misc/Extensions.cs b/src/client/DCSInsight/Misc/Extensions.cs new file mode 100644 index 0000000..9c81bab --- /dev/null +++ b/src/client/DCSInsight/Misc/Extensions.cs @@ -0,0 +1,49 @@ +using System; +using System.Globalization; +using System.IO; +using Newtonsoft.Json; + +namespace DCSInsight.Misc +{ + using TextBox = System.Windows.Controls.TextBox; + + public static class Extensions + { + /// + /// Perform a deep Copy of the object, using Json as a serialization method. NOTE: Private members are not cloned using this method. + /// + /// The type of object being copied. + /// The object instance to copy. + /// The copied object. + public static T CloneJson(this T source) + { + //Note to devs: Use Newtonsoft.Json to clone the object, not System.Text.Json; because there are a lot of Newtonsoft.Json [JsonIgnore] attributes that are ignored + //by the System.Text.Json serializer. This could lead to recursive serialization of unwanted properties that raises an exception. + + if (!typeof(T).IsSerializable) + { + throw new ArgumentException($"DeepClone error. The type must be serializable"); + } + + //Following line fixes "Could not create an instance of type xxx Type is an interface or abstract class and cannot be instantiated." + //when deep cloning IKeyPressInfo from AddKeySequence(string description, SortedList keySequence) + var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }; + + var jsonString = JsonConvert.SerializeObject(source, settings); + return JsonConvert.DeserializeObject(jsonString, settings); + } + + /// + /// US Culture used. Decimal separator is '.' + /// + public static bool ValidateDouble(this TextBox textBox) + { + if (string.IsNullOrEmpty(textBox.Text)) + { + return true; + } + + return double.TryParse(textBox.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out _); + } + } +} diff --git a/src/client/DCSInsight/Misc/ResultComparator.cs b/src/client/DCSInsight/Misc/ResultComparator.cs new file mode 100644 index 0000000..b1da4fa --- /dev/null +++ b/src/client/DCSInsight/Misc/ResultComparator.cs @@ -0,0 +1,95 @@ +using System; +using System.Diagnostics; +using System.Text; +using DCSInsight.JSON; + +namespace DCSInsight.Misc +{ + internal class ResultComparator + { + private readonly DCSAPI _dcsApi; + private bool _resultHasChanged; + private object _lockObject = new(); + + public ResultComparator(DCSAPI dcsApi) + { + _dcsApi = dcsApi; + _dcsApi.Result = int.MinValue.ToString(); // Set so that first value will be listed in the results. + } + + public bool IsMatch(DCSAPI dcsApi) + { + try + { + lock (_lockObject) + { + if (dcsApi.Parameters.Count != _dcsApi.Parameters.Count) return false; + + for (var i = 0; i < _dcsApi.ParamCount; i++) + { + if (_dcsApi.Parameters[i].Value != dcsApi.Parameters[i].Value) + { + return false; + } + } + } + } + catch (Exception ex) + { + Common.ShowErrorMessageBox(ex); + } + + return true; + } + + /// + /// Returns true if result is different since previous check + /// + /// + /// + public bool SetResult(DCSAPI dcsApi) + { + try + { + lock (_lockObject) + { + if (!IsMatch(dcsApi)) + { + throw new Exception("SetResult() : This is not the matching DCSAPI."); + } + + if (dcsApi.Result != _dcsApi.Result) + { + _dcsApi.Result = dcsApi.Result; + _resultHasChanged = true; + return true; + } + } + } + catch (Exception ex) + { + Common.ShowErrorMessageBox(ex); + } + + _resultHasChanged = false; + return false; + } + + public string GetResultString() + { + lock (_lockObject) + { + var currentTestString = new StringBuilder(); + + foreach (var dcsApiParameter in _dcsApi.Parameters) + { + currentTestString.Append($"{dcsApiParameter.ParameterName} [{dcsApiParameter.Value}], "); + } + + currentTestString.Append($" result : {_dcsApi.Result}\n"); + + return currentTestString.ToString(); + } + } + } +} diff --git a/src/client/DCSInsight/Windows/WindowRangeTest.xaml b/src/client/DCSInsight/Windows/WindowRangeTest.xaml index 9bcc0e9..aadf858 100644 --- a/src/client/DCSInsight/Windows/WindowRangeTest.xaml +++ b/src/client/DCSInsight/Windows/WindowRangeTest.xaml @@ -21,7 +21,15 @@ - +