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:
Simeon 2021-03-05 14:05:00 -08:00 коммит произвёл GitHub
Родитель 12fbb261dd
Коммит 11c75f8865
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
11 изменённых файлов: 278 добавлений и 171 удалений

Просмотреть файл

@ -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,16 +83,18 @@ 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
? this
: new Constructed(x, y, z, w);
return
ReferenceEquals(x, X) &&
ReferenceEquals(y, Y) &&
ReferenceEquals(z, Z) &&
ReferenceEquals(w, W)
? this
: new Constructed(x, y, z, w);
}
/// <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)