public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var result = new ZoneProgramInput();

            // Deserialize into a temporary JObject
            JObject obj = serializer.Deserialize <JObject>(reader);

            // Populate the ZoneProgramInput object with the contents
            serializer.Populate(obj.CreateReader(), result);

            // Overwrite the "Value" property with the correct value based on the
            // "Type" property.
            result.SetValue(obj.GetValue("value", StringComparison.OrdinalIgnoreCase)
                            .ToObject(result.Type, serializer));

            return(result);
        }
Exemple #2
0
        /// <summary>
        /// Adds a live input as a direct map to a member of the subclass. This essentially extends a property in
        /// the subclass as an input, which can be set to any value by the user.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="instance"></param>
        /// <param name="propertyName"></param>
        /// <param name="filterPredicate">The incoming value will be run through this filter predicate function and only set the value if the function returns true.</param>
        /// <returns></returns>
        protected ZoneProgramInput AddMappedInput <T>(object instance, string propertyName, Func <T, bool> filterPredicate = null)
        {
            var propertyInfo = instance.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            var input        = new ZoneProgramInput(propertyInfo.Name, propertyInfo.PropertyType);

            Inputs.Add(input);
            if (filterPredicate != null)
            {
                input.Subscribe(incomingValue =>
                {
                    if (filterPredicate(ConvertIncomingValue <T>(incomingValue)))
                    {
                        propertyInfo.SetValue(instance, incomingValue);
                    }
                    else
                    {
                        throw new WarningException("Incoming value out of range of valid input values.");
                    }
                });
            }
            else
            {
                input.Subscribe(incomingValue =>
                {
                    if (propertyInfo.CanWrite)
                    {
                        propertyInfo.SetValue(instance, ConvertIncomingValue <T>(incomingValue));
                    }
                    else
                    {
                        throw new InvalidOperationException(
                            $"Input {input.Name} has an underlying property without an accessible setter. Cannot set value for this property.");
                    }
                });
            }

            //set value of input to the value of the property
            input.SetValue(propertyInfo.GetValue(instance));

            return(input);
        }