From d00c8bed5ffe602b192b04397af802acd809de24 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 20 May 2021 10:52:12 -0600 Subject: [PATCH] fix:(EssentialsCore) Add ability for `devjson` command to handle overloads The `devjson` command needs to ability to handle overloads. With this change, if a method is an overloaded method, the command will get all methods on an object that match the entered method name, then get the first entry in the list of methods that matches the length of the provided parameters list. This won't work in all cases, as there may be situations where the parameters of the methods have the same length, but different types. In that situation, it's likely that the conversion from `Object` to the desired type will fail, in which case, the command will notify the user that something went wrong. --- .../Devices/DeviceJsonApi.cs | 81 +++++++++++++------ 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs index 51d5882f..a1930cf0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs @@ -20,8 +20,23 @@ namespace PepperDash.Essentials.Core /// public static void DoDeviceActionWithJson(string json) { - var action = JsonConvert.DeserializeObject(json); - DoDeviceAction(action); + if (String.IsNullOrEmpty(json)) + { + CrestronConsole.ConsoleCommandResponse( + "Please provide a JSON object matching the format {\"deviceKey\":\"myDevice\", \"methodName\":\"someMethod\", \"params\": [\"param1\", true]}.\r\nIf the method has no parameters, the \"params\" object may be omitted."); + return; + } + try + { + var action = JsonConvert.DeserializeObject(json); + + DoDeviceAction(action); + } + catch (Exception ex) + { + CrestronConsole.ConsoleCommandResponse("Incorrect format for JSON. Please check that the format matches {\"deviceKey\":\"myDevice\", \"methodName\":\"someMethod\", \"params\": [\"param1\", true]}"); + } + } @@ -33,29 +48,47 @@ namespace PepperDash.Essentials.Core { var key = action.DeviceKey; var obj = FindObjectOnPath(key); - if (obj == null) - return; + if (obj == null) + { + CrestronConsole.ConsoleCommandResponse("Unable to find object at path {0}", key); + return; + } - CType t = obj.GetType(); - var method = t.GetMethod(action.MethodName); - if (method == null) - { - Debug.Console(0, "Method '{0}' not found", action.MethodName); - return; - } - var mParams = method.GetParameters(); - // Add empty params if not provided - if (action.Params == null) action.Params = new object[0]; - if (mParams.Length > action.Params.Length) - { - Debug.Console(0, "Method '{0}' requires {1} params", action.MethodName, mParams.Length); - return; - } - object[] convertedParams = mParams - .Select((p, i) => Convert.ChangeType(action.Params[i], p.ParameterType, - System.Globalization.CultureInfo.InvariantCulture)) - .ToArray(); - object ret = method.Invoke(obj, convertedParams); + if (action.Params == null) + { + //no params, so setting action.Params to empty array + action.Params = new object[0]; + } + + CType t = obj.GetType(); + try + { + var methods = t.GetMethods().Where(m => m.Name == action.MethodName).ToList(); + + var method = methods.Count == 1 ? methods[0] : methods.FirstOrDefault(m => m.GetParameters().Length == action.Params.Length); + + if (method == null) + { + CrestronConsole.ConsoleCommandResponse( + "Unable to find method with name {0} and that matches parameters {1}", action.MethodName, + action.Params); + return; + } + var mParams = method.GetParameters(); + + var convertedParams = mParams + .Select((p, i) => Convert.ChangeType(action.Params[i], p.ParameterType, + System.Globalization.CultureInfo.InvariantCulture)) + .ToArray(); + var ret = method.Invoke(obj, convertedParams); + + CrestronConsole.ConsoleCommandResponse("Method {0} successfully called on device {1}", method.Name, + action.DeviceKey); + } + catch (Exception ex) + { + CrestronConsole.ConsoleCommandResponse("Unable to call method with name {0}. {1}", action.MethodName, + ex.Message);} } ///