示例#1
0
        /// <summary>
        /// crawls the given type for parameter converter methods
        /// </summary>
        /// <param name="type">the type to crawl</param>
        /// <param name="converters">the resulting converters</param>
        /// <param name="declaredConverters">the converters that are already known</param>
        /// <param name="methodInfos">the method infos</param>
        public static void CrawlConverterMethods(Type type, Dictionary <string, SpeechParameterConverter> converters,
                                                 Dictionary <string, SpeechParameterConverter> declaredConverters, params MethodInfo[] methodInfos)
        {
            foreach (var methodInfo in methodInfos)
            {
                var cattributes = methodInfo.GetCustomAttributes(typeof(SpeechParameterConverterAttribute), false);


                if (cattributes.Length > 0)
                {
                    IEnumerable <SpeechParameterConverterAttribute> speechMethodAttributes = cattributes.Cast <SpeechParameterConverterAttribute>();

                    //should be only one

                    var attrib = speechMethodAttributes.FirstOrDefault();

                    if (attrib == null)
                    {
                        throw new Exception("#0 unknown");
                    }
                    else
                    {
                        //check if its a valid method... 1 string argument, 1 return parameter

                        ParameterInfo[] parameters = methodInfo.GetParameters();

                        if (parameters.Length == 1 && parameters[0].ParameterType == typeof(string) && methodInfo.ReturnType != typeof(void))
                        {
                            var converter = new SpeechParameterConverter();
                            converter.Key           = attrib.Key;
                            converter.ExecutingType = type;
                            converter.MethodInfo    = methodInfo;


                            if (converters.ContainsKey(converter.Key) || declaredConverters.ContainsKey(converter.Key))
                            {
                                throw new Exception("the parameter converter method key: " + methodInfo.Name + " on type: " + type.FullName +
                                                    " is already used by another method");
                            }

                            converters.Add(converter.Key, converter);
                        }
                        else
                        {
                            throw new Exception("a parameter converter method must have 1 string parameter and returning the correct type for " +
                                                "the methods that use this converter (-> never void).\ntype: " + type.FullName + "method: " + methodInfo.Name);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// finishes the current parameter (assigns value) and if this was the last param then executes the current method
        /// </summary>
        /// <param name="valueText"></param>
        private bool FinishCurrentParameter(string valueText)
        {
            if (this.State == ExecutingState.ListeningForParameters)
            {
                //check the first left parameter
                //parameter name was left out

                int leftParameterIndex = -1;

                for (int i = 0; i < this.CurrentSpeechStream.SpeechTuple.Method.Arguments.Count; i++)
                {
                    var arg = this.CurrentSpeechStream.SpeechTuple.Method.Arguments[i];
                    if (
                        this.CurrentSpeechStream.SpeechParameterStreams.Any(
                            p => p.SpeechParameterInfo.Parameter.ParameterInfo.Name == arg.ParameterInfo.Name) == false)
                    {
                        leftParameterIndex = i;
                        break;
                    }
                }

                if (leftParameterIndex != -1)
                {
                    this.CurrentParameter = new SpeechParameterStream("", this.CurrentSpeechStream.SpeechTuple,
                                                                      new SpeechParameterInfo(this.CurrentSpeechStream.SpeechTuple.Method.Arguments[leftParameterIndex]));
                }
            }

            SpeechParameterConverter converter = this.CurrentParameter.SpeechParameterInfo.Parameter.Converter;


            object erg = null;//OnParameterValueConvert(this.CurrentParameter, valueText);

            if (converter == null)
            {
                throw new Exception("converter was not set so the parameter value: " + valueText + " for parameter " +
                                    this.CurrentParameter.RecognizedParameterNameText + "(real name: " + this.CurrentParameter.SpeechParameterInfo.Parameter.ParameterInfo.Name +
                                    ") couldnt be converted");
            }
            else
            {
                if (converter.MethodInfo.IsStatic == false && converter.InvokingInstance == null)
                {
                    try
                    {
                        converter.InvokingInstance = Activator.CreateInstance(converter.ExecutingType);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("tried to create an instance of " + converter.ExecutingType.FullName + " in order to convert the parameter " +
                                            this.CurrentParameter.RecognizedParameterNameText + "(real name: " + this.CurrentParameter.SpeechParameterInfo.Parameter.ParameterInfo.Name + ")" +
                                            "\nException: " + ex.Message);
                    }
                }

                erg = converter.MethodInfo.Invoke(converter.InvokingInstance, new object[] { valueText });
            }


            if (erg != null)
            {
                this.CurrentParameter.SpeechParameterInfo.Value = erg;


                if (this.State == ExecutingState.ListeningForParameters) //only add if the parameter name was left out
                {
                    this.CurrentSpeechStream.SpeechParameterStreams.Add(this.CurrentParameter);
                }

                this._OnParameterFinished.OnNext(this.CurrentParameter);
            }
            else
            {
                return(false);
            }



            //now check if this was the last parameter...
            if (this.CurrentSpeechStream.SpeechParameterStreams.Count == this.CurrentSpeechStream.SpeechTuple.Method.Arguments.Count)
            {
                //we have all parameters...
                if (this.CurrentSpeechStream.SpeechTuple.Method.MethodInfo.IsStatic == false)
                {
                    if (this.CurrentSpeechStream.SpeechTuple.InvokeInstance == null)
                    {
                        var obj = Activator.CreateInstance(this.CurrentSpeechStream.SpeechTuple.Method.ExecutingType);
                        this.CurrentSpeechStream.SpeechTuple.InvokeInstance = obj;
                    }
                }

                //reorder parameters to fit signature
                var values = new List <object>();
                foreach (var speechParameter in this.CurrentSpeechStream.SpeechTuple.Method.Arguments)
                {
                    SpeechParameterStream speechParameterInfo =
                        this.CurrentSpeechStream.SpeechParameterStreams.FirstOrDefault(
                            p => p.SpeechParameterInfo.Parameter.ParameterInfo.Name == speechParameter.ParameterInfo.Name);

                    if (speechParameterInfo != null)
                    {
                        values.Add(speechParameterInfo.SpeechParameterInfo.Value);
                    }
                    else
                    {
                        //TODO parameter has no value or parameter info ??
                    }
                }
                this._OnLastParameterFinished.OnNext(this.CurrentSpeechStream);

                //finally execute the method with the right parameter order
                ExecuteMethod(this.CurrentSpeechStream.SpeechTuple, this.CurrentSpeechStream.SpeechTuple.InvokeInstance, values.ToArray());

                this.AbortListeningForParameters();
                this.State = ExecutingState.ListeningForMethods;
            }
            else
            {
                this.State = ExecutingState.ListeningForParameters;
            }

            return(true);
        }