Skip to content

Commit

Permalink
Merge pull request #1750 from glopesdev/cache-reset-combinator
Browse files Browse the repository at this point in the history
Avoid rebuilding combinator reset delegate
  • Loading branch information
glopesdev authored Apr 23, 2024
2 parents bbfe0cf + 7b757bb commit 9357b9e
Showing 1 changed file with 43 additions and 25 deletions.
68 changes: 43 additions & 25 deletions Bonsai.Core/Expressions/CombinatorBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ void UpdateArgumentRange()
else
{
var combinatorType = combinator.GetType();
resetCombinator = BuildResetCombinator(combinatorType);
resetCombinator = GetResetCombinatorAction(combinatorType);
var processMethodParameters = GetProcessMethods(combinatorType).Select(m => m.GetParameters()).ToArray();
var paramArray = processMethodParameters.Any(p =>
p.Length >= 1 &&
Expand All @@ -75,39 +75,57 @@ void UpdateArgumentRange()
}
}

static Delegate BuildResetCombinator(Type combinatorType)
static Delegate GetResetCombinatorAction(Type combinatorType)
{
if (!combinatorType.IsDefined(typeof(ResetCombinatorAttribute)))
{
return null;
}

List<PropertyInfo> resetProperties = null;
var combinatorProperties = combinatorType.GetProperties();
for (int i = 0; i < combinatorProperties.Length; i++)
{
var property = combinatorProperties[i];
if (!property.CanWrite || !Attribute.IsDefined(property, typeof(XmlIgnoreAttribute))) continue;
var resetCombinatorType = typeof(ResetCombinator<>).MakeGenericType(combinatorType);
return ((ResetCombinator)Activator.CreateInstance(resetCombinatorType)).Action;
}

var proxyProperty = Array.Find(combinatorProperties, p =>
{
var xmlElement = p.GetCustomAttribute<XmlElementAttribute>();
return xmlElement != null && xmlElement.ElementName == property.Name;
});
if (proxyProperty == null)
abstract class ResetCombinator
{
public abstract Delegate Action { get; }
}

class ResetCombinator<T> : ResetCombinator
{
static readonly Delegate Instance = BuildResetCombinator(typeof(T));

public override Delegate Action => Instance;

static Delegate BuildResetCombinator(Type combinatorType)
{
List<PropertyInfo> resetProperties = null;
var combinatorProperties = combinatorType.GetProperties();
for (int i = 0; i < combinatorProperties.Length; i++)
{
if (resetProperties == null) resetProperties = new List<PropertyInfo>();
resetProperties.Add(property);
var property = combinatorProperties[i];
if (!property.CanWrite || !Attribute.IsDefined(property, typeof(XmlIgnoreAttribute))) continue;

var proxyProperty = Array.Find(combinatorProperties, p =>
{
var xmlElement = p.GetCustomAttribute<XmlElementAttribute>();
return xmlElement != null && xmlElement.ElementName == property.Name;
});
if (proxyProperty == null)
{
resetProperties ??= new List<PropertyInfo>();
resetProperties.Add(property);
}
}
}

if (resetProperties == null) return null;
var combinator = Expression.Parameter(combinatorType);
return Expression.Lambda(Expression.Block(resetProperties.Select(property =>
{
var propertyExpression = Expression.Property(combinator, property);
return Expression.Assign(propertyExpression, Expression.Default(property.PropertyType));
})), combinator).Compile();
if (resetProperties == null) return null;
var combinator = Expression.Parameter(combinatorType);
return Expression.Lambda(Expression.Block(resetProperties.Select(property =>
{
var propertyExpression = Expression.Property(combinator, property);
return Expression.Assign(propertyExpression, Expression.Default(property.PropertyType));
})), combinator).Compile();
}
}

static IEnumerable<MethodInfo> GetProcessMethods(Type combinatorType)
Expand Down Expand Up @@ -150,7 +168,7 @@ protected override Expression BuildCombinator(IEnumerable<Expression> arguments)
{
var combinatorExpression = Expression.Constant(combinator);
var processMethods = GetProcessMethods(combinatorExpression.Type);
if (resetCombinator != null) resetCombinator.DynamicInvoke(combinator);
resetCombinator?.DynamicInvoke(combinator);
return BuildCall(combinatorExpression, processMethods, arguments.Take(maxArgumentCount).ToArray());
}
}
Expand Down

0 comments on commit 9357b9e

Please sign in to comment.