Beispiel #1
0
        /// <summary>
        /// Sends the specified <see cref="WatchoutCommand" /> asynchronously while waiting for a response.
        /// </summary>
        /// <typeparam name="T">The <see cref="WatchoutFeedback" /> type.</typeparam>
        /// <param name="command">The command.</param>
        /// <returns>
        /// Returns the proper feedback.
        /// </returns>
        public async Task <T> SendCommand <T>(WatchoutCommand command) where T : WatchoutFeedback
        {
            Task <T> task = new Task <T>(() =>
            {
                SendCommand(command);

                DateTime sentDate = DateTime.Now;

                while (!_availableFeedbacks.Exists(x => x.ID == command.ID) && DateTime.Now < sentDate.AddSeconds(CommandsTimeout))
                {
                    Thread.Sleep(30);
                }

                var feedback = _availableFeedbacks.SingleOrDefault(x => x.ID == command.ID) as T;

                if (feedback == null)
                {
                    WatchoutFeedback falseInstnce = Activator.CreateInstance <T>();
                    falseInstnce.CommandName      = command.Name;
                    falseInstnce.ID    = command.ID;
                    falseInstnce.Error = new ErrorFeedback()
                    {
                        ErrorKind = ErrorKind.NETWORK_ERRORS, Explanation = "Could not contact the Watchout server."
                    };
                    return(falseInstnce as T);
                }
                else
                {
                    feedback.CommandName = command.Name;
                }

                _availableFeedbacks.Remove(feedback);

                if (feedback.GetType() == typeof(ErrorFeedback))
                {
                    WatchoutFeedback falseInstnce = Activator.CreateInstance <T>();
                    falseInstnce.ID    = feedback.ID;
                    falseInstnce.Error = feedback as ErrorFeedback;
                    return(falseInstnce as T);
                }

                return(feedback);
            });

            task.Start();
            await task;

            return(task.Result);
        }
        /// <summary>
        /// Deserializes the specified response string and returns the proper <see cref="WatchoutFeedback"/>.
        /// </summary>
        /// <param name="response">The response string.</param>
        /// <returns>Returns the proper <see cref="WatchoutFeedback"/>.</returns>
        public static WatchoutFeedback Deserialize(String response)
        {
            response = RemoveCarriageReturn(response);

            var feedbackTypes = Assembly.GetAssembly(typeof(CommandFormatter)).GetTypes().Where(t => t != typeof(WatchoutFeedback) && typeof(WatchoutFeedback).IsAssignableFrom(t));

            List <String> parameters = Regex.Matches(response, @"[\""].+?[\""]|[^ ]+")
                                       .Cast <Match>()
                                       .Select(m => m.Value)
                                       .ToList();

            String commandName = parameters.FirstOrDefault();

            if (parameters.Count == 1 && commandName.Contains("["))
            {
                return(new WatchoutFeedback()
                {
                    ID = commandName.Replace("[", "").Replace("]", "")
                });
            }

            parameters.RemoveAt(0);

            String commandId = null;

            if (commandName.Contains("["))
            {
                commandName = commandName.Remove(0, 1);

                String[] commandAndID = commandName.Split(']');
                commandId   = commandAndID[0];
                commandName = commandAndID[1];
            }

            foreach (var type in feedbackTypes)
            {
                String fName = type.GetAttributeValue((FeedbackNameAttribute att) => att.Name);

                if (fName == commandName)
                {
                    WatchoutFeedback feedback = Activator.CreateInstance(type) as WatchoutFeedback;
                    feedback.ID = commandId;

                    var props = type.GetProperties().Where(pi => !pi.GetCustomAttributes(typeof(WatchoutIgnoreAttribute), true).Any()).ToList();

                    for (int i = 0; i < parameters.Count; i++)
                    {
                        if (i > props.Count - 1)
                        {
                            break;
                        }

                        var prop = props[i];

                        if (prop.PropertyType == typeof(String))
                        {
                            prop.SetValue(feedback, Convert.ChangeType(parameters[i].Replace("\"", ""), prop.PropertyType));
                        }
                        else if (prop.PropertyType == typeof(TimeSpan))
                        {
                            prop.SetValue(feedback, TimeSpan.FromMilliseconds(Convert.ToInt32(parameters[i])));
                        }
                        else if (prop.PropertyType.IsEnum)
                        {
                            int number = -1;
                            if (int.TryParse(parameters[i], out number))
                            {
                                prop.SetValue(feedback, Convert.ChangeType(Enum.ToObject(prop.PropertyType, number), prop.PropertyType));
                            }
                        }
                        else
                        {
                            prop.SetValue(feedback, Convert.ChangeType(parameters[i], prop.PropertyType));
                        }
                    }

                    return(feedback);
                }
            }

            Debug.WriteLine("Unrecognized feedback received. " + response);
            return(null);
            //throw new UnrecognizedFeedbackException("Unrecognized feedback received. " + response);
        }