Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
2.6KB

  1. using System;
  2. using System.Reflection;
  3. using System.Reflection.Emit;
  4. using System.Linq.Expressions;
  5. namespace Svelto.Utilities
  6. {
  7. //https://stackoverflow.com/questions/321650/how-do-i-set-a-field-value-in-an-c-sharp-expression-tree/321686#321686
  8. public static class FastInvoke<T> where T : class
  9. {
  10. #if ENABLE_IL2CPP
  11. public static Action<CastedType, object> MakeSetter<CastedType>(FieldInfo field)
  12. {
  13. if (field.FieldType.IsInterface == true && field.FieldType.IsValueType == false)
  14. {
  15. return new Action<CastedType, object>((target, value) => field.SetValue(target, value));
  16. }
  17. throw new ArgumentException("<color=orange>Svelto.ECS</color> unsupported EntityView field (must be an interface and a class)");
  18. }
  19. #elif !NETFX_CORE
  20. public static Action<CastedType, object> MakeSetter<CastedType>(FieldInfo field)
  21. {
  22. if (field.FieldType.IsInterfaceEx() == true && field.FieldType.IsValueTypeEx() == false)
  23. {
  24. DynamicMethod m = new DynamicMethod("setter", typeof(void), new Type[] { typeof(T), typeof(object) });
  25. ILGenerator cg = m.GetILGenerator();
  26. // arg0.<field> = arg1
  27. cg.Emit(OpCodes.Ldarg_0);
  28. cg.Emit(OpCodes.Ldarg_1);
  29. cg.Emit(OpCodes.Stfld, field);
  30. cg.Emit(OpCodes.Ret);
  31. return new Action<CastedType, object>((target, value) => m.CreateDelegate(typeof(Action<T, object>)).DynamicInvoke(target, value));
  32. }
  33. throw new ArgumentException("<color=orange>Svelto.ECS</color> unsupported EntityView field (must be an interface and a class)");
  34. }
  35. #else
  36. public static Action<CastedType, object> MakeSetter<CastedType>(FieldInfo field)
  37. {
  38. if (field.FieldType.IsInterfaceEx() == true && field.FieldType.IsValueTypeEx() == false)
  39. {
  40. ParameterExpression targetExp = Expression.Parameter(typeof(T), "target");
  41. ParameterExpression valueExp = Expression.Parameter(field.FieldType, "value");
  42. MemberExpression fieldExp = Expression.Field(targetExp, field);
  43. BinaryExpression assignExp = Expression.Assign(fieldExp, valueExp);
  44. var setter = Expression.Lambda(assignExp, targetExp, valueExp).Compile();
  45. return new Action<CastedType, object>((target, value) => setter.DynamicInvoke(target, value));
  46. }
  47. throw new ArgumentException("<color=orange>Svelto.ECS</color> unsupported EntityView field (must be an interface and a class)");
  48. }
  49. #endif
  50. }
  51. }