Part 1 here.

Working with GConsole and want to be able to wrap existing functions more automatically

public static bool AddCommand(string command, string description, Func<string, string="">; method, string helpText = null)

 

That’s how we get things in the console. In GConsole then when you eval the input string it matches the first part against all ‘command’ that have been registered. If it finds a match it calls the ‘method’ with the substring of the input string from after the command name till end of string. So for ease of use I wanted to be able to wrap an arbitrary function in a Func<string,string>.

That’s a few separate tasks

  • Converting string to type
  • Determining number of parameters
  • Knowing param types in the first place

Determining number of params. To start with during testing I simply used .Splint(“,”) on the inputstring, this meant that as long they were comma separated they where different. I knew this was just to get other things tested out as things like sentences within quotes and vector3s etc. want commas in them but not to be a separate param. Regex was the solution as things got more complicated.

 

Regex regex = new Regex(@"\(.*?\)|\[.*?\]|"".*?""|[^\s]+");
MatchCollection matches = regex.Matches(s);
string[] res = new string[matches.Count];
for (int i = 0; i < res.Length; i++)
{
 res[i] = matches[i].Value;
}

 

This will hold out for a while but it’s not going to handle object hierarchies, like json, should the Console get to that level of complexity in the future.

 

Converting strings to types, assuming we know what it should be. ints and floats etc. have builtin Parse functions, if it’s a string, it already is one. For the immediate future, vectors were the other thing I really wanted, they just require breaking up the string and using multiple float Parse. Now we need a way to access these in a way that makes sense for our use case. For me it was a lookup, keyed by Type and storing a Func<object, string>. When these are eventually used in an automated fashion we put the conversion inside try catch blocks so if the conversion fails we report that to the user via the console output and don’t call the function.

 

Knowing parameter types in the first place. Reflection is very powerful. In fact we’ll end up using it for far more than just this. We get the method info out of the type. That can give us attributes applied to the method, which GConsole and CUDLR etc. already use to mark up classes or methods with names that they should be stored under in the console as well as description text to display to the user. What I need right now though is the the parameters of the method. Then we get something like this.

 

var pList = item.GetParameters();

if (!StringToType.Supports(pList))
 continue;

System.Func<string, string> wrappedFunc = (string stringIn) =>
{
 string[] sParams = StringToType.ParamStringToElements(stringIn);
 object[] parameters;

 if (StringToType.StringArrayToObjects(sParams, pList, out parameters))
 {
 item.Invoke(null, parameters);
 return "";
 }

 return "Could not call " + item.Name;
};

 

Next step will be more automating binding and now that we’ve proved out some concepts, moving to CUDLR.

Part 3 here.