Skip to content

Commit

Permalink
Fix codegen to generate IAnimatedVisual2 and IAnimatedVisualSource2 i…
Browse files Browse the repository at this point in the history
…nterfaces for WinUI3 (#551)

* Unify animation controller initialization code for remapped time scales

* Fixed CreateSpriteShape helper codegen

* Allow IAV2 and IAVS2 to be implemented for WinUI3
  • Loading branch information
aborziak-ms authored Feb 28, 2024
1 parent 1570c14 commit 0443b1e
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 39 deletions.
28 changes: 21 additions & 7 deletions source/LottieToWinComp/Animate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,27 @@ public static void WithKeyFrame(
Debug.Assert(scale <= 1, "Precondition");
Debug.Assert(animation.KeyFrameCount > 0, "Precondition");

if (scale == 1.0 && offset == 0.0 && context.ObjectFactory.IsUapApiAvailable(nameof(AnimationController)) && context.RootProgressController is not null)
var key = new ScaleAndOffset(scale, offset);
var state = context.GetStateCache<StateCache>();

if (context.ObjectFactory.IsUapApiAvailable(nameof(AnimationController)))
{
// Special case when we can use root AnimationController (no time stretch, no time offset)
compObject.StartAnimation(target, animation, context.RootProgressController!);
if (!state.ProgressControllers.TryGetValue(key, out var controllerCached))
{
controllerCached = context.ObjectFactory.CreateAnimationControllerList();
controllerCached.Pause();

var rootProgressAnimation = context.ObjectFactory.CreateExpressionAnimation(scale == 1.0 && offset == 0.0 ? ExpressionFactory.RootProgress : ExpressionFactory.ScaledAndOffsetRootProgress(scale, offset));
rootProgressAnimation.SetReferenceParameter(ExpressionFactory.RootName, context.RootVisual!);
controllerCached.StartAnimation("Progress", rootProgressAnimation);

state.ProgressControllers.Add(key, controllerCached);
}

compObject.StartAnimation(target, animation, controllerCached);
return;
}

var state = context.GetStateCache<StateCache>();

// Start the animation ...
compObject.StartAnimation(target, animation);

Expand All @@ -61,7 +73,6 @@ public static void WithKeyFrame(
controller!.Pause();

// Bind it to the root visual's Progress property, scaling and offsetting if necessary.
var key = new ScaleAndOffset(scale, offset);
if (!state.ProgressBindingAnimations.TryGetValue(key, out var bindingAnimation))
{
bindingAnimation = context.ObjectFactory.CreateExpressionAnimation(ExpressionFactory.ScaledAndOffsetRootProgress(scale, offset));
Expand Down Expand Up @@ -853,7 +864,7 @@ void InsertExpressionKeyFrame(TCA animation, float progress, CubicBezierFunction
}

// A pair of doubles used as a key in a dictionary.
sealed class ScaleAndOffset
public sealed class ScaleAndOffset
{
internal ScaleAndOffset(double scale, double offset)
{
Expand All @@ -877,6 +888,9 @@ sealed class StateCache
{
public Dictionary<ScaleAndOffset, ExpressionAnimation> ProgressBindingAnimations { get; }
= new Dictionary<ScaleAndOffset, ExpressionAnimation>();

public Dictionary<ScaleAndOffset, AnimationController> ProgressControllers { get; }
= new Dictionary<ScaleAndOffset, AnimationController>();
}
}
}
15 changes: 0 additions & 15 deletions source/LottieToWinComp/TranslationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,6 @@ internal static TranslationResult TryTranslateLottieComposition(
/// </summary>
public ContainerVisual? RootVisual { get; private set; }

/// <summary>
/// AnimationController that has Progress property bound to RootVisual.Progress property.
/// </summary>
public AnimationController? RootProgressController { get; private set; }

/// <summary>
/// True iff theme property bindings are enabled.
/// </summary>
Expand Down Expand Up @@ -228,16 +223,6 @@ void Translate()
// Add the master progress property to the visual.
RootVisual.Properties.InsertScalar(ProgressPropertyName, 0);

// AnimationController that has Progress value bound to RootVisual.Progress
if (ObjectFactory.IsUapApiAvailable(nameof(AnimationController)))
{
RootProgressController = ObjectFactory.CreateAnimationControllerList();
var rootProgressAnimation = context.ObjectFactory.CreateExpressionAnimation(ExpressionFactory.RootProgress);
rootProgressAnimation.SetReferenceParameter(ExpressionFactory.RootName, RootVisual);
RootProgressController.Pause();
RootProgressController.StartAnimation("Progress", rootProgressAnimation);
}

// Add the translations of each layer to the root visual. This will recursively
// add the tranlation of the layers in precomps.
var contentsChildren = RootVisual.Children;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ void WriteIAnimatedVisualSource(CodeBuilder builder, bool implementDynamicAVS)
builder.WriteLine($": {Interface_IAnimatedVisualSource.GetQualifiedName(_s)}");
}

if (SourceInfo.WinUIVersion >= new Version(2, 6) && SourceInfo.WinUIVersion.Major < 3)
if (SourceInfo.WinUIVersion >= new Version(2, 6))
{
builder.WriteLine($", {Interface_IAnimatedVisualSource2.GetQualifiedName(_s)}");
}
Expand Down Expand Up @@ -685,15 +685,17 @@ void WriteSetPropertyImpl(
protected override void WriteAnimatedVisualStart(CodeBuilder builder, IAnimatedVisualInfo info)
{
// Start the instantiator class.
builder.WriteLine($"sealed class {info.ClassName}");
builder.Indent();
builder.WriteLine($": {Interface_IAnimatedVisual.GetQualifiedName(_s)}");

if (info.ImplementCreateAndDestroyMethods)
{
builder.WriteLine($"sealed class {info.ClassName} : {Interface_IAnimatedVisual2.GetQualifiedName(_s)}");
}
else
{
builder.WriteLine($"sealed class {info.ClassName} : {Interface_IAnimatedVisual.GetQualifiedName(_s)}");
builder.WriteLine($", {Interface_IAnimatedVisual2.GetQualifiedName(_s)}");
}

builder.UnIndent();

builder.OpenScope();
}

Expand Down
2 changes: 1 addition & 1 deletion source/UIDataCodeGen/CodeGen/CodegenConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,6 @@ Version winUIVersion
/// </summary>
public Version WinUIVersion { get; set; }

public bool ImplementCreateAndDestroyMethods => WinUIVersion >= Version.Parse("2.8") && WinUIVersion < Version.Parse("3.0");
public bool ImplementCreateAndDestroyMethods => WinUIVersion >= Version.Parse("2.8");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,11 @@ string GenerateIdlText()
else
{
builder.WriteLine($": [default] {Interface_IAnimatedVisualSource.NormalizedQualifiedName}");
}

if (SourceInfo.WinUIVersion >= new Version(2, 6) && SourceInfo.WinUIVersion.Major < 3)
{
builder.WriteLine($", {Interface_IAnimatedVisualSource2.NormalizedQualifiedName}");
}
if (SourceInfo.WinUIVersion >= new Version(2, 6))
{
builder.WriteLine($", {Interface_IAnimatedVisualSource2.NormalizedQualifiedName}");
}

if (_isIDynamic)
Expand Down
7 changes: 3 additions & 4 deletions source/UIDataCodeGen/CodeGen/Cx/CxInstantiatorGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ public static CxCodegenResult CreateFactoryCode(CodegenConfiguration configurati
_animatedVisualTypeName = Interface_IAnimatedVisual.GetQualifiedName(_s);
_animatedVisualTypeName2 = Interface_IAnimatedVisual2.GetQualifiedName(_s);

// Temporary until IAnimatedVisualSource2 makes it into WinUI3.
_isAnimatedIcon = SourceInfo.WinUIVersion >= new Version(2, 6) && SourceInfo.WinUIVersion.Major < 3;
_isAnimatedIcon = SourceInfo.WinUIVersion >= new Version(2, 6);
}

static string FieldAssignment(string fieldName) => fieldName is not null ? $"{fieldName} = " : string.Empty;
Expand Down Expand Up @@ -134,7 +133,7 @@ void WriteIAnimatedVisualSourceHeaderText(HeaderBuilder builder)

inherits.Add(Interface_IAnimatedVisualSource.GetQualifiedName(_s));

if (SourceInfo.WinUIVersion >= new Version(2, 6) && SourceInfo.WinUIVersion.Major < 3)
if (SourceInfo.WinUIVersion >= new Version(2, 6))
{
inherits.Add(Interface_IAnimatedVisualSource2.GetQualifiedName(_s));
}
Expand Down Expand Up @@ -372,7 +371,7 @@ void WriteIDynamicAnimatedVisualSourceHeaderText(HeaderBuilder builder)

inherits.Add("Microsoft::UI::Xaml::Controls::IDynamicAnimatedVisualSource");

if (SourceInfo.WinUIVersion >= new Version(2, 6) && SourceInfo.WinUIVersion.Major < 3)
if (SourceInfo.WinUIVersion >= new Version(2, 6))
{
inherits.Add(Interface_IAnimatedVisualSource2.GetQualifiedName(_s));
}
Expand Down
4 changes: 2 additions & 2 deletions source/UIDataCodeGen/CodeGen/InstantiatorGeneratorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2212,7 +2212,7 @@ void WriteCallHelperCreateSpriteShape(
{
b.WriteLine($"{ReferenceTypeName("CompositionSpriteShape")} CreateSpriteShape({ReferenceTypeName("CompositionGeometry")} geometry, {_s.TypeMatrix3x2} transformMatrix)");
b.OpenScope();
WriteCreateAssignment(b, node, $"_c{Deref}CreateSpriteShape(geometry)");
b.WriteLine($"{ConstVar} result = _c{Deref}CreateSpriteShape(geometry);");
WriteSetPropertyStatement(b, "TransformMatrix", "transformMatrix");
b.WriteLine("return result;");
b.CloseScope();
Expand Down Expand Up @@ -2244,7 +2244,7 @@ void WriteCallHelperCreateSpriteShapeWithFillBrush(
{
b.WriteLine($"{ReferenceTypeName("CompositionSpriteShape")} CreateSpriteShape({ReferenceTypeName("CompositionGeometry")} geometry, {_s.TypeMatrix3x2} transformMatrix, {ReferenceTypeName("CompositionBrush")} fillBrush)");
b.OpenScope();
WriteCreateAssignment(b, node, $"_c{Deref}CreateSpriteShape(geometry)");
b.WriteLine($"{ConstVar} result = _c{Deref}CreateSpriteShape(geometry);");
WriteSetPropertyStatement(b, "TransformMatrix", "transformMatrix");
WriteSetPropertyStatement(b, "FillBrush", "fillBrush");
b.WriteLine("return result;");
Expand Down

0 comments on commit 0443b1e

Please sign in to comment.