From 33580aaaac12ce4a7f352da1638a2dd854f7bcf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Garc=C3=ADa?= Date: Wed, 30 Jul 2025 13:24:43 -0500 Subject: [PATCH] Removed boxing in TweenMemberss getters and setters (#1002) * Removed boxing in TweenMemberss getters and setters * Removed unnecessary inclusions and comments * Simplified the get method creation on @AristurtleDev 's suggestion --- .../Tweening/TweenFieldMember.cs | 34 ++++++++++--------- .../MonoGame.Extended/Tweening/TweenMember.cs | 8 ++--- .../Tweening/TweenPropertyMember.cs | 34 +++++++++++-------- 3 files changed, 41 insertions(+), 35 deletions(-) diff --git a/source/MonoGame.Extended/Tweening/TweenFieldMember.cs b/source/MonoGame.Extended/Tweening/TweenFieldMember.cs index da2f75d4..aae418f7 100644 --- a/source/MonoGame.Extended/Tweening/TweenFieldMember.cs +++ b/source/MonoGame.Extended/Tweening/TweenFieldMember.cs @@ -2,43 +2,45 @@ using System; using System.Diagnostics; using System.Linq.Expressions; using System.Reflection; +using Microsoft.VisualBasic; namespace MonoGame.Extended.Tweening { public sealed class TweenFieldMember : TweenMember - where T : struct + where T : struct { private readonly FieldInfo _fieldInfo; - public TweenFieldMember(object target, FieldInfo fieldInfo) + public TweenFieldMember(object target, FieldInfo fieldInfo) : base(target, CompileGetMethod(fieldInfo), CompileSetMethod(fieldInfo)) { _fieldInfo = fieldInfo; } - private static Func CompileGetMethod(FieldInfo fieldInfo) + private static Func CompileGetMethod(FieldInfo fieldInfo) { - var self = Expression.Parameter(typeof(object)); - var instance = Expression.Convert(self, fieldInfo.DeclaringType); - var field = Expression.Field(instance, fieldInfo); - var convert = Expression.TypeAs(field, typeof(object)); - - return Expression.Lambda>(convert, self).Compile(); + var entityType = fieldInfo.DeclaringType!; + var parameter = Expression.Parameter(typeof(object), "entity"); + var property = Expression.Field(Expression.Convert(parameter, entityType), fieldInfo); + return Expression.Lambda>(property, parameter).Compile(); } - private static Action CompileSetMethod(FieldInfo fieldInfo) + private static Action CompileSetMethod(FieldInfo fieldInfo) { Debug.Assert(fieldInfo.DeclaringType != null); - var self = Expression.Parameter(typeof(object)); - var value = Expression.Parameter(typeof(object)); - var fieldExp = Expression.Field(Expression.Convert(self, fieldInfo.DeclaringType), fieldInfo); - var assignExp = Expression.Assign(fieldExp, Expression.Convert(value, fieldInfo.FieldType)); + var entityType = fieldInfo.DeclaringType!; + var targetParam = Expression.Parameter(typeof(object), "target"); + var valueParam = Expression.Parameter(typeof(T), "value"); + var conversion = Expression.Convert(targetParam, entityType); - return Expression.Lambda>(assignExp, self, value).Compile(); + var field = Expression.Field(conversion, fieldInfo); + var assignation = Expression.Assign(field, valueParam); + + return Expression.Lambda>(assignation, targetParam, valueParam).Compile(); } public override Type Type => _fieldInfo.FieldType; public override string Name => _fieldInfo.Name; } -} \ No newline at end of file +} diff --git a/source/MonoGame.Extended/Tweening/TweenMember.cs b/source/MonoGame.Extended/Tweening/TweenMember.cs index adcee598..ab97c559 100644 --- a/source/MonoGame.Extended/Tweening/TweenMember.cs +++ b/source/MonoGame.Extended/Tweening/TweenMember.cs @@ -18,19 +18,19 @@ namespace MonoGame.Extended.Tweening public abstract class TweenMember : TweenMember where T : struct { - protected TweenMember(object target, Func getMethod, Action setMethod) + protected TweenMember(object target, Func getMethod, Action setMethod) : base(target) { _getMethod = getMethod; _setMethod = setMethod; } - private readonly Func _getMethod; - private readonly Action _setMethod; + private readonly Func _getMethod; + private readonly Action _setMethod; public T Value { - get { return (T) _getMethod(Target); } + get { return _getMethod(Target); } set { _setMethod(Target, value); } } } diff --git a/source/MonoGame.Extended/Tweening/TweenPropertyMember.cs b/source/MonoGame.Extended/Tweening/TweenPropertyMember.cs index 7b1db718..f196a5c9 100644 --- a/source/MonoGame.Extended/Tweening/TweenPropertyMember.cs +++ b/source/MonoGame.Extended/Tweening/TweenPropertyMember.cs @@ -6,7 +6,7 @@ using System.Reflection; namespace MonoGame.Extended.Tweening { public sealed class TweenPropertyMember : TweenMember - where T : struct + where T : struct { private readonly PropertyInfo _propertyInfo; @@ -19,25 +19,29 @@ namespace MonoGame.Extended.Tweening public override Type Type => _propertyInfo.PropertyType; public override string Name => _propertyInfo.Name; - private static Func CompileGetMethod(PropertyInfo propertyInfo) + //TODO: Try to further optimize this. For example, it needs to do all this reflection compilation shenanigan every time. + //Could we cache these instead? + + private static Func CompileGetMethod(PropertyInfo propertyInfo) { - var param = Expression.Parameter(typeof(object)); - var instance = Expression.Convert(param, propertyInfo.DeclaringType); - var convert = Expression.TypeAs(Expression.Property(instance, propertyInfo), typeof(object)); - return Expression.Lambda>(convert, param).Compile(); + var entityType = propertyInfo.DeclaringType!; + var parameter = Expression.Parameter(typeof(object), "entity"); + var property = Expression.Property(Expression.Convert(parameter, entityType), propertyInfo); + return Expression.Lambda>(property, parameter).Compile(); } - private static Action CompileSetMethod(PropertyInfo propertyInfo) + private static Action CompileSetMethod(PropertyInfo propertyInfo) { Debug.Assert(propertyInfo.DeclaringType != null); - var param = Expression.Parameter(typeof(object)); - var argument = Expression.Parameter(typeof(object)); - var expression = Expression.Convert(param, propertyInfo.DeclaringType); - var methodInfo = propertyInfo.SetMethod; - var arguments = Expression.Convert(argument, propertyInfo.PropertyType); - var setterCall = Expression.Call(expression, methodInfo, arguments); - return Expression.Lambda>(setterCall, param, argument).Compile(); + var entityType = propertyInfo.DeclaringType!; + var targetParam = Expression.Parameter(typeof(object), "target"); + var valueParam = Expression.Parameter(typeof(T), "value"); + var conversion = Expression.Convert(targetParam, entityType); + var methodInfo = propertyInfo.SetMethod!; + var set = Expression.Call(conversion, methodInfo, valueParam); + + return Expression.Lambda>(set, targetParam, valueParam).Compile(); } } -} \ No newline at end of file +}