TweenFieldMember.cs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. using System;
  2. using System.Diagnostics;
  3. using System.Linq.Expressions;
  4. using System.Reflection;
  5. using Microsoft.VisualBasic;
  6. namespace MonoGame.Extended.Tweening
  7. {
  8. public sealed class TweenFieldMember<T> : TweenMember<T>
  9. where T : struct
  10. {
  11. private readonly FieldInfo _fieldInfo;
  12. public TweenFieldMember(object target, FieldInfo fieldInfo)
  13. : base(target, CompileGetMethod(fieldInfo), CompileSetMethod(fieldInfo))
  14. {
  15. _fieldInfo = fieldInfo;
  16. }
  17. private static Func<object, T> CompileGetMethod(FieldInfo fieldInfo)
  18. {
  19. var entityType = fieldInfo.DeclaringType!;
  20. var parameter = Expression.Parameter(typeof(object), "entity");
  21. var property = Expression.Field(Expression.Convert(parameter, entityType), fieldInfo);
  22. return Expression.Lambda<Func<object, T>>(property, parameter).Compile();
  23. }
  24. private static Action<object, T> CompileSetMethod(FieldInfo fieldInfo)
  25. {
  26. Debug.Assert(fieldInfo.DeclaringType != null);
  27. var entityType = fieldInfo.DeclaringType!;
  28. var targetParam = Expression.Parameter(typeof(object), "target");
  29. var valueParam = Expression.Parameter(typeof(T), "value");
  30. var conversion = Expression.Convert(targetParam, entityType);
  31. var field = Expression.Field(conversion, fieldInfo);
  32. var assignation = Expression.Assign(field, valueParam);
  33. return Expression.Lambda<Action<object, T>>(assignation, targetParam, valueParam).Compile();
  34. }
  35. public override Type Type => _fieldInfo.FieldType;
  36. public override string Name => _fieldInfo.Name;
  37. }
  38. }