예제 #1
0
        /// <summary>Invokes a command on the QuantumConsoleProcessor.</summary>
        /// <returns>Return value of the invocation.</returns>
        /// <param name="commandString">The command to invoke.</param>
        public static object InvokeCommand(string commandString)
        {
            GenerateCommandTable();

            commandString = commandString.Trim();
            commandString = _preprocessor.Process(commandString);

            if (string.IsNullOrWhiteSpace(commandString))
            {
                throw new ArgumentException("Cannot parse an empty string.");
            }
            string[] commandParts = commandString.SplitScoped(' ');
            commandParts = commandParts.Where(x => !string.IsNullOrWhiteSpace(x)).ToArray();

            string commandName = commandParts[0];

            string[] commandParams = commandParts.SubArray(1, commandParts.Length - 1);
            int      paramCount    = commandParams.Length;

            string[] commandNameParts = commandName.Split(new[] { '<' }, 2);
            string   genericSignature = commandNameParts.Length > 1 ? $"<{commandNameParts[1]}" : "";

            commandName = commandNameParts[0];

            string keyName = $"{commandName}({paramCount})";

            if (!_commandTable.ContainsKey(keyName))
            {
                bool overloadExists = _commandTable.Keys.Any(key => key.Contains($"{commandName}(") && _commandTable[key].CommandName == commandName);
                if (overloadExists)
                {
                    throw new ArgumentException($"No overload of '{commandName}' with {paramCount} parameters could be found.");
                }
                else
                {
                    throw new ArgumentException($"Command '{commandName}' could not be found.");
                }
            }
            CommandData command = _commandTable[keyName];

            Type[] genericTypes = Array.Empty <Type>();
            if (command.IsGeneric)
            {
                int      expectedArgCount = command.GenericParamTypes.Length;
                string[] genericArgNames  = genericSignature.ReduceScope('<', '>').SplitScoped(',');
                if (genericArgNames.Length == expectedArgCount)
                {
                    genericTypes = new Type[genericArgNames.Length];
                    for (int i = 0; i < genericTypes.Length; i++)
                    {
                        genericTypes[i] = QuantumParser.ParseType(genericArgNames[i]);
                    }
                }
                else
                {
                    throw new ArgumentException($"Generic command '{commandName}' requires {expectedArgCount} generic parameter{(expectedArgCount == 1 ? "" : "s")} but was supplied with {genericArgNames.Length}.");
                }
            }
            else if (genericSignature != string.Empty)
            {
                throw new ArgumentException($"Command '{commandName}' is not a generic command and cannot be invoked as such.");
            }

#if !UNITY_EDITOR && ENABLE_IL2CPP
            if (genericTypes.Any((Type x) => x.IsValueType))
            {
                throw new NotSupportedException("Value types in generic commands are not currently supported by Unity in IL2CPP");
            }
#endif

            object[] parsedCommandParams = ParseParamData(command.MakeGenericArguments(genericTypes), commandParams);
            return(command.Invoke(parsedCommandParams, genericTypes));
        }