public static void Dispose(AvisynthFilter filter) { var props = GetAnnotatedProperties(filter.GetType()).Select(p => p.Item1) .Where(p => p.PropertyType == typeof(Clip) || p.PropertyType == typeof(Clip[])) .Select(p => { var val = p.GetGetMethod(true).Invoke(filter, null); p.GetSetMethod(true).Invoke(filter, new object[] { null }); return(val); }).ToArray(); props .OfType <Clip>().ToList() .ForEach(p => p?.Dispose()); props .OfType <Clip[]>().SelectMany(p => p).ToList() .ForEach(p => p?.Dispose()); }
public static void Dispose(AvisynthFilter filter) { GetAnnotatedProperties(filter.GetType()).Select(p => p.Item1).Where(p => p.PropertyType == typeof(Clip)) .Select(p => p.GetGetMethod(true).Invoke(filter, null)).OfType <Clip>().ToList() .ForEach(p => p.Dispose()); }
public static void InitArgs(AvisynthFilter filter, AVSValue args) { var annotatedProperties = GetAnnotatedProperties(filter.GetType()); if (annotatedProperties.Length != args.ArraySize() && annotatedProperties.Length != args.ArraySize() - 1) { throw new AvisynthException("Instance attributes count not match to declared"); } var zeroBased = annotatedProperties.Length == args.ArraySize(); var annotatedPropertiesWithArguments = annotatedProperties.Select((p, i) => new { Argument = args[zeroBased ? i : ++i], Property = p.Item1, Attribute = p.Item2 }); var filterName = filter.GetType().Assembly .GetCustomAttributes(typeof(AvisynthFilterClassAttribute), true) .OfType <AvisynthFilterClassAttribute>() .FirstOrDefault(p => p.FilterType == filter.GetType()) ?.FilterName ?? filter.GetType().Name; foreach (var tuple in annotatedPropertiesWithArguments) { var propertyName = $"{filterName}.{tuple.Property.Name}"; var isDefined = tuple.Argument.Defined(); if (tuple.Attribute.Required && !isDefined) { throw new AvisynthException($"{propertyName} is required but not defined"); } if (!isDefined) { continue; } var value = tuple.Argument.AsObject(); if (!tuple.Attribute.Min.Equals(double.MinValue) && Convert.ToDouble(value) < tuple.Attribute.Min) { throw new AvisynthException($"{propertyName} is equal to {value} but must be greater or equal to {tuple.Attribute.Min}"); } if (!tuple.Attribute.Max.Equals(double.MaxValue) && Convert.ToDouble(value) > tuple.Attribute.Max) { throw new AvisynthException($"{propertyName} is equal to {value} but must be less or equal to {tuple.Attribute.Max}"); } if (tuple.Property.PropertyType.IsEnum && value is string) { tuple.Attribute.Values = Enum.GetNames(tuple.Property.PropertyType); } if (tuple.Property.PropertyType.IsEnum && value is int) { tuple.Attribute.Values = Enum.GetValues(tuple.Property.PropertyType).Cast <object>().Select(p => Convert.ToInt32(p).ToString()).ToArray(); } if (tuple.Attribute.Values.Any() && tuple.Attribute.Values.Select(p => p.ToLower()).All(p => !p.Equals(value.ToString()))) { throw new AvisynthException($"{propertyName} is equal to '{value}' but allowed values are [{string.Join(", ", tuple.Attribute.Values)}]"); } if (tuple.Property.PropertyType.IsEnum && value is string) { value = Enum.Parse(tuple.Property.PropertyType, value.ToString(), true); } if (tuple.Property.PropertyType.IsEnum && value is int) { value = Enum.ToObject(tuple.Property.PropertyType, value); } tuple.Property.GetSetMethod(true).Invoke(filter, new[] { value }); } }
public static void InitArgs(AvisynthFilter filter, AVSValue args) { var annotatedProperties = GetAnnotatedProperties(filter.GetType()); if (annotatedProperties.Length != args.ArraySize() && annotatedProperties.Length != args.ArraySize() - 1) { throw new AvisynthException("Instance attributes count not match to declared"); } var zeroBased = annotatedProperties.Length == args.ArraySize(); var annotatedPropertiesWithArguments = annotatedProperties.Select((p, i) => new { Argument = args[zeroBased ? i : ++i], Property = p.Item1, Attribute = p.Item2 }); var filterName = filter.GetType().Assembly .GetCustomAttributes(typeof(AvisynthFilterClassAttribute), true) .OfType <AvisynthFilterClassAttribute>() .FirstOrDefault(p => p.FilterType == filter.GetType()) ?.FilterName ?? filter.GetType().Name; foreach (var tuple in annotatedPropertiesWithArguments) { var propertyName = $"{filterName}.{tuple.Property.Name}"; var isDefined = tuple.Argument.Defined(); if (tuple.Attribute.Required && !isDefined) { throw new AvisynthException($"{propertyName} is required but not defined"); } if (!isDefined) { continue; } var value = tuple.Argument.AsObject(); Func <int, Rectangle> readRect = i => { using var frame = ((Clip)value).GetFrame(i, DynamicEnvironment.Env); var rect = Rect.FromFrame(frame); return(Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom)); }; if (tuple.Property.PropertyType == typeof(Rectangle)) { tuple.Property.GetSetMethod(true).Invoke(filter, new object[] { readRect(0) }); continue; } if (typeof(ICollection <Rectangle>).IsAssignableFrom(tuple.Property.PropertyType)) { var col = (ICollection <Rectangle>)Activator.CreateInstance(tuple.Property.PropertyType); var clip = value as Clip; var numFrames = clip.GetVideoInfo().num_frames; if (numFrames > tuple.Attribute.Max) { throw new AvisynthException($"{propertyName} contains {value} values but limit is {tuple.Attribute.Max}"); } for (var i = 0; i < numFrames; i++) { col.Add(readRect(i)); } tuple.Property.GetSetMethod(true).Invoke(filter, new object[] { col }); continue; } if (!tuple.Attribute.Min.Equals(double.MinValue) && Convert.ToDouble(value) < tuple.Attribute.Min) { throw new AvisynthException($"{propertyName} is equal to {value} but must be greater or equal to {tuple.Attribute.Min}"); } if (!tuple.Attribute.Max.Equals(double.MaxValue) && Convert.ToDouble(value) > tuple.Attribute.Max) { throw new AvisynthException($"{propertyName} is equal to {value} but must be less or equal to {tuple.Attribute.Max}"); } if (tuple.Property.PropertyType.IsEnum && value is string) { tuple.Attribute.Values = Enum.GetNames(tuple.Property.PropertyType); } if (tuple.Property.PropertyType.IsEnum && value is int) { tuple.Attribute.Values = Enum.GetValues(tuple.Property.PropertyType).Cast <object>().Select(p => Convert.ToInt32(p).ToString()).ToArray(); } if (tuple.Attribute.Values.Any() && tuple.Attribute.Values.Select(p => p.ToLower()).All(p => !p.Equals(value.ToString()))) { throw new AvisynthException($"{propertyName} is equal to '{value}' but allowed values are [{string.Join(", ", tuple.Attribute.Values)}]"); } if (tuple.Property.PropertyType.IsEnum && value is string) { value = Enum.Parse(tuple.Property.PropertyType, value.ToString(), true); } if (tuple.Property.PropertyType.IsEnum && value is int) { value = Enum.ToObject(tuple.Property.PropertyType, value); } tuple.Property.GetSetMethod(true).Invoke(filter, new[] { value }); } }