Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Evaluate() method to expression nodes #4559

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -263,5 +263,46 @@ private static ExpressionAnimation CreateExpressionAnimationFromNode(Compositor

return expressionNode.ExpressionAnimation;
}

internal static float EvaluateSubchannel(this ExpressionNode node, string subchannel) => (node, subchannel) switch
{
(Vector2Node n, "X") => n.Evaluate().X,
(Vector2Node n, "Y") => n.Evaluate().Y,

(Vector3Node n, "X") => n.Evaluate().X,
(Vector3Node n, "Y") => n.Evaluate().Y,
(Vector3Node n, "Z") => n.Evaluate().Z,

(Vector4Node n, "X") => n.Evaluate().X,
(Vector4Node n, "Y") => n.Evaluate().Y,
(Vector4Node n, "Z") => n.Evaluate().Z,
(Vector4Node n, "W") => n.Evaluate().W,

(Matrix3x2Node n, "Channel11") => n.Evaluate().M11,
(Matrix3x2Node n, "Channel12") => n.Evaluate().M12,
(Matrix3x2Node n, "Channel21") => n.Evaluate().M21,
(Matrix3x2Node n, "Channel22") => n.Evaluate().M22,
(Matrix3x2Node n, "Channel31") => n.Evaluate().M31,
(Matrix3x2Node n, "Channel32") => n.Evaluate().M32,

(Matrix4x4Node n, "Channel11") => n.Evaluate().M11,
(Matrix4x4Node n, "Channel12") => n.Evaluate().M12,
(Matrix4x4Node n, "Channel13") => n.Evaluate().M13,
(Matrix4x4Node n, "Channel14") => n.Evaluate().M14,
(Matrix4x4Node n, "Channel21") => n.Evaluate().M21,
(Matrix4x4Node n, "Channel22") => n.Evaluate().M22,
(Matrix4x4Node n, "Channel23") => n.Evaluate().M23,
(Matrix4x4Node n, "Channel24") => n.Evaluate().M24,
(Matrix4x4Node n, "Channel31") => n.Evaluate().M31,
(Matrix4x4Node n, "Channel32") => n.Evaluate().M32,
(Matrix4x4Node n, "Channel33") => n.Evaluate().M33,
(Matrix4x4Node n, "Channel34") => n.Evaluate().M34,
(Matrix4x4Node n, "Channel41") => n.Evaluate().M41,
(Matrix4x4Node n, "Channel42") => n.Evaluate().M42,
(Matrix4x4Node n, "Channel43") => n.Evaluate().M43,
(Matrix4x4Node n, "Channel44") => n.Evaluate().M44,

_ => 0
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;

namespace Microsoft.Toolkit.Uwp.UI.Animations.Expressions
{
// Ignore warning: 'BooleanNode' defines operator == or operator != but does not override Object.Equals(object o) && Object.GetHashCode()
Expand Down Expand Up @@ -127,6 +129,67 @@ protected internal override string GetValue()
}

private bool _value;

/// <summary>
/// Evaluates the current value of the expression
/// </summary>
/// <returns>The current value of the expression</returns>
public bool Evaluate()
{
switch (NodeType)
{
case ExpressionNodeType.ConstantValue:
return _value;
case ExpressionNodeType.Equals:
return Equals(Children[0], Children[1]);
case ExpressionNodeType.NotEquals:
return !Equals(Children[0], Children[1]);
case ExpressionNodeType.And:
return (Children[0] as BooleanNode).Evaluate() && (Children[1] as BooleanNode).Evaluate();
case ExpressionNodeType.Or:
return (Children[0] as BooleanNode).Evaluate() || (Children[1] as BooleanNode).Evaluate();
case ExpressionNodeType.LessThan:
return (Children[0] as ScalarNode).Evaluate() < (Children[1] as ScalarNode).Evaluate();
case ExpressionNodeType.LessThanEquals:
return (Children[0] as ScalarNode).Evaluate() <= (Children[1] as ScalarNode).Evaluate();
case ExpressionNodeType.GreaterThan:
return (Children[0] as ScalarNode).Evaluate() > (Children[1] as ScalarNode).Evaluate();
case ExpressionNodeType.GreaterThanEquals:
return (Children[0] as ScalarNode).Evaluate() >= (Children[1] as ScalarNode).Evaluate();
case ExpressionNodeType.Not:
return !(Children[0] as BooleanNode).Evaluate();
case ExpressionNodeType.ReferenceProperty:
var reference = (Children[0] as ReferenceNode).Reference;
switch (PropertyName)
{
default:
reference.Properties.TryGetBoolean(PropertyName, out var referencedProperty);
return referencedProperty;
}

case ExpressionNodeType.Conditional:
return
(Children[0] as BooleanNode).Evaluate() ?
(Children[1] as BooleanNode).Evaluate() :
(Children[2] as BooleanNode).Evaluate();
default:
throw new NotImplementedException();
}

bool Equals(ExpressionNode e1, ExpressionNode e2) => (e1, e2) switch
{
(BooleanNode n1, BooleanNode n2) => n1.Evaluate() == n2.Evaluate(),
(ScalarNode n1, ScalarNode n2) => n1.Evaluate() == n2.Evaluate(),
(Vector2Node n1, Vector2Node n2) => n1.Evaluate() == n2.Evaluate(),
(Vector3Node n1, Vector3Node n2) => n1.Evaluate() == n2.Evaluate(),
(Vector4Node n1, Vector4Node n2) => n1.Evaluate() == n2.Evaluate(),
(ColorNode n1, ColorNode n2) => n1.Evaluate() == n2.Evaluate(),
(QuaternionNode n1, QuaternionNode n2) => n1.Evaluate() == n2.Evaluate(),
(Matrix3x2Node n1, Matrix3x2Node n2) => n1.Evaluate() == n2.Evaluate(),
(Matrix4x4Node n1, Matrix4x4Node n2) => n1.Evaluate() == n2.Evaluate(),
_ => false
};
}
}
#pragma warning restore CS0660, CS0661
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using Windows.UI;
using Windows.UI.Composition;

namespace Microsoft.Toolkit.Uwp.UI.Animations.Expressions
{
Expand Down Expand Up @@ -97,6 +99,40 @@ protected internal override string GetValue()
}

private Color _value;

/// <summary>
/// Evaluates the current value of the expression
/// </summary>
/// <returns>The current value of the expression</returns>
public Color Evaluate()
{
switch (NodeType)
{
case ExpressionNodeType.ConstantValue:
return _value;
case ExpressionNodeType.ReferenceProperty:
var reference = (Children[0] as ReferenceNode).Reference;
return PropertyName switch
{
nameof(CompositionColorBrush.Color) => (reference as CompositionColorBrush).Color,
_ => GetProperty()
};

Color GetProperty()
{
reference.Properties.TryGetColor(PropertyName, out var value);
return value;
}

case ExpressionNodeType.Conditional:
return
(Children[0] as BooleanNode).Evaluate() ?
(Children[1] as ColorNode).Evaluate() :
(Children[2] as ColorNode).Evaluate();
default:
throw new NotImplementedException();
}
}
}
#pragma warning restore CS0660, CS0661
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Numerics;

namespace Microsoft.Toolkit.Uwp.UI.Animations.Expressions
Expand Down Expand Up @@ -336,6 +337,57 @@ protected internal override string GetValue()
}

private Matrix3x2 _value;

/// <summary>
/// Evaluates the current value of the expression
/// </summary>
/// <returns>The current value of the expression</returns>
public Matrix3x2 Evaluate()
{
switch (NodeType)
{
case ExpressionNodeType.ConstantValue:
return _value;
case ExpressionNodeType.ReferenceProperty:
var reference = (Children[0] as ReferenceNode).Reference;
reference.Properties.TryGetMatrix3x2(PropertyName, out var referencedProperty);
return referencedProperty;
case ExpressionNodeType.Add:
return
(Children[0] as Matrix3x2Node).Evaluate() +
(Children[1] as Matrix3x2Node).Evaluate();
case ExpressionNodeType.Subtract:
return
(Children[0] as Matrix3x2Node).Evaluate() -
(Children[1] as Matrix3x2Node).Evaluate();
case ExpressionNodeType.Negate:
return
-(Children[0] as Matrix3x2Node).Evaluate();
case ExpressionNodeType.Multiply:
return (Children[0], Children[1]) switch
{
(Matrix3x2Node v1, Matrix3x2Node v2) => v1.Evaluate() * v2.Evaluate(),
(Matrix3x2Node v1, ScalarNode s2) => v1.Evaluate() * s2.Evaluate(),
(ScalarNode s1, Matrix3x2Node v2) => v2.Evaluate() * s1.Evaluate(),
_ => throw new NotImplementedException()
};
case ExpressionNodeType.Conditional:
return
(Children[0] as BooleanNode).Evaluate() ?
(Children[1] as Matrix3x2Node).Evaluate() :
(Children[2] as Matrix3x2Node).Evaluate();
case ExpressionNodeType.Swizzle:
return new Matrix3x2(
Children[0].EvaluateSubchannel(Subchannels[0]),
Children[0].EvaluateSubchannel(Subchannels[1]),
Children[0].EvaluateSubchannel(Subchannels[2]),
Children[0].EvaluateSubchannel(Subchannels[3]),
Children[0].EvaluateSubchannel(Subchannels[4]),
Children[0].EvaluateSubchannel(Subchannels[5]));
default:
throw new NotImplementedException();
}
}
}
#pragma warning restore CS0660, CS0661
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Numerics;
using Windows.UI.Composition;

namespace Microsoft.Toolkit.Uwp.UI.Animations.Expressions
{
Expand Down Expand Up @@ -410,6 +412,77 @@ protected internal override string GetValue()
}

private Matrix4x4 _value;

/// <summary>
/// Evaluates the current value of the expression
/// </summary>
/// <returns>The current value of the expression</returns>
public Matrix4x4 Evaluate()
{
switch (NodeType)
{
case ExpressionNodeType.ConstantValue:
return _value;
case ExpressionNodeType.ReferenceProperty:
var reference = (Children[0] as ReferenceNode).Reference;
return PropertyName switch
{
nameof(Visual.TransformMatrix) => (reference as Visual).TransformMatrix,
_ => GetProperty()
};

Matrix4x4 GetProperty()
{
reference.Properties.TryGetMatrix4x4(PropertyName, out var value);
return value;
}

case ExpressionNodeType.Add:
return
(Children[0] as Matrix4x4Node).Evaluate() +
(Children[1] as Matrix4x4Node).Evaluate();
case ExpressionNodeType.Subtract:
return
(Children[0] as Matrix4x4Node).Evaluate() -
(Children[1] as Matrix4x4Node).Evaluate();
case ExpressionNodeType.Negate:
return
-(Children[0] as Matrix4x4Node).Evaluate();
case ExpressionNodeType.Multiply:
return (Children[0], Children[1]) switch
{
(Matrix4x4Node v1, Matrix4x4Node v2) => v1.Evaluate() * v2.Evaluate(),
(Matrix4x4Node v1, ScalarNode s2) => v1.Evaluate() * s2.Evaluate(),
(ScalarNode s1, Matrix4x4Node v2) => v2.Evaluate() * s1.Evaluate(),
_ => throw new NotImplementedException()
};
case ExpressionNodeType.Conditional:
return
(Children[0] as BooleanNode).Evaluate() ?
(Children[1] as Matrix4x4Node).Evaluate() :
(Children[2] as Matrix4x4Node).Evaluate();
case ExpressionNodeType.Swizzle:
return new Matrix4x4(
Children[0].EvaluateSubchannel(Subchannels[0]),
Children[0].EvaluateSubchannel(Subchannels[1]),
Children[0].EvaluateSubchannel(Subchannels[2]),
Children[0].EvaluateSubchannel(Subchannels[3]),
Children[0].EvaluateSubchannel(Subchannels[4]),
Children[0].EvaluateSubchannel(Subchannels[5]),
Children[0].EvaluateSubchannel(Subchannels[6]),
Children[0].EvaluateSubchannel(Subchannels[7]),
Children[0].EvaluateSubchannel(Subchannels[8]),
Children[0].EvaluateSubchannel(Subchannels[9]),
Children[0].EvaluateSubchannel(Subchannels[10]),
Children[0].EvaluateSubchannel(Subchannels[11]),
Children[0].EvaluateSubchannel(Subchannels[12]),
Children[0].EvaluateSubchannel(Subchannels[13]),
Children[0].EvaluateSubchannel(Subchannels[14]),
Children[0].EvaluateSubchannel(Subchannels[15]));
default:
throw new NotImplementedException();
}
}
}
#pragma warning restore CS0660, CS0661
}