80 lines
No EOL
2.6 KiB
C#
80 lines
No EOL
2.6 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
|
|
namespace JD.Serialization
|
|
{
|
|
/// <summary>
|
|
/// Holds the curves of a clip.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Initialize itself using the reflection. Parses all the properties declared with a <see cref="BezierCurveTypeAttribute"/> and adds them to the editable list.
|
|
/// </remarks>
|
|
public class CurveCollection : UAFList<BezierCurveFloat>
|
|
{
|
|
private readonly Clip _clip;
|
|
|
|
public CurveCollection(Clip clip)
|
|
{
|
|
_clip = clip;
|
|
_clip.PropertyChanged += clip_PropertyChanged;
|
|
InitializeCurves();
|
|
}
|
|
|
|
public BezierCurveFloat this[BezierCurveType curveType]
|
|
{
|
|
get
|
|
{
|
|
return Items.FirstOrDefault(x => x.Type == curveType);
|
|
}
|
|
}
|
|
|
|
#region Curve Initialization With Reflection
|
|
|
|
/// <summary>
|
|
/// Cache the curve properties, calling the reflection can be long.
|
|
/// </summary>
|
|
private static readonly ConcurrentDictionary<Type, List<PropertyInfo>> _curvesProperties = new ConcurrentDictionary<Type, List<PropertyInfo>>();
|
|
|
|
private void InitializeCurves()
|
|
{
|
|
foreach (var property in GetCurveProperties())
|
|
{
|
|
var curve = (BezierCurveFloat)property.GetValue(_clip, null);
|
|
curve.Type = GetCurveType(property).Value;
|
|
curve.Clip = _clip;
|
|
Add(curve);
|
|
}
|
|
}
|
|
|
|
private IEnumerable<PropertyInfo> GetCurveProperties()
|
|
{
|
|
return _curvesProperties.GetOrAdd(_clip.GetType(), x =>
|
|
{
|
|
return _clip.GetType().GetProperties().Where(property => GetCurveType(property) != null).ToList();
|
|
});
|
|
}
|
|
|
|
private BezierCurveType? GetCurveType(PropertyInfo property)
|
|
{
|
|
var attributes = property.GetCustomAttributes(typeof(BezierCurveTypeAttribute), true);
|
|
return attributes.Length > 0 ? ((BezierCurveTypeAttribute)attributes[0]).Type : (BezierCurveType?)null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// When a curve is reassigned, update the curve collection.
|
|
/// </summary>
|
|
void clip_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
|
{
|
|
if (!string.IsNullOrEmpty(e.PropertyName) && GetCurveProperties().Any(property => property.Name == e.PropertyName))
|
|
{
|
|
Clear();
|
|
InitializeCurves();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |