Fix some missing simplifications in Composition expressions. (#429)
* Fix some missing simplifications in Composition expressions. The logic for determining whether an expression could be simplified was sometimes wrong because it ended up hitting an overridden equality operator which compared the already-simplified values. Also fixed the test script to look at last write time when determining which is the latest build of LottieGen.exe to run. We were looking at creation time, but it turns out that when the compiler builds, it doesn't cause the creation time to be updated if the output file previously existed. Our test script could accidentally use a release build when the latest build was actually a debug build, resulting in the test running on an old build. * Replace the IsAtomic bool with a more generalized Precedence concept. Without this, it was getting unwieldy to handle all the cases of precedence. Now we're removing parentheses more aggressively, so the expressions will be more efficient to parse. * Eliminate some unnecessary whitespace in Min and Max expression functions.
This commit is contained in:
Родитель
12fbb261dd
Коммит
11c75f8865
|
@ -31,8 +31,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
_text = text;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool IsAtomic => true;
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
// We don't actually know the operation count because the text could
|
||||
|
@ -78,9 +77,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
return new Literal(literalLeft.Value < literalRight.Value);
|
||||
}
|
||||
|
||||
return left != Left || right != Right
|
||||
? new LessThan(left, right)
|
||||
: this;
|
||||
return ReferenceEquals(left, Left) && ReferenceEquals(right, Right)
|
||||
? this
|
||||
: new LessThan(left, right);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@ -97,8 +96,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
Value = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool IsAtomic => true;
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int OperationsCount => 0;
|
||||
|
|
|
@ -25,8 +25,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
_text = text;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool IsAtomic => true;
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
// We don't actually know the operation count because the text could
|
||||
|
@ -58,8 +57,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
|
||||
public Scalar A { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool IsAtomic => true;
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int OperationsCount => R.OperationsCount + G.OperationsCount + B.OperationsCount + A.OperationsCount;
|
||||
|
@ -72,9 +70,13 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
var b = B.Simplified;
|
||||
var a = A.Simplified;
|
||||
|
||||
return r != R || g != G || b != B || a != A
|
||||
? new Constructed(r, g, b, a)
|
||||
: this;
|
||||
return
|
||||
ReferenceEquals(r, R) &&
|
||||
ReferenceEquals(g, G) &&
|
||||
ReferenceEquals(b, B) &&
|
||||
ReferenceEquals(a, A)
|
||||
? this
|
||||
: new Constructed(r, g, b, a);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
|
@ -71,10 +71,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
public abstract string ToText();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the string form of the expression can be unambigiously
|
||||
/// parsed without parentheses.
|
||||
/// Gets a value indicating the relative precedence of the string form of the expression.
|
||||
/// This is used to determine whether parentheses are necessary in order to
|
||||
/// override the left-to-right evaluation of the parent expression.
|
||||
/// </summary>
|
||||
protected virtual bool IsAtomic => false;
|
||||
internal virtual Precedence Precedence => Precedence.Unknown;
|
||||
|
||||
/// <summary>
|
||||
/// The number of operations in this <see cref="Expression"/>. An operation is something that
|
||||
|
@ -83,7 +84,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
public abstract int OperationsCount { get; }
|
||||
|
||||
protected static string Parenthesize(Expression expression)
|
||||
=> expression.IsAtomic
|
||||
=> expression.Precedence == Precedence.Atomic
|
||||
? expression.ToText()
|
||||
: $"({expression.ToText()})";
|
||||
|
||||
|
|
|
@ -57,8 +57,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
_text = text;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool IsAtomic => true;
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
// We don't actually know the operation count because the text could
|
||||
|
@ -108,18 +107,18 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
var m32 = _32.Simplified;
|
||||
|
||||
return
|
||||
m11 != _11 || m12 != _12 ||
|
||||
m21 != _21 || m22 != _22 ||
|
||||
m31 != _31 || m32 != _32
|
||||
? new Constructed(m11, m12, m21, m22, m31, m32)
|
||||
: this;
|
||||
ReferenceEquals(m11, _11) && ReferenceEquals(m12, _12) &&
|
||||
ReferenceEquals(m21, _21) && ReferenceEquals(m22, _22) &&
|
||||
ReferenceEquals(m31, _31) && ReferenceEquals(m32, _32)
|
||||
? this
|
||||
: new Constructed(m11, m12, m21, m22, m31, m32);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
=> $"Matrix3x2({Parenthesize(_11)},{Parenthesize(_12)},{Parenthesize(_21)},{Parenthesize(_22)},{Parenthesize(_31)},{Parenthesize(_32)})";
|
||||
|
||||
protected override bool IsAtomic => true;
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
}
|
||||
|
||||
Scalar Channel(string channelName) => Expressions.Scalar.Channel(this, channelName);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines the relative precedence of an operation in the string
|
||||
/// form of an expression. For example, multiplication has higher
|
||||
/// precedence than addition.
|
||||
/// </summary>
|
||||
enum Precedence : uint
|
||||
{
|
||||
Unknown = 0,
|
||||
Subtraction,
|
||||
Addition,
|
||||
Multiplication,
|
||||
Division,
|
||||
Atomic,
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
||||
|
@ -45,13 +46,17 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
// Composition will do this internally.
|
||||
internal bool IsOne => Simplified is Literal literal && ((float)literal.Value) == 1;
|
||||
|
||||
internal sealed class Add : BinaryExpression
|
||||
internal sealed class Add : BinaryOperatorExpression
|
||||
{
|
||||
public Add(Scalar left, Scalar right)
|
||||
: base(left, right)
|
||||
{
|
||||
}
|
||||
|
||||
internal override Precedence Precedence => Precedence.Addition;
|
||||
|
||||
private protected override string ExpressionOperator => "+";
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Scalar Simplify()
|
||||
{
|
||||
|
@ -72,17 +77,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
return new Literal(literalLeft.Value + literalRight.Value);
|
||||
}
|
||||
|
||||
return left != Left || right != Right
|
||||
? new Add(left, right)
|
||||
: this;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
{
|
||||
var left = Left is Add ? Left.ToText() : Parenthesize(Left);
|
||||
var right = Right is Add ? Right.ToText() : Parenthesize(Right);
|
||||
return $"{left}+{right}";
|
||||
return ReferenceEquals(left, Left) && ReferenceEquals(right, Right)
|
||||
? this
|
||||
: new Add(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,8 +92,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
_text = text;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool IsAtomic => true;
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
// We don't actually know the operation count because the text could
|
||||
|
@ -123,13 +119,41 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
public override int OperationsCount => Left.OperationsCount + Right.OperationsCount;
|
||||
}
|
||||
|
||||
internal sealed class Divide : BinaryExpression
|
||||
internal abstract class BinaryOperatorExpression : BinaryExpression
|
||||
{
|
||||
internal BinaryOperatorExpression(Scalar left, Scalar right)
|
||||
: base(left, right)
|
||||
{
|
||||
}
|
||||
|
||||
private protected abstract string ExpressionOperator { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
{
|
||||
var left = Left.Precedence == Precedence.Unknown
|
||||
? Parenthesize(Left)
|
||||
: Left.ToText();
|
||||
|
||||
var right = Right.Precedence != Precedence && Right.Precedence != Precedence.Atomic
|
||||
? Parenthesize(Right)
|
||||
: Right.ToText();
|
||||
|
||||
return $"{left}{ExpressionOperator}{right}";
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class Divide : BinaryOperatorExpression
|
||||
{
|
||||
internal Divide(Scalar left, Scalar right)
|
||||
: base(left, right)
|
||||
{
|
||||
}
|
||||
|
||||
private protected override string ExpressionOperator => "/";
|
||||
|
||||
internal override Precedence Precedence => Precedence.Division;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Scalar Simplify()
|
||||
{
|
||||
|
@ -157,13 +181,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
return new Literal(literalLeft.Value / literalRight.Value);
|
||||
}
|
||||
|
||||
return left != Left || right != Right
|
||||
? new Divide(left, right)
|
||||
: this;
|
||||
return ReferenceEquals(left, Left) && ReferenceEquals(right, Right)
|
||||
? this
|
||||
: new Divide(left, right);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText() => $"{Parenthesize(Left)}/{Parenthesize(Right)}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -176,8 +197,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
Value = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool IsAtomic => Value >= 0;
|
||||
internal override Precedence Precedence =>
|
||||
Value >= 0
|
||||
? Precedence.Atomic
|
||||
: Precedence.Unknown;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int OperationsCount => 0;
|
||||
|
@ -205,6 +228,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
{
|
||||
}
|
||||
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Scalar Simplify()
|
||||
{
|
||||
|
@ -217,14 +242,23 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
return new Literal(Math.Max(literalLeft.Value, literalRight.Value));
|
||||
}
|
||||
|
||||
return left != Left || right != Right
|
||||
? new Max(left, right)
|
||||
: this;
|
||||
return ReferenceEquals(left, Left) && ReferenceEquals(right, Right)
|
||||
? this
|
||||
: new Max(left, right);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
=> $"Max({Parenthesize(Left)},{Parenthesize(Right)})";
|
||||
{
|
||||
var left = Left.Precedence == Precedence.Unknown
|
||||
? Parenthesize(Left)
|
||||
: Left.ToText();
|
||||
|
||||
var right = Right.Precedence != Precedence && Right.Precedence != Precedence.Atomic
|
||||
? Parenthesize(Right)
|
||||
: Right.ToText();
|
||||
|
||||
return $"Max({left},{right})";
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed new class Min : BinaryExpression
|
||||
|
@ -234,6 +268,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
{
|
||||
}
|
||||
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Scalar Simplify()
|
||||
{
|
||||
|
@ -246,23 +282,36 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
return new Literal(Math.Min(literalLeft.Value, literalRight.Value));
|
||||
}
|
||||
|
||||
return left != Left || right != Right
|
||||
? new Min(left, right)
|
||||
: this;
|
||||
return ReferenceEquals(left, Left) && ReferenceEquals(right, Right)
|
||||
? this
|
||||
: new Min(left, right);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
=> $"Min({Parenthesize(Left)},{Parenthesize(Right)})";
|
||||
{
|
||||
var left = Left.Precedence == Precedence.Unknown
|
||||
? Parenthesize(Left)
|
||||
: Left.ToText();
|
||||
|
||||
var right = Right.Precedence != Precedence && Right.Precedence != Precedence.Atomic
|
||||
? Parenthesize(Right)
|
||||
: Right.ToText();
|
||||
|
||||
return $"Min({left},{right})";
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class Multiply : BinaryExpression
|
||||
internal sealed class Multiply : BinaryOperatorExpression
|
||||
{
|
||||
public Multiply(Scalar left, Scalar right)
|
||||
: base(left, right)
|
||||
{
|
||||
}
|
||||
|
||||
private protected override string ExpressionOperator => "*";
|
||||
|
||||
internal override Precedence Precedence => Precedence.Multiplication;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Scalar Simplify()
|
||||
{
|
||||
|
@ -300,17 +349,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
return new Literal(literalLeft.Value * literalRight.Value);
|
||||
}
|
||||
|
||||
return left != Left || right != Right
|
||||
? new Multiply(left, right)
|
||||
: this;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
{
|
||||
var left = Left is Multiply ? Left.ToText() : Parenthesize(Left);
|
||||
var right = Right is Multiply ? Right.ToText() : Parenthesize(Right);
|
||||
return $"{left}*{right}";
|
||||
return ReferenceEquals(left, Left) && ReferenceEquals(right, Right)
|
||||
? this
|
||||
: new Multiply(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,6 +370,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
/// <inheritdoc/>
|
||||
public override int OperationsCount => Power.OperationsCount + Value.OperationsCount;
|
||||
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Scalar Simplify()
|
||||
{
|
||||
|
@ -360,13 +403,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
}
|
||||
}
|
||||
|
||||
return value != Value || power != Power
|
||||
? new Pow(value, power)
|
||||
: this;
|
||||
return ReferenceEquals(value, Value) && ReferenceEquals(power, Power)
|
||||
? this
|
||||
: new Pow(value, power);
|
||||
}
|
||||
|
||||
protected override bool IsAtomic => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
=> $"Pow({Value.ToText()},{Power.ToText()})";
|
||||
|
@ -392,7 +433,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
: (Scalar)this;
|
||||
}
|
||||
|
||||
protected override bool IsAtomic => true;
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText() => $"Square({Value.ToText()})";
|
||||
|
@ -417,25 +458,28 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
protected override Scalar Simplify()
|
||||
{
|
||||
var valueSimplified = _value.Simplified;
|
||||
return valueSimplified != _value
|
||||
? new Subchannel<T>(valueSimplified, _channelName)
|
||||
: this;
|
||||
return ReferenceEquals(valueSimplified, _value)
|
||||
? this
|
||||
: new Subchannel<T>(valueSimplified, _channelName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText() => $"{Parenthesize(_value)}.{_channelName}";
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool IsAtomic => true;
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
}
|
||||
|
||||
internal sealed class Subtract : BinaryExpression
|
||||
internal sealed class Subtract : BinaryOperatorExpression
|
||||
{
|
||||
public Subtract(Scalar left, Scalar right)
|
||||
: base(left, right)
|
||||
{
|
||||
}
|
||||
|
||||
private protected override string ExpressionOperator => "-";
|
||||
|
||||
internal override Precedence Precedence => Precedence.Subtraction;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Scalar Simplify()
|
||||
{
|
||||
|
@ -453,13 +497,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
return new Literal(literalLeft.Value - literalRight.Value);
|
||||
}
|
||||
|
||||
return left != Left || right != Right
|
||||
? new Subtract(left, right)
|
||||
: this;
|
||||
return ReferenceEquals(left, Left) && ReferenceEquals(right, Right)
|
||||
? this
|
||||
: new Subtract(left, right);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText() => $"{Parenthesize(Left)}-{Parenthesize(Right)}";
|
||||
}
|
||||
|
||||
internal sealed new class Ternary : Scalar
|
||||
|
@ -497,12 +538,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
return f;
|
||||
}
|
||||
|
||||
if (c != Condition || t != TrueValue || f != FalseValue)
|
||||
{
|
||||
return new Ternary(c, t, f);
|
||||
}
|
||||
|
||||
return this;
|
||||
return
|
||||
ReferenceEquals(c, Condition) &&
|
||||
ReferenceEquals(t, TrueValue) &&
|
||||
ReferenceEquals(f, FalseValue)
|
||||
? this
|
||||
: new Ternary(c, t, f);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
|
@ -61,18 +61,14 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
return left;
|
||||
}
|
||||
|
||||
return left != Left || right != Right
|
||||
? new Add(left, right)
|
||||
: this;
|
||||
return ReferenceEquals(left, Left) && ReferenceEquals(right, Right)
|
||||
? this
|
||||
: new Add(left, right);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
{
|
||||
var left = Left is Add ? Left.ToText() : Parenthesize(Left);
|
||||
var right = Right is Add ? Right.ToText() : Parenthesize(Right);
|
||||
return $"{left}+{right}";
|
||||
}
|
||||
internal override Precedence Precedence => Precedence.Addition;
|
||||
|
||||
private protected override string ExpressionOperator => "+";
|
||||
}
|
||||
|
||||
internal sealed class Asserted : Vector2
|
||||
|
@ -84,8 +80,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
_text = text;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool IsAtomic => true;
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
// We don't actually know the operation count because the text could
|
||||
|
@ -108,8 +103,24 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
|
||||
public Vector2 Right { get; }
|
||||
|
||||
private protected abstract string ExpressionOperator { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int OperationsCount => Left.OperationsCount + Right.OperationsCount;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override sealed string CreateExpressionText()
|
||||
{
|
||||
var left = Left.Precedence == Precedence.Unknown
|
||||
? Parenthesize(Left)
|
||||
: Left.ToText();
|
||||
|
||||
var right = Right.Precedence != Precedence && Right.Precedence != Precedence.Atomic
|
||||
? Parenthesize(Right)
|
||||
: Right.ToText();
|
||||
|
||||
return $"{left}{ExpressionOperator}{right}";
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class Constructed : Vector2
|
||||
|
@ -133,16 +144,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
var x = X.Simplified;
|
||||
var y = Y.Simplified;
|
||||
|
||||
return x != X || y != Y
|
||||
? new Constructed(x, y)
|
||||
: this;
|
||||
return ReferenceEquals(x, X) && ReferenceEquals(y, Y)
|
||||
? this
|
||||
: new Constructed(x, y);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
=> $"Vector2({X},{Y})";
|
||||
|
||||
protected override bool IsAtomic => true;
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
}
|
||||
|
||||
internal sealed class Divide : BinaryExpression
|
||||
|
@ -173,14 +184,14 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
return left;
|
||||
}
|
||||
|
||||
return left != Left || right != Right
|
||||
? new Divide(left, right)
|
||||
: this;
|
||||
return ReferenceEquals(left, Left) && ReferenceEquals(right, Right)
|
||||
? this
|
||||
: new Divide(left, right);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
=> $"{Parenthesize(Left)}/{Parenthesize(Right)}";
|
||||
internal override Precedence Precedence => Precedence.Division;
|
||||
|
||||
private protected override string ExpressionOperator => "/";
|
||||
}
|
||||
|
||||
internal sealed class Multiply : BinaryExpression
|
||||
|
@ -216,18 +227,14 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
return left;
|
||||
}
|
||||
|
||||
return left != Left || right != Right
|
||||
? new Multiply(left, right)
|
||||
: this;
|
||||
return ReferenceEquals(left, Left) && ReferenceEquals(right, Right)
|
||||
? this
|
||||
: new Multiply(left, right);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
{
|
||||
var left = Left is Multiply ? Left.ToText() : Parenthesize(Left);
|
||||
var right = Right is Multiply ? Right.ToText() : Parenthesize(Right);
|
||||
return $"{left}*{right}";
|
||||
}
|
||||
internal override Precedence Precedence => Precedence.Multiplication;
|
||||
|
||||
private protected override string ExpressionOperator => "*";
|
||||
}
|
||||
|
||||
internal sealed class ScalarMultiply : Vector2
|
||||
|
@ -245,6 +252,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
/// <inheritdoc/>
|
||||
public override int OperationsCount => Left.OperationsCount + Right.OperationsCount;
|
||||
|
||||
internal override Precedence Precedence => Precedence.Multiplication;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Vector2 Simplify()
|
||||
{
|
||||
|
@ -261,16 +270,24 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
return right;
|
||||
}
|
||||
|
||||
return left != Left || right != Right
|
||||
? new ScalarMultiply(left, right)
|
||||
: this;
|
||||
return ReferenceEquals(left, Left) && ReferenceEquals(right, Right)
|
||||
? this
|
||||
: new ScalarMultiply(left, right);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
=> Left is Scalar.BinaryExpression.Multiply left
|
||||
? $"{left.ToText()}*{Parenthesize(Right)}"
|
||||
: $"{Parenthesize(Left)}*{Parenthesize(Right)}";
|
||||
{
|
||||
var left = Left.Precedence == Precedence.Unknown
|
||||
? Parenthesize(Left)
|
||||
: Left.ToText();
|
||||
|
||||
var right = Right.Precedence != Precedence && Right.Precedence != Precedence.Atomic
|
||||
? Parenthesize(Right)
|
||||
: Right.ToText();
|
||||
|
||||
return $"{left}*{right}";
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class Subtract : BinaryExpression
|
||||
|
@ -280,6 +297,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
{
|
||||
}
|
||||
|
||||
internal override Precedence Precedence => Precedence.Subtraction;
|
||||
|
||||
private protected override string ExpressionOperator => "-";
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Vector2 Simplify()
|
||||
{
|
||||
|
@ -291,14 +312,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
return left;
|
||||
}
|
||||
|
||||
return left != Left || right != Right
|
||||
? new Subtract(left, right)
|
||||
: this;
|
||||
return ReferenceEquals(left, Left) && ReferenceEquals(right, Right)
|
||||
? this
|
||||
: new Subtract(left, right);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
=> $"{Parenthesize(Left)}-{Parenthesize(Right)}";
|
||||
}
|
||||
|
||||
Scalar Channel(string channelName) => Expressions.Scalar.Channel(this, channelName);
|
||||
|
|
|
@ -41,6 +41,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
{
|
||||
}
|
||||
|
||||
private protected override string ExpressionOperator => "+";
|
||||
|
||||
internal override Precedence Precedence => Precedence.Addition;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Vector3 Simplify()
|
||||
{
|
||||
|
@ -57,17 +61,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
return left;
|
||||
}
|
||||
|
||||
return left != Left || right != Right
|
||||
? new Add(left, right)
|
||||
: this;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
{
|
||||
var left = Left is Add ? Left.ToText() : Parenthesize(Left);
|
||||
var right = Right is Add ? Right.ToText() : Parenthesize(Right);
|
||||
return $"{left}+{right}";
|
||||
return ReferenceEquals(left, Left) && ReferenceEquals(right, Right)
|
||||
? this
|
||||
: new Add(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,8 +76,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
_text = text;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool IsAtomic => true;
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
// We don't actually know the operation count because the text could
|
||||
|
@ -104,8 +99,24 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
|
||||
public Vector3 Right { get; }
|
||||
|
||||
private protected abstract string ExpressionOperator { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int OperationsCount => Left.OperationsCount + Right.OperationsCount;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override sealed string CreateExpressionText()
|
||||
{
|
||||
var left = Left.Precedence == Precedence.Unknown
|
||||
? Parenthesize(Left)
|
||||
: Left.ToText();
|
||||
|
||||
var right = Right.Precedence != Precedence && Right.Precedence != Precedence.Atomic
|
||||
? Parenthesize(Right)
|
||||
: Right.ToText();
|
||||
|
||||
return $"{left}{ExpressionOperator}{right}";
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class Constructed : Vector3
|
||||
|
@ -126,6 +137,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
/// <inheritdoc/>
|
||||
public override int OperationsCount => X.OperationsCount + Y.OperationsCount + Z.OperationsCount;
|
||||
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Vector3 Simplify()
|
||||
{
|
||||
|
@ -133,7 +146,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
var y = Y.Simplified;
|
||||
var z = Z.Simplified;
|
||||
|
||||
return x == X && y == Y && z == Z
|
||||
return ReferenceEquals(x, X) && ReferenceEquals(y, Y) && ReferenceEquals(z, Z)
|
||||
? this
|
||||
: Vector3(x, y, z);
|
||||
}
|
||||
|
@ -141,8 +154,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
=> $"Vector3({X},{Y},{Z})";
|
||||
|
||||
protected override bool IsAtomic => true;
|
||||
}
|
||||
|
||||
internal sealed class ScalarMultiply : Vector3
|
||||
|
@ -160,6 +171,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
/// <inheritdoc/>
|
||||
public override int OperationsCount => Left.OperationsCount + Right.OperationsCount;
|
||||
|
||||
internal override Precedence Precedence => Precedence.Multiplication;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Vector3 Simplify()
|
||||
{
|
||||
|
@ -176,16 +189,24 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
return right;
|
||||
}
|
||||
|
||||
return left != Left || right != Right
|
||||
? new ScalarMultiply(left, right)
|
||||
: this;
|
||||
return ReferenceEquals(left, Left) && ReferenceEquals(right, Right)
|
||||
? this
|
||||
: new ScalarMultiply(left, right);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
=> Left is Scalar.BinaryExpression.Multiply left
|
||||
? $"{left.ToText()}*{Parenthesize(Right)}"
|
||||
: $"{Parenthesize(Left)}*{Parenthesize(Right)}";
|
||||
{
|
||||
var left = Left.Precedence == Precedence.Unknown
|
||||
? Parenthesize(Left)
|
||||
: Left.ToText();
|
||||
|
||||
var right = Right.Precedence != Precedence && Right.Precedence != Precedence.Atomic
|
||||
? Parenthesize(Right)
|
||||
: Right.ToText();
|
||||
|
||||
return $"{left}*{right}";
|
||||
}
|
||||
}
|
||||
|
||||
Scalar Channel(string channelName) => Expressions.Scalar.Channel(this, channelName);
|
||||
|
|
|
@ -41,8 +41,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
_text = text;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool IsAtomic => true;
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
// We don't actually know the operation count because the text could
|
||||
|
@ -71,6 +70,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
|
||||
public override Scalar W { get; }
|
||||
|
||||
internal override Precedence Precedence => Precedence.Atomic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int OperationsCount => X.OperationsCount + Y.OperationsCount + Z.OperationsCount + W.OperationsCount;
|
||||
|
||||
|
@ -82,7 +83,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
var z = Z.Simplified;
|
||||
var w = W.Simplified;
|
||||
|
||||
return x == X && y == Y && z == Z && w == W
|
||||
return
|
||||
ReferenceEquals(x, X) &&
|
||||
ReferenceEquals(y, Y) &&
|
||||
ReferenceEquals(z, Z) &&
|
||||
ReferenceEquals(w, W)
|
||||
? this
|
||||
: new Constructed(x, y, z, w);
|
||||
}
|
||||
|
@ -90,8 +95,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Expressions
|
|||
/// <inheritdoc/>
|
||||
protected override string CreateExpressionText()
|
||||
=> $"Vector4({X},{Y},{Z},{W})";
|
||||
|
||||
protected override bool IsAtomic => true;
|
||||
}
|
||||
|
||||
Scalar Channel(string channelName) => Expressions.Scalar.Channel(this, channelName);
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
<Compile Include="$(MSBuildThisFileDirectory)Expressions\Boolean.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Expressions\Color.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Expressions\Expression_.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Expressions\Precedence.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Expressions\Scalar.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Expressions\Expression.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Expressions\ExpressionType.cs" />
|
||||
|
|
|
@ -24,9 +24,12 @@ Param(
|
|||
)
|
||||
|
||||
# Find the most recently built LottieGen.dll.
|
||||
# Sort by LastWriteTime rather than CreationTime because the compiler will
|
||||
# reuse existing output files such that the CreationTime does not represent
|
||||
# the time when the compilation was done.
|
||||
$lottieGenExe =
|
||||
Get-ChildItem LottieGen.exe -r -path "$PSScriptRoot\..\LottieGen\bin\" |
|
||||
Sort-Object -Property 'CreationTime' -Desc |
|
||||
Get-ChildItem LottieGen.exe -r -path "$PSScriptRoot\..\LottieGen\dotnettool\bin\" |
|
||||
Sort-Object -Property 'LastWriteTime' -Desc |
|
||||
Select-Object -first 1
|
||||
|
||||
if (!$lottieGenExe)
|
||||
|
|
Загрузка…
Ссылка в новой задаче