Generate version-dependent code. (#165)
Support codegen of multiple versions to allow runtime switching based on the current platform.
This commit is contained in:
Родитель
98cba02414
Коммит
1a87b8d6fa
|
@ -1,47 +0,0 @@
|
|||
// 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.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using static Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.InstantiatorGeneratorBase;
|
||||
|
||||
namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information about code being generated for an IAnimatedVisual.
|
||||
/// </summary>
|
||||
public sealed class AnimatedVisualInfo
|
||||
{
|
||||
internal AnimatedVisualInfo(
|
||||
AnimatedVisualSourceInfo animatedVisualSourceInfo,
|
||||
string className,
|
||||
IReadOnlyList<LoadedImageSurfaceInfo> loadedImageSurfaceNodes)
|
||||
{
|
||||
AnimatedVisualSourceInfo = animatedVisualSourceInfo;
|
||||
ClassName = className;
|
||||
LoadedImageSurfaceNodes = loadedImageSurfaceNodes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="AnimatedVisualSourceInfo"/> describing the IAnimatedVisualSource that
|
||||
/// will source the IAnimatedVisual described by this object.
|
||||
/// </summary>
|
||||
public AnimatedVisualSourceInfo AnimatedVisualSourceInfo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the IAnimatedVisual class that will be exposed to users.
|
||||
/// </summary>
|
||||
public string ClassName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the AnimatedVisual has LoadedImageSurface.
|
||||
/// </summary>
|
||||
public bool HasLoadedImageSurface => LoadedImageSurfaceNodes.Count > 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the LoadedImageSurface nodes of the AnimatedVisual.
|
||||
/// </summary>
|
||||
internal IReadOnlyList<LoadedImageSurfaceInfo> LoadedImageSurfaceNodes { get; }
|
||||
}
|
||||
}
|
|
@ -71,7 +71,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
|
||||
/// <inheritdoc/>
|
||||
// Called by the base class to write the start of the file (i.e. everything up to the body of the Instantiator class).
|
||||
protected override void WriteFileStart(CodeBuilder builder, AnimatedVisualSourceInfo info)
|
||||
protected override void WriteFileStart(CodeBuilder builder, IAnimatedVisualSourceInfo info)
|
||||
{
|
||||
// A sorted set to hold the namespaces that the generated code will use. The set is maintained in sorted order.
|
||||
var namepaces = new SortedSet<string>();
|
||||
|
@ -133,7 +133,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
/// <summary>
|
||||
/// Write a class that implements the IAnimatedVisualSource interface.
|
||||
/// </summary>
|
||||
void WriteIAnimatedVisualSource(CodeBuilder builder, AnimatedVisualSourceInfo info)
|
||||
void WriteIAnimatedVisualSource(CodeBuilder builder, IAnimatedVisualSourceInfo info)
|
||||
{
|
||||
builder.WriteLine("namespace AnimatedVisuals");
|
||||
builder.OpenScope();
|
||||
|
@ -144,19 +144,29 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
builder.WriteLine("public IAnimatedVisual TryCreateAnimatedVisual(Compositor compositor, out object diagnostics)");
|
||||
builder.OpenScope();
|
||||
builder.WriteLine("diagnostics = null;");
|
||||
builder.WriteLine("if (!IsRuntimeCompatible())");
|
||||
builder.OpenScope();
|
||||
builder.WriteLine();
|
||||
|
||||
// Check the runtime version and instantiate the highest compatible IAnimatedVisual class.
|
||||
var animatedVisualInfos = info.AnimatedVisualInfos.OrderByDescending(avi => avi.RequiredUapVersion).ToArray();
|
||||
for (var i = 0; i < animatedVisualInfos.Length; i++)
|
||||
{
|
||||
var current = animatedVisualInfos[i];
|
||||
builder.WriteLine($"if ({current.ClassName}.IsRuntimeCompatible())");
|
||||
builder.OpenScope();
|
||||
builder.WriteLine($"return new {current.ClassName}(compositor);");
|
||||
builder.CloseScope();
|
||||
builder.WriteLine();
|
||||
}
|
||||
|
||||
builder.WriteLine("return null;");
|
||||
builder.CloseScope();
|
||||
builder.WriteLine("return new AnimatedVisual(compositor);");
|
||||
builder.CloseScope();
|
||||
builder.WriteLine();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a class that implements the IDynamicAnimatedVisualSource interface.
|
||||
/// </summary>
|
||||
void WriteIDynamicAnimatedVisualSource(CodeBuilder builder, AnimatedVisualSourceInfo info)
|
||||
void WriteIDynamicAnimatedVisualSource(CodeBuilder builder, IAnimatedVisualSourceInfo info)
|
||||
{
|
||||
builder.WriteLine("namespace AnimatedVisuals");
|
||||
builder.OpenScope();
|
||||
|
@ -215,9 +225,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
builder.WriteLine("public IAnimatedVisual TryCreateAnimatedVisual(Compositor compositor, out object diagnostics)");
|
||||
builder.OpenScope();
|
||||
builder.WriteLine("_isTryCreateAnimatedVisualCalled = true;");
|
||||
builder.WriteLine();
|
||||
builder.WriteLine("diagnostics = null;");
|
||||
builder.WriteLine("if (!IsRuntimeCompatible())");
|
||||
builder.WriteLine();
|
||||
|
||||
// Check whether the runtime will support the lowest UAP version required.
|
||||
var animatedVisualInfos = info.AnimatedVisualInfos.OrderByDescending(avi => avi.RequiredUapVersion).ToArray();
|
||||
builder.WriteLine($"if (!{animatedVisualInfos[animatedVisualInfos.Length - 1].ClassName}.IsRuntimeCompatible())");
|
||||
builder.OpenScope();
|
||||
builder.WriteLine("return null;");
|
||||
builder.CloseScope();
|
||||
|
@ -228,14 +241,40 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
builder.OpenScope();
|
||||
builder.WriteLine("return null;");
|
||||
builder.CloseScope();
|
||||
builder.WriteLine("return");
|
||||
builder.Indent();
|
||||
builder.WriteLine("new AnimatedVisual(compositor,");
|
||||
builder.Indent();
|
||||
builder.WriteCommaSeparatedLines(info.LoadedImageSurfaceNodes.Select(n => n.FieldName));
|
||||
builder.WriteLine(");");
|
||||
builder.UnIndent();
|
||||
builder.UnIndent();
|
||||
builder.WriteLine();
|
||||
|
||||
// Check the runtime version and instantiate the highest compatible IAnimatedVisual class.
|
||||
for (var i = 0; i < animatedVisualInfos.Length; i++)
|
||||
{
|
||||
var current = animatedVisualInfos[i];
|
||||
var versionTestRequired = i < animatedVisualInfos.Length - 1;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
builder.WriteLine();
|
||||
}
|
||||
|
||||
if (versionTestRequired)
|
||||
{
|
||||
builder.WriteLine($"if ({current.ClassName}.IsRuntimeCompatible())");
|
||||
builder.OpenScope();
|
||||
}
|
||||
|
||||
builder.WriteLine("return");
|
||||
builder.Indent();
|
||||
builder.WriteLine($"new {current.ClassName}(");
|
||||
builder.Indent();
|
||||
builder.WriteLine("compositor,");
|
||||
builder.WriteCommaSeparatedLines(info.LoadedImageSurfaceNodes.Select(n => n.FieldName));
|
||||
builder.WriteLine(");");
|
||||
builder.UnIndent();
|
||||
builder.UnIndent();
|
||||
if (versionTestRequired)
|
||||
{
|
||||
builder.CloseScope();
|
||||
}
|
||||
}
|
||||
|
||||
builder.CloseScope();
|
||||
builder.WriteLine();
|
||||
|
||||
|
@ -261,7 +300,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void WriteAnimatedVisualStart(CodeBuilder builder, AnimatedVisualInfo info)
|
||||
protected override void WriteAnimatedVisualStart(CodeBuilder builder, IAnimatedVisualInfo info)
|
||||
{
|
||||
// Start the instantiator class.
|
||||
builder.WriteLine($"sealed class {info.ClassName} : IAnimatedVisual");
|
||||
|
@ -272,14 +311,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
// Called by the base class to write the end of the AnimatedVisual class.
|
||||
protected override void WriteAnimatedVisualEnd(
|
||||
CodeBuilder builder,
|
||||
AnimatedVisualInfo info)
|
||||
IAnimatedVisualInfo info)
|
||||
{
|
||||
// Write the constructor for the AnimatedVisual class.
|
||||
if (info.HasLoadedImageSurface)
|
||||
{
|
||||
builder.WriteLine($"internal {info.ClassName}(Compositor compositor,");
|
||||
builder.WriteLine($"internal {info.ClassName}(");
|
||||
builder.Indent();
|
||||
|
||||
builder.WriteLine("Compositor compositor,");
|
||||
|
||||
// Define the image surface parameters of the AnimatedVisual() constructor.
|
||||
builder.WriteCommaSeparatedLines(info.LoadedImageSurfaceNodes.Select(n => $"{_s.ReferenceTypeName(n.TypeName)} {_s.CamelCase(n.Name)}"));
|
||||
builder.WriteLine(")");
|
||||
|
@ -298,7 +339,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
}
|
||||
else
|
||||
{
|
||||
builder.WriteLine("internal AnimatedVisual(Compositor compositor)");
|
||||
builder.WriteLine($"internal {info.ClassName}(Compositor compositor)");
|
||||
builder.OpenScope();
|
||||
builder.WriteLine("_c = compositor;");
|
||||
builder.WriteLine($"{info.AnimatedVisualSourceInfo.ReusableExpressionAnimationFieldName} = compositor.CreateExpressionAnimation();");
|
||||
|
@ -313,6 +354,13 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
builder.WriteLine($"TimeSpan IAnimatedVisual.Duration => TimeSpan.FromTicks({info.AnimatedVisualSourceInfo.DurationTicksFieldName});");
|
||||
builder.WriteLine($"Vector2 IAnimatedVisual.Size => {Vector2(info.AnimatedVisualSourceInfo.CompositionDeclaredSize)};");
|
||||
builder.WriteLine("void IDisposable.Dispose() => _root?.Dispose();");
|
||||
builder.WriteLine();
|
||||
|
||||
// Write the IsRuntimeCompatible static method.
|
||||
builder.WriteLine("internal static bool IsRuntimeCompatible()");
|
||||
builder.OpenScope();
|
||||
builder.WriteLine($"return Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent(\"Windows.Foundation.UniversalApiContract\", {info.RequiredUapVersion});");
|
||||
builder.CloseScope();
|
||||
|
||||
// Close the scope for the instantiator class.
|
||||
builder.CloseScope();
|
||||
|
@ -322,7 +370,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
// Called by the base class to write the end of the file (i.e. everything after the body of the AnimatedVisual class).
|
||||
protected override void WriteFileEnd(
|
||||
CodeBuilder builder,
|
||||
AnimatedVisualSourceInfo info)
|
||||
IAnimatedVisualSourceInfo info)
|
||||
{
|
||||
// Close the scope for the IAnimatedVisualSource class.
|
||||
builder.CloseScope();
|
||||
|
@ -366,7 +414,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
builder.WriteLine($"var result = {FieldAssignment(fieldName)}CanvasGeometry.CreateGroup(");
|
||||
builder.Indent();
|
||||
builder.WriteLine($"null,");
|
||||
builder.WriteLine($"new CanvasGeometry[] {{ {string.Join(", ", obj.Geometries.Select(g => CallFactoryFor(g)) ) } }},");
|
||||
builder.WriteLine($"new CanvasGeometry[] {{ {string.Join(", ", obj.Geometries.Select(g => CallFactoryFor(g))) } }},");
|
||||
builder.WriteLine($"{_s.FilledRegionDetermination(obj.FilledRegionDetermination)});");
|
||||
builder.UnIndent();
|
||||
}
|
||||
|
@ -419,7 +467,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
builder.WriteLine($"{Float(obj.W)},");
|
||||
builder.WriteLine($"{Float(obj.H)},");
|
||||
builder.WriteLine($"{Float(obj.RadiusX)},");
|
||||
builder.WriteLine($"{Float(obj.RadiusY)};");
|
||||
builder.WriteLine($"{Float(obj.RadiusY)});");
|
||||
builder.UnIndent();
|
||||
}
|
||||
|
||||
|
@ -445,7 +493,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
builder.WriteLine();
|
||||
}
|
||||
|
||||
void WriteEnsureImageLoadingStarted(CodeBuilder builder, AnimatedVisualSourceInfo info)
|
||||
void WriteEnsureImageLoadingStarted(CodeBuilder builder, IAnimatedVisualSourceInfo info)
|
||||
{
|
||||
builder.WriteLine("void EnsureImageLoadingStarted()");
|
||||
builder.OpenScope();
|
||||
|
|
|
@ -93,7 +93,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
// Called by the base class to write the start of the file (i.e. everything up to the body of the Instantiator class).
|
||||
protected override void WriteFileStart(
|
||||
CodeBuilder builder,
|
||||
AnimatedVisualSourceInfo info)
|
||||
IAnimatedVisualSourceInfo info)
|
||||
{
|
||||
builder.WriteLine("#include \"pch.h\"");
|
||||
builder.WriteLine($"#include \"{_headerFileName}\"");
|
||||
|
@ -188,7 +188,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void WriteAnimatedVisualStart(CodeBuilder builder, AnimatedVisualInfo info)
|
||||
protected override void WriteAnimatedVisualStart(
|
||||
CodeBuilder builder,
|
||||
IAnimatedVisualInfo info)
|
||||
{
|
||||
// Start writing the instantiator.
|
||||
builder.WriteLine($"ref class {info.ClassName} sealed : public Microsoft::UI::Xaml::Controls::IAnimatedVisual");
|
||||
|
@ -206,7 +208,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
// Called by the base class to write the end of the AnimatedVisual class.
|
||||
protected override void WriteAnimatedVisualEnd(
|
||||
CodeBuilder builder,
|
||||
AnimatedVisualInfo info)
|
||||
IAnimatedVisualInfo info)
|
||||
{
|
||||
if (info.AnimatedVisualSourceInfo.UsesCanvasEffects ||
|
||||
info.AnimatedVisualSourceInfo.UsesCanvasGeometry)
|
||||
|
@ -237,9 +239,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
|
||||
if (info.AnimatedVisualSourceInfo.HasLoadedImageSurface)
|
||||
{
|
||||
builder.WriteLine($"{info.ClassName}(Compositor^ compositor,");
|
||||
builder.WriteLine($"{info.ClassName}(");
|
||||
builder.Indent();
|
||||
|
||||
builder.WriteLine("Compositor^ compositor,");
|
||||
builder.WriteCommaSeparatedLines(info.LoadedImageSurfaceNodes.Select(n => $"{_s.ReferenceTypeName(n.TypeName)} {_s.CamelCase(n.Name)}"));
|
||||
|
||||
// Initializer list.
|
||||
|
@ -289,7 +291,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
builder.WriteLine();
|
||||
builder.WriteLine("property TimeSpan Duration");
|
||||
builder.OpenScope();
|
||||
builder.WriteLine("virtual TimeSpan get() { return { c_durationTicks }; }");
|
||||
builder.WriteLine($"virtual TimeSpan get() {{ return {{ {info.AnimatedVisualSourceInfo.DurationTicksFieldName} }}; }}");
|
||||
builder.CloseScope();
|
||||
builder.WriteLine();
|
||||
builder.WriteLine("property Visual^ RootVisual");
|
||||
|
@ -303,6 +305,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
builder.CloseScope();
|
||||
builder.WriteLine();
|
||||
|
||||
// Write the IsRuntimeCompatible static method.
|
||||
builder.WriteLine("static bool IsRuntimeCompatible()");
|
||||
builder.OpenScope();
|
||||
builder.WriteLine($"return Windows::Foundation::Metadata::ApiInformation::IsApiContractPresent(\"Windows.Foundation.UniversalApiContract\", {info.RequiredUapVersion});");
|
||||
builder.CloseScope();
|
||||
|
||||
// Close the scope for the instantiator class.
|
||||
builder.UnIndent();
|
||||
builder.WriteLine("};");
|
||||
|
@ -312,7 +320,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
// Called by the base class to write the end of the file (i.e. everything after the body of the AnimatedVisual class).
|
||||
protected override void WriteFileEnd(
|
||||
CodeBuilder builder,
|
||||
AnimatedVisualSourceInfo info)
|
||||
IAnimatedVisualSourceInfo info)
|
||||
{
|
||||
// Close the anonymous namespace.
|
||||
builder.WriteLine("} // end namespace");
|
||||
|
@ -333,12 +341,23 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
else
|
||||
{
|
||||
builder.WriteLine("diagnostics = nullptr;");
|
||||
builder.WriteLine("if (!IsRuntimeCompatible())");
|
||||
builder.OpenScope();
|
||||
|
||||
// Check whether the runtime will support the lowest UAP version required.
|
||||
var animatedVisualInfos = info.AnimatedVisualInfos.OrderByDescending(avi => avi.RequiredUapVersion).ToArray();
|
||||
|
||||
// Check the runtime version and instantiate the highest compatible IAnimatedVisual class.
|
||||
for (var i = 0; i < animatedVisualInfos.Length; i++)
|
||||
{
|
||||
var current = animatedVisualInfos[i];
|
||||
builder.WriteLine($"if ({current.ClassName}::IsRuntimeCompatible())");
|
||||
builder.OpenScope();
|
||||
builder.WriteLine("return ref new {current.ClassName}(compositor);");
|
||||
builder.CloseScope();
|
||||
}
|
||||
|
||||
builder.WriteLine();
|
||||
builder.WriteLine("return nullptr;");
|
||||
builder.CloseScope();
|
||||
builder.WriteLine("return ref new AnimatedVisual(compositor);");
|
||||
builder.CloseScope();
|
||||
}
|
||||
|
||||
if (info.HasLoadedImageSurface)
|
||||
|
@ -490,12 +509,15 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
/// <summary>
|
||||
/// Generate the body of the TryCreateAnimatedVisual() method for the composition that contains LoadedImageSurfaces.
|
||||
/// </summary>
|
||||
void WriteTryCreateInstantiatorWithImageLoading(CodeBuilder builder, AnimatedVisualSourceInfo info)
|
||||
void WriteTryCreateInstantiatorWithImageLoading(CodeBuilder builder, IAnimatedVisualSourceInfo info)
|
||||
{
|
||||
builder.WriteLine("m_isTryCreateAnimatedVisualCalled = true;");
|
||||
builder.WriteLine();
|
||||
builder.WriteLine("diagnostics = nullptr;");
|
||||
builder.WriteLine("if (!IsRuntimeCompatible())");
|
||||
builder.WriteLine();
|
||||
|
||||
// Check whether the runtime will support the lowest UAP version required.
|
||||
var animatedVisualInfos = info.AnimatedVisualInfos.OrderByDescending(avi => avi.RequiredUapVersion).ToArray();
|
||||
builder.WriteLine($"if (!{animatedVisualInfos[animatedVisualInfos.Length - 1].ClassName}::IsRuntimeCompatible())");
|
||||
builder.OpenScope();
|
||||
builder.WriteLine("return nullptr;");
|
||||
builder.CloseScope();
|
||||
|
@ -506,16 +528,40 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
builder.OpenScope();
|
||||
builder.WriteLine("return nullptr;");
|
||||
builder.CloseScope();
|
||||
builder.WriteLine("return ref new AnimatedVisual(compositor,");
|
||||
builder.Indent();
|
||||
builder.WriteCommaSeparatedLines(info.LoadedImageSurfaceNodes.Select(n => MakeFieldName(n.Name)));
|
||||
builder.UnIndent();
|
||||
builder.WriteLine(");");
|
||||
|
||||
// Check the runtime version and instantiate the highest compatible IAnimatedVisual class.
|
||||
for (var i = 0; i < animatedVisualInfos.Length; i++)
|
||||
{
|
||||
var current = animatedVisualInfos[i];
|
||||
var versionTestRequired = i < animatedVisualInfos.Length - 1;
|
||||
|
||||
builder.WriteLine();
|
||||
if (versionTestRequired)
|
||||
{
|
||||
builder.WriteLine($"if ({current.ClassName}::IsRuntimeCompatible())");
|
||||
builder.OpenScope();
|
||||
}
|
||||
|
||||
builder.WriteLine("return");
|
||||
builder.Indent();
|
||||
builder.WriteLine($"ref new {current.ClassName}(");
|
||||
builder.Indent();
|
||||
builder.WriteLine("compositor,");
|
||||
builder.WriteCommaSeparatedLines(info.LoadedImageSurfaceNodes.Select(n => n.FieldName));
|
||||
builder.WriteLine(");");
|
||||
builder.UnIndent();
|
||||
builder.UnIndent();
|
||||
if (versionTestRequired)
|
||||
{
|
||||
builder.CloseScope();
|
||||
}
|
||||
}
|
||||
|
||||
builder.CloseScope();
|
||||
builder.WriteLine();
|
||||
}
|
||||
|
||||
void WriteIsAnimatedVisualSourceDynamicGetSet(CodeBuilder builder, AnimatedVisualSourceInfo info)
|
||||
void WriteIsAnimatedVisualSourceDynamicGetSet(CodeBuilder builder, IAnimatedVisualSourceInfo info)
|
||||
{
|
||||
builder.WriteLine($"bool AnimatedVisuals::{info.ClassName}::IsAnimatedVisualSourceDynamic::get()");
|
||||
builder.OpenScope();
|
||||
|
@ -532,7 +578,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
builder.CloseScope();
|
||||
}
|
||||
|
||||
void WriteEnsureImageLoadingStarted(CodeBuilder builder, AnimatedVisualSourceInfo info)
|
||||
void WriteEnsureImageLoadingStarted(CodeBuilder builder, IAnimatedVisualSourceInfo info)
|
||||
{
|
||||
builder.WriteLine($"void AnimatedVisuals::{info.ClassName}::EnsureImageLoadingStarted()");
|
||||
builder.OpenScope();
|
||||
|
@ -573,7 +619,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
builder.WriteLine();
|
||||
}
|
||||
|
||||
void WriteHandleLoadCompleted(CodeBuilder builder, AnimatedVisualSourceInfo info)
|
||||
void WriteHandleLoadCompleted(CodeBuilder builder, IAnimatedVisualSourceInfo info)
|
||||
{
|
||||
builder.WriteLine($"void AnimatedVisuals::{info.ClassName}::HandleLoadCompleted(LoadedImageSurface^ sender, LoadedImageSourceLoadCompletedEventArgs^ e)");
|
||||
builder.OpenScope();
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
// 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.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information about code being generated for an IAnimatedVisual.
|
||||
/// </summary>
|
||||
#if PUBLIC_UIData
|
||||
public
|
||||
#endif
|
||||
interface IAnimatedVisualInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="IAnimatedVisualSourceInfo"/> describing the IAnimatedVisualSource that
|
||||
/// will source the IAnimatedVisual described by this object.
|
||||
/// </summary>
|
||||
IAnimatedVisualSourceInfo AnimatedVisualSourceInfo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the IAnimatedVisual class that will be exposed to users.
|
||||
/// </summary>
|
||||
string ClassName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the AnimatedVisual has LoadedImageSurface.
|
||||
/// </summary>
|
||||
bool HasLoadedImageSurface { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The UAP version required by the IAnimatedVisual.
|
||||
/// </summary>
|
||||
uint RequiredUapVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the XAML LoadedImageSurface nodes of the AnimatedVisual.
|
||||
/// </summary>
|
||||
IReadOnlyList<LoadedImageSurfaceInfo> LoadedImageSurfaceNodes { get; }
|
||||
}
|
||||
}
|
|
@ -4,99 +4,81 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using static Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen.InstantiatorGeneratorBase;
|
||||
|
||||
namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information about code being generated for an IAnimatedVisualSource.
|
||||
/// </summary>
|
||||
public sealed class AnimatedVisualSourceInfo
|
||||
#if PUBLIC_UIData
|
||||
public
|
||||
#endif
|
||||
interface IAnimatedVisualSourceInfo
|
||||
{
|
||||
internal AnimatedVisualSourceInfo(
|
||||
string className,
|
||||
string reusableExpressionAnimationFieldName,
|
||||
string durationTicksFieldName,
|
||||
Vector2 compositionDeclaredSize,
|
||||
bool usesCanvas,
|
||||
bool usesCanvasEffects,
|
||||
bool usesCanvasGeometry,
|
||||
bool usesNamespaceWindowsUIXamlMedia,
|
||||
bool usesStreams,
|
||||
bool usesCompositeEffect,
|
||||
IReadOnlyList<LoadedImageSurfaceInfo> loadedImageSurfaceNodes)
|
||||
{
|
||||
ClassName = className;
|
||||
ReusableExpressionAnimationFieldName = reusableExpressionAnimationFieldName;
|
||||
DurationTicksFieldName = durationTicksFieldName;
|
||||
CompositionDeclaredSize = compositionDeclaredSize;
|
||||
UsesCanvas = usesCanvas;
|
||||
UsesCanvasEffects = usesCanvasEffects;
|
||||
UsesCanvasGeometry = usesCanvasGeometry;
|
||||
UsesNamespaceWindowsUIXamlMedia = usesNamespaceWindowsUIXamlMedia;
|
||||
UsesStreams = usesStreams;
|
||||
UsesCompositeEffect = usesCompositeEffect;
|
||||
LoadedImageSurfaceNodes = loadedImageSurfaceNodes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the IAnimatedVisualSource class that will be exposed to users.
|
||||
/// </summary>
|
||||
public string ClassName { get; }
|
||||
string ClassName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the field in the instantiator class that holds the reusable ExpressionAnimation.
|
||||
/// </summary>
|
||||
public string ReusableExpressionAnimationFieldName { get; }
|
||||
string ReusableExpressionAnimationFieldName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the constant holding the duration of the composition in ticks.
|
||||
/// </summary>
|
||||
public string DurationTicksFieldName { get; }
|
||||
string DurationTicksFieldName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the declared size of the composition.
|
||||
/// </summary>
|
||||
public Vector2 CompositionDeclaredSize { get; }
|
||||
Vector2 CompositionDeclaredSize { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the composition depends on the Microsoft.Graphics.Canvas namespace.
|
||||
/// </summary>
|
||||
public bool UsesCanvas { get; }
|
||||
bool UsesCanvas { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the composition depends on the Microsoft.Graphics.Canvas.Effects namespace.
|
||||
/// </summary>
|
||||
public bool UsesCanvasEffects { get; }
|
||||
bool UsesCanvasEffects { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the composition depends on the Microsoft.Graphics.Canvas.Geometry namespace.
|
||||
/// </summary>
|
||||
public bool UsesCanvasGeometry { get; }
|
||||
bool UsesCanvasGeometry { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the composition uses the Windows.UI.Xaml.Media namespace.
|
||||
/// </summary>
|
||||
public bool UsesNamespaceWindowsUIXamlMedia { get; }
|
||||
bool UsesNamespaceWindowsUIXamlMedia { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the composition uses streams.
|
||||
/// </summary>
|
||||
public bool UsesStreams { get; }
|
||||
bool UsesStreams { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the composition has LoadedImageSurface.
|
||||
/// </summary>
|
||||
public bool HasLoadedImageSurface => LoadedImageSurfaceNodes.Count > 0;
|
||||
bool HasLoadedImageSurface { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the LoadedImageSurface nodes of the composition.
|
||||
/// Gets the <see cref="IAnimatedVisualInfo"/> objects that describe each IAnimatedVisual
|
||||
/// class that can be returned from the generated code.
|
||||
/// </summary>
|
||||
internal IReadOnlyList<LoadedImageSurfaceInfo> LoadedImageSurfaceNodes { get; }
|
||||
IReadOnlyList<IAnimatedVisualInfo> AnimatedVisualInfos { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the composition depends on a composite effect.
|
||||
/// </summary>
|
||||
public bool UsesCompositeEffect { get; }
|
||||
bool UsesCompositeEffect { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the XAML LoadedImageSurface nodes of the composition.
|
||||
/// </summary>
|
||||
IReadOnlyList<LoadedImageSurfaceInfo> LoadedImageSurfaceNodes { get; }
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
#if PUBLIC_UIData
|
||||
public
|
||||
#endif
|
||||
abstract class InstantiatorGeneratorBase
|
||||
abstract class InstantiatorGeneratorBase : IAnimatedVisualSourceInfo
|
||||
{
|
||||
// The name of the field holding the singleton reusable ExpressionAnimation.
|
||||
const string SingletonExpressionAnimationName = "_reusableExpressionAnimation";
|
||||
|
@ -164,28 +164,28 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
/// </summary>
|
||||
protected abstract void WriteFileStart(
|
||||
CodeBuilder builder,
|
||||
AnimatedVisualSourceInfo info);
|
||||
IAnimatedVisualSourceInfo info);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the start of the IAnimatedVisual implementation class.
|
||||
/// </summary>
|
||||
protected abstract void WriteAnimatedVisualStart(
|
||||
CodeBuilder builder,
|
||||
AnimatedVisualInfo info);
|
||||
IAnimatedVisualInfo info);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the end of the IAnimatedVisual implementation class.
|
||||
/// </summary>
|
||||
protected abstract void WriteAnimatedVisualEnd(
|
||||
CodeBuilder builder,
|
||||
AnimatedVisualInfo info);
|
||||
IAnimatedVisualInfo info);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the end of the file.
|
||||
/// </summary>
|
||||
protected abstract void WriteFileEnd(
|
||||
CodeBuilder builder,
|
||||
AnimatedVisualSourceInfo info);
|
||||
IAnimatedVisualSourceInfo info);
|
||||
|
||||
/// <summary>
|
||||
/// Writes CanvasGeometery.Combination factory code.
|
||||
|
@ -309,21 +309,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
{
|
||||
var builder = new CodeBuilder();
|
||||
|
||||
// This object contains information about the AnimatedVisualSourceInfo for use during codegen.
|
||||
var animatedVisualSourceInfo = new AnimatedVisualSourceInfo(
|
||||
className: _className,
|
||||
reusableExpressionAnimationFieldName: SingletonExpressionAnimationName,
|
||||
durationTicksFieldName: DurationTicksFieldName,
|
||||
compositionDeclaredSize: _compositionDeclaredSize,
|
||||
usesCanvas: _animatedVisualGenerators.Any(f => f.UsesCanvas),
|
||||
usesCanvasEffects: _animatedVisualGenerators.Any(f => f.UsesCanvasEffects),
|
||||
usesCanvasGeometry: _animatedVisualGenerators.Any(f => f.UsesCanvasGeometry),
|
||||
usesNamespaceWindowsUIXamlMedia: _animatedVisualGenerators.Any(f => f.UsesNamespaceWindowsUIXamlMedia),
|
||||
usesStreams: _animatedVisualGenerators.Any(f => f.UsesStreams),
|
||||
loadedImageSurfaceNodes: GetLoadedImageSurfaceInfos(),
|
||||
usesCompositeEffect: _animatedVisualGenerators.Any(f => f.UsesCompositeEffect)
|
||||
);
|
||||
|
||||
// Write the auto-generated warning comment.
|
||||
foreach (var line in AutoGeneratedHeaderText)
|
||||
{
|
||||
|
@ -331,7 +316,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
}
|
||||
|
||||
// Write the start of the file. This is everything up to the start of the AnimatedVisual class.
|
||||
WriteFileStart(builder, animatedVisualSourceInfo);
|
||||
WriteFileStart(builder, this);
|
||||
|
||||
// Write the LoadedImageSurface byte arrays into the outer (IAnimatedVisualSource) class.
|
||||
{
|
||||
|
@ -356,45 +341,22 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
}
|
||||
}
|
||||
|
||||
var requiredUapVersion = _animatedVisualGenerators.Select(f => f.RequiredUapVersion).Max();
|
||||
|
||||
// Write the IsRuntimeCompatible() method.
|
||||
builder.WriteLine("static bool IsRuntimeCompatible()");
|
||||
builder.OpenScope();
|
||||
#if false
|
||||
// TODO This is the implementation for the new UAP contract way of checking versions. It will replace the IsRuntimeCompatible method shortly.
|
||||
//builder.WriteLine($"return Windows{ScopeResolve}Foundation{ScopeResolve}Metadata{ScopeResolve}ApiInformation{ScopeResolve}IsApiContractPresent(\"Windows.Foundation.UniversalApiContract\", {requiredUapVersion});");
|
||||
//builder.CloseScope();
|
||||
#endif
|
||||
builder.WriteLine($"if (!Windows{_stringifier.ScopeResolve}Foundation{_stringifier.ScopeResolve}Metadata{_stringifier.ScopeResolve}ApiInformation{_stringifier.ScopeResolve}IsTypePresent(\"Windows.UI.Composition.CompositionGeometricClip\"))");
|
||||
builder.OpenScope();
|
||||
builder.WriteLine("return false;");
|
||||
builder.CloseScope();
|
||||
|
||||
if (requiredUapVersion > 7)
|
||||
{
|
||||
builder.WriteLine($"if (!Windows{_stringifier.ScopeResolve}Foundation{_stringifier.ScopeResolve}Metadata{_stringifier.ScopeResolve}ApiInformation{_stringifier.ScopeResolve}IsTypePresent(\"Windows.UI.Composition.CompositionVisualSurface\"))");
|
||||
builder.OpenScope();
|
||||
builder.WriteLine("return false;");
|
||||
builder.CloseScope();
|
||||
}
|
||||
|
||||
builder.WriteLine("return true;");
|
||||
builder.CloseScope();
|
||||
builder.WriteLine();
|
||||
|
||||
// Write each AnimatedVisual class.
|
||||
var firstAnimatedVisualWritten = false;
|
||||
foreach (var animatedVisualGenerator in _animatedVisualGenerators)
|
||||
{
|
||||
animatedVisualGenerator.WriteAnimatedVisualCode(builder, animatedVisualSourceInfo);
|
||||
if (firstAnimatedVisualWritten)
|
||||
{
|
||||
// Put a blank line between each AnimatedVisual class.
|
||||
builder.WriteLine();
|
||||
}
|
||||
|
||||
// TODO - this "break" is just to get compatible output during testing. Remove it to get all the versions.
|
||||
// TODO - add a WriteLine between each version (i.e. before the second one).
|
||||
break;
|
||||
animatedVisualGenerator.WriteAnimatedVisualCode(builder);
|
||||
firstAnimatedVisualWritten = true;
|
||||
}
|
||||
|
||||
// Write the end of the file.
|
||||
WriteFileEnd(builder, animatedVisualSourceInfo);
|
||||
WriteFileEnd(builder, this);
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
@ -488,6 +450,32 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
|
||||
string ScopeResolve => _stringifier.ScopeResolve;
|
||||
|
||||
string IAnimatedVisualSourceInfo.ClassName => _className;
|
||||
|
||||
string IAnimatedVisualSourceInfo.ReusableExpressionAnimationFieldName => SingletonExpressionAnimationName;
|
||||
|
||||
string IAnimatedVisualSourceInfo.DurationTicksFieldName => DurationTicksFieldName;
|
||||
|
||||
Vector2 IAnimatedVisualSourceInfo.CompositionDeclaredSize => _compositionDeclaredSize;
|
||||
|
||||
bool IAnimatedVisualSourceInfo.UsesCanvas => _animatedVisualGenerators.Any(f => f.UsesCanvas);
|
||||
|
||||
bool IAnimatedVisualSourceInfo.UsesCanvasEffects => _animatedVisualGenerators.Any(f => f.UsesCanvasEffects);
|
||||
|
||||
bool IAnimatedVisualSourceInfo.UsesCanvasGeometry => _animatedVisualGenerators.Any(f => f.UsesCanvasGeometry);
|
||||
|
||||
bool IAnimatedVisualSourceInfo.UsesNamespaceWindowsUIXamlMedia => _animatedVisualGenerators.Any(f => f.UsesNamespaceWindowsUIXamlMedia);
|
||||
|
||||
bool IAnimatedVisualSourceInfo.UsesStreams => _animatedVisualGenerators.Any(f => f.UsesStreams);
|
||||
|
||||
IReadOnlyList<IAnimatedVisualInfo> IAnimatedVisualSourceInfo.AnimatedVisualInfos => _animatedVisualGenerators;
|
||||
|
||||
bool IAnimatedVisualSourceInfo.UsesCompositeEffect => _animatedVisualGenerators.Any(f => f.UsesCompositeEffect);
|
||||
|
||||
bool IAnimatedVisualSourceInfo.HasLoadedImageSurface => GetLoadedImageSurfaceInfos().Any();
|
||||
|
||||
IReadOnlyList<LoadedImageSurfaceInfo> IAnimatedVisualSourceInfo.LoadedImageSurfaceNodes => GetLoadedImageSurfaceInfos();
|
||||
|
||||
static LoadedImageSurfaceInfo LoadedImageSurfaceInfoFromObjectData(ObjectData node)
|
||||
{
|
||||
if (!node.IsLoadedImageSurface)
|
||||
|
@ -511,48 +499,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
static IEnumerable<ObjectData> OrderByName(IEnumerable<ObjectData> nodes) =>
|
||||
nodes.OrderBy(n => n.Name, AlphanumericStringComparer.Instance);
|
||||
|
||||
/// <summary>
|
||||
/// Describes LoadedImageSurface objects in the composition.
|
||||
/// </summary>
|
||||
protected internal class LoadedImageSurfaceInfo
|
||||
{
|
||||
internal LoadedImageSurfaceInfo(
|
||||
string typeName,
|
||||
string name,
|
||||
string fieldName,
|
||||
string bytesFieldName,
|
||||
Uri imageUri,
|
||||
Wmd.LoadedImageSurface.LoadedImageSurfaceType loadedImageSurfaceType,
|
||||
byte[] bytes)
|
||||
{
|
||||
TypeName = typeName;
|
||||
Name = name;
|
||||
FieldName = fieldName;
|
||||
BytesFieldName = bytesFieldName;
|
||||
ImageUri = imageUri;
|
||||
LoadedImageSurfaceType = loadedImageSurfaceType;
|
||||
Bytes = bytes;
|
||||
}
|
||||
|
||||
public string TypeName { get; }
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public string FieldName { get; }
|
||||
|
||||
public string BytesFieldName { get; }
|
||||
|
||||
public Uri ImageUri { get; }
|
||||
|
||||
public Wmd.LoadedImageSurface.LoadedImageSurfaceType LoadedImageSurfaceType { get; }
|
||||
|
||||
public byte[] Bytes { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates an IAnimatedVisual implementation.
|
||||
/// </summary>
|
||||
sealed class AnimatedVisualGenerator
|
||||
sealed class AnimatedVisualGenerator : IAnimatedVisualInfo
|
||||
{
|
||||
readonly HashSet<(ObjectData, ObjectData)> _factoriesAlreadyCalled = new HashSet<(ObjectData, ObjectData)>();
|
||||
readonly InstantiatorGeneratorBase _owner;
|
||||
|
@ -647,6 +597,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
_rootNode.RequiresStorage = true;
|
||||
}
|
||||
|
||||
internal IAnimatedVisualInfo AnimatedVisualInfo => this;
|
||||
|
||||
// Returns the nodes that can be shared between multiple IAnimatedVisuals.
|
||||
internal IEnumerable<ObjectData> GetShareableNodes() => _nodes.Where(n => n.IsShareableNode);
|
||||
|
||||
|
@ -686,6 +638,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
|
||||
internal bool UsesCompositeEffect => _nodes.Where(n => n.UsesCompositeEffect).Any();
|
||||
|
||||
string ScopeResolve => _stringifier.ScopeResolve;
|
||||
|
||||
string Const(string value) => _stringifier.Const(value);
|
||||
|
||||
string Deref => _stringifier.Deref;
|
||||
|
@ -861,18 +815,15 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
WriteObjectFactoryStartWithoutCache(builder, node, parameters);
|
||||
}
|
||||
|
||||
internal void WriteAnimatedVisualCode(CodeBuilder builder, AnimatedVisualSourceInfo animatedVisualSourceInfo)
|
||||
internal void WriteAnimatedVisualCode(CodeBuilder builder)
|
||||
{
|
||||
_owner._currentAnimatedVisualGenerator = this;
|
||||
var animatedVisualInfo = new AnimatedVisualInfo(
|
||||
animatedVisualSourceInfo,
|
||||
className: "AnimatedVisual",
|
||||
loadedImageSurfaceNodes: GetLoadedImageSurfaceInfos().ToArray());
|
||||
|
||||
// Write the body of the AnimatedVisual class.
|
||||
_owner.WriteAnimatedVisualStart(builder, animatedVisualInfo);
|
||||
_owner.WriteAnimatedVisualStart(builder, this);
|
||||
|
||||
// Write fields for constant values.
|
||||
builder.WriteComment($"Animation duration: {_owner._compositionDuration.Ticks / (double)System.TimeSpan.TicksPerSecond,-1:N3} seconds.");
|
||||
WriteField(builder, Const(_stringifier.Int64TypeName), $"{DurationTicksFieldName} = {_stringifier.Int64(_owner._compositionDuration.Ticks)}");
|
||||
|
||||
// Write fields for each object that needs storage (i.e. objects that are
|
||||
|
@ -888,11 +839,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
// Write methods for each node.
|
||||
foreach (var node in _nodes)
|
||||
{
|
||||
WriteCodeForNode(builder, animatedVisualSourceInfo, node);
|
||||
WriteCodeForNode(builder, node);
|
||||
}
|
||||
|
||||
// Write the end of the AnimatedVisual class.
|
||||
_owner.WriteAnimatedVisualEnd(builder, animatedVisualInfo);
|
||||
_owner.WriteAnimatedVisualEnd(builder, this);
|
||||
|
||||
_owner._currentAnimatedVisualGenerator = null;
|
||||
}
|
||||
|
@ -913,7 +864,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
}
|
||||
|
||||
// Generates code for the given node. The code is written into the given CodeBuilder.
|
||||
void WriteCodeForNode(CodeBuilder builder, AnimatedVisualSourceInfo info, ObjectData node)
|
||||
void WriteCodeForNode(CodeBuilder builder, ObjectData node)
|
||||
{
|
||||
// Only generate if the node is not inlined into the caller.
|
||||
if (!node.Inlined)
|
||||
|
@ -2048,6 +1999,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
|||
builder.CloseScope();
|
||||
builder.WriteLine();
|
||||
}
|
||||
|
||||
IAnimatedVisualSourceInfo IAnimatedVisualInfo.AnimatedVisualSourceInfo => _owner;
|
||||
|
||||
string IAnimatedVisualInfo.ClassName => $"AnimatedVisual_UAPv{_requiredUapVersion}";
|
||||
|
||||
bool IAnimatedVisualInfo.HasLoadedImageSurface => GetLoadedImageSurfaceInfos().Any();
|
||||
|
||||
IReadOnlyList<LoadedImageSurfaceInfo> IAnimatedVisualInfo.LoadedImageSurfaceNodes => GetLoadedImageSurfaceInfos().ToArray();
|
||||
|
||||
uint IAnimatedVisualInfo.RequiredUapVersion => _requiredUapVersion;
|
||||
}
|
||||
|
||||
// Aggregates ObjectData nodes that are shared between different IAnimatedVisual instances,
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using Wmd = Microsoft.Toolkit.Uwp.UI.Lottie.WinUIXamlMediaData;
|
||||
|
||||
namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes LoadedImageSurface objects in the composition.
|
||||
/// </summary>
|
||||
#if PUBLIC_UIData
|
||||
public
|
||||
#endif
|
||||
sealed class LoadedImageSurfaceInfo
|
||||
{
|
||||
internal LoadedImageSurfaceInfo(
|
||||
string typeName,
|
||||
string name,
|
||||
string fieldName,
|
||||
string bytesFieldName,
|
||||
Uri imageUri,
|
||||
Wmd.LoadedImageSurface.LoadedImageSurfaceType loadedImageSurfaceType,
|
||||
byte[] bytes)
|
||||
{
|
||||
TypeName = typeName;
|
||||
Name = name;
|
||||
FieldName = fieldName;
|
||||
BytesFieldName = bytesFieldName;
|
||||
ImageUri = imageUri;
|
||||
LoadedImageSurfaceType = loadedImageSurfaceType;
|
||||
Bytes = bytes;
|
||||
}
|
||||
|
||||
public string TypeName { get; }
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public string FieldName { get; }
|
||||
|
||||
public string BytesFieldName { get; }
|
||||
|
||||
public Uri ImageUri { get; }
|
||||
|
||||
public Wmd.LoadedImageSurface.LoadedImageSurfaceType LoadedImageSurfaceType { get; }
|
||||
|
||||
public byte[] Bytes { get; }
|
||||
}
|
||||
}
|
|
@ -7,15 +7,16 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\AlphanumericStringComparer.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\AnimatedVisualInfo.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\AnimatedVisualSourceInfo.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\CanonicalizedNode.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\Canonicalizer.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\CodeBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\CppStringifier.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\CSharpInstantiatorGenerator.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\CxInstantiatorGenerator.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\IAnimatedVisualInfo.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\IAnimatedVisualSourceInfo.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\InstantiatorGeneratorBase.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\LoadedImageSurfaceInfo.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\NodeNamer.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\Optimizer.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CodeGen\Stringifier.cs" />
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
@echo off
|
||||
setlocal
|
||||
if '%1' EQU '' (
|
||||
echo No directory provided.
|
||||
goto :eof
|
||||
)
|
||||
|
||||
echo Compiling all .cs files under %1
|
||||
|
||||
:: The C# compiler on your machine.
|
||||
set cscPath="%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\Roslyn\csc.exe"
|
||||
|
||||
:: WinUI local copy. Needed because we can't mock IDynamicAnimatedVisualSource in C# due to the use of WinRT events.
|
||||
set winuiWinmdPath="%homedrive%%homepath%\.nuget\packages\microsoft.ui.xaml\2.2.190917002\lib\uap10.0\Microsoft.UI.Xaml.winmd"
|
||||
|
||||
for /r "%1" %%F in (*.cs) do @%cscPath% /noconfig @CompileDirectory.rsp /reference:%winuiWinmdPath% "%%F" /out:"%%~dpnF.dll" & del "%%~dpnF.dll"
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
# Do not show the csc signon.
|
||||
/nologo
|
||||
# Do not emit PDB
|
||||
/debug-
|
||||
/nowarn:2008,1701,1702,2008
|
||||
/nostdlib+
|
||||
/platform:x86
|
||||
/errorreport:prompt
|
||||
/warn:0
|
||||
/define:DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP;CODE_ANALYSIS
|
||||
/errorendlocation
|
||||
/preferreduilang:en-US
|
||||
/highentropyva+
|
||||
/lib:"C:\Program Files (x86)\Microsoft SDKs\UWPNuGetPackages\microsoft.netcore.universalwindowsplatform\6.2.9\ref\uap10.0.15138"
|
||||
/reference:"Microsoft.CSharp.dll"
|
||||
/reference:"C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\XamlCompiler\Microsoft.UI.Xaml.Markup.winmd"
|
||||
/reference:"Microsoft.VisualBasic.dll"
|
||||
/reference:"Microsoft.Win32.Primitives.dll"
|
||||
/reference:"mscorlib.dll"
|
||||
/reference:"netstandard.dll"
|
||||
/reference:"System.AppContext.dll"
|
||||
/reference:"System.Buffers.dll"
|
||||
/reference:"System.Collections.Concurrent.dll"
|
||||
/reference:"System.Collections.dll"
|
||||
/reference:"System.Collections.Immutable.dll"
|
||||
/reference:"System.Collections.NonGeneric.dll"
|
||||
/reference:"System.Collections.Specialized.dll"
|
||||
/reference:"System.ComponentModel.Annotations.dll"
|
||||
/reference:"System.ComponentModel.Composition.dll"
|
||||
/reference:"System.ComponentModel.DataAnnotations.dll"
|
||||
/reference:"System.ComponentModel.dll"
|
||||
/reference:"System.ComponentModel.EventBasedAsync.dll"
|
||||
/reference:"System.ComponentModel.Primitives.dll"
|
||||
/reference:"System.ComponentModel.TypeConverter.dll"
|
||||
/reference:"System.Configuration.dll"
|
||||
/reference:"System.Core.dll"
|
||||
/reference:"System.Data.Common.dll"
|
||||
/reference:"System.Data.dll"
|
||||
/reference:"System.Diagnostics.Contracts.dll"
|
||||
/reference:"System.Diagnostics.Debug.dll"
|
||||
/reference:"System.Diagnostics.FileVersionInfo.dll"
|
||||
/reference:"System.Diagnostics.Process.dll"
|
||||
/reference:"System.Diagnostics.StackTrace.dll"
|
||||
/reference:"System.Diagnostics.TextWriterTraceListener.dll"
|
||||
/reference:"System.Diagnostics.Tools.dll"
|
||||
/reference:"System.Diagnostics.TraceSource.dll"
|
||||
/reference:"System.Diagnostics.Tracing.dll"
|
||||
/reference:"System.dll"
|
||||
/reference:"System.Drawing.dll"
|
||||
/reference:"System.Drawing.Primitives.dll"
|
||||
/reference:"System.Dynamic.Runtime.dll"
|
||||
/reference:"System.Globalization.Calendars.dll"
|
||||
/reference:"System.Globalization.dll"
|
||||
/reference:"System.Globalization.Extensions.dll"
|
||||
/reference:"System.IO.dll"
|
||||
/reference:"System.IO.IsolatedStorage.dll"
|
||||
/reference:"System.IO.MemoryMappedFiles.dll"
|
||||
/reference:"System.IO.Pipes.dll"
|
||||
/reference:"System.IO.Ports.dll"
|
||||
/reference:"System.IO.UnmanagedMemoryStream.dll"
|
||||
/reference:"System.Linq.dll"
|
||||
/reference:"System.Linq.Expressions.dll"
|
||||
/reference:"System.Linq.Parallel.dll"
|
||||
/reference:"System.Linq.Queryable.dll"
|
||||
/reference:"System.Net.dll"
|
||||
/reference:"System.Net.NameResolution.dll"
|
||||
/reference:"System.Net.NetworkInformation.dll"
|
||||
/reference:"System.Net.Primitives.dll"
|
||||
/reference:"System.Net.Requests.dll"
|
||||
/reference:"System.Net.Security.dll"
|
||||
/reference:"System.Numerics.dll"
|
||||
/reference:"System.Numerics.Vectors.dll"
|
||||
/reference:"System.Numerics.Vectors.WindowsRuntime.dll"
|
||||
/reference:"System.ObjectModel.dll"
|
||||
/reference:"System.Reflection.Context.dll"
|
||||
/reference:"System.Reflection.DispatchProxy.dll"
|
||||
/reference:"System.Reflection.dll"
|
||||
/reference:"System.Reflection.Extensions.dll"
|
||||
/reference:"System.Reflection.Metadata.dll"
|
||||
/reference:"System.Reflection.Primitives.dll"
|
||||
/reference:"System.Reflection.TypeExtensions.dll"
|
||||
/reference:"System.Resources.Reader.dll"
|
||||
/reference:"System.Resources.ResourceManager.dll"
|
||||
/reference:"System.Resources.Writer.dll"
|
||||
/reference:"System.Runtime.CompilerServices.VisualC.dll"
|
||||
/reference:"System.Runtime.dll"
|
||||
/reference:"System.Runtime.Extensions.dll"
|
||||
/reference:"System.Runtime.Handles.dll"
|
||||
/reference:"System.Runtime.InteropServices.dll"
|
||||
/reference:"System.Runtime.InteropServices.RuntimeInformation.dll"
|
||||
/reference:"System.Runtime.InteropServices.WindowsRuntime.dll"
|
||||
/reference:"System.Runtime.Numerics.dll"
|
||||
/reference:"System.Runtime.Serialization.dll"
|
||||
/reference:"System.Runtime.Serialization.Formatters.dll"
|
||||
/reference:"System.Runtime.Serialization.Json.dll"
|
||||
/reference:"System.Runtime.Serialization.Primitives.dll"
|
||||
/reference:"System.Runtime.Serialization.Xml.dll"
|
||||
/reference:"System.Runtime.WindowsRuntime.dll"
|
||||
/reference:"System.Runtime.WindowsRuntime.UI.Xaml.dll"
|
||||
/reference:"System.Security.AccessControl.dll"
|
||||
/reference:"System.Security.Claims.dll"
|
||||
/reference:"System.Security.Cryptography.Algorithms.dll"
|
||||
/reference:"System.Security.Cryptography.Cng.dll"
|
||||
/reference:"System.Security.Cryptography.Csp.dll"
|
||||
/reference:"System.Security.Cryptography.Encoding.dll"
|
||||
/reference:"System.Security.Cryptography.Primitives.dll"
|
||||
/reference:"System.Security.Cryptography.X509Certificates.dll"
|
||||
/reference:"System.Security.dll"
|
||||
/reference:"System.Security.Principal.dll"
|
||||
/reference:"System.Security.Principal.Windows.dll"
|
||||
/reference:"System.Security.SecureString.dll"
|
||||
/reference:"System.ServiceModel.dll"
|
||||
/reference:"System.ServiceModel.Duplex.dll"
|
||||
/reference:"System.ServiceModel.Http.dll"
|
||||
/reference:"System.ServiceModel.NetTcp.dll"
|
||||
/reference:"System.ServiceModel.Primitives.dll"
|
||||
/reference:"System.ServiceModel.Security.dll"
|
||||
/reference:"System.ServiceModel.Web.dll"
|
||||
/reference:"System.ServiceProcess.dll"
|
||||
/reference:"System.Text.Encoding.CodePages.dll"
|
||||
/reference:"System.Text.Encoding.dll"
|
||||
/reference:"System.Text.Encoding.Extensions.dll"
|
||||
/reference:"System.Text.RegularExpressions.dll"
|
||||
/reference:"System.Threading.dll"
|
||||
/reference:"System.Threading.Overlapped.dll"
|
||||
/reference:"System.Threading.Tasks.Dataflow.dll"
|
||||
/reference:"System.Threading.Tasks.dll"
|
||||
/reference:"System.Threading.Tasks.Parallel.dll"
|
||||
/reference:"System.Threading.Thread.dll"
|
||||
/reference:"System.Threading.ThreadPool.dll"
|
||||
/reference:"System.Threading.Timer.dll"
|
||||
/reference:"System.Transactions.dll"
|
||||
/reference:"System.Transactions.Local.dll"
|
||||
/reference:"System.ValueTuple.dll"
|
||||
/reference:"System.Web.dll"
|
||||
/reference:"System.Web.HttpUtility.dll"
|
||||
/reference:"System.Windows.dll"
|
||||
/reference:"WindowsBase.dll"
|
||||
/reference:"C:\Program Files (x86)\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.FoundationContract\3.0.0.0\Windows.Foundation.FoundationContract.winmd"
|
||||
/reference:"C:\Program Files (x86)\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.UniversalApiContract\8.0.0.0\Windows.Foundation.UniversalApiContract.winmd"
|
||||
/reference:"C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.18362.0\Facade\Windows.winmd"
|
||||
/ruleset:"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Team Tools\Static Analysis Tools\\Rule Sets\MinimumRecommendedRules.ruleset"
|
||||
/subsystemversion:6.02
|
||||
/target:library
|
||||
/utf8output
|
||||
/langversion:7.3
|
||||
Mocks.cs
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
// 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.
|
||||
|
||||
// This file contains mocks of Win2D for use when testing that LottieGen's output is compilable.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Metadata;
|
||||
using Windows.Graphics;
|
||||
using Windows.Graphics.Effects;
|
||||
using Windows.UI.Composition;
|
||||
|
||||
namespace Microsoft.Graphics.Canvas
|
||||
{
|
||||
enum CanvasComposite
|
||||
{
|
||||
DestinationIn,
|
||||
DestinationOut,
|
||||
}
|
||||
}
|
||||
|
||||
namespace Microsoft.Graphics.Canvas.Effects
|
||||
{
|
||||
class CompositeEffect : Windows.Graphics.Effects.IGraphicsEffect
|
||||
{
|
||||
public CanvasComposite Mode { get; set; }
|
||||
public string Name { get; set; }
|
||||
public IList<IGraphicsEffectSource> Sources { get; }
|
||||
}
|
||||
}
|
||||
|
||||
namespace Microsoft.Graphics.Canvas.Geometry
|
||||
{
|
||||
enum CanvasFigureLoop
|
||||
{
|
||||
Open,
|
||||
Closed,
|
||||
}
|
||||
|
||||
enum CanvasFilledRegionDetermination
|
||||
{
|
||||
Winding,
|
||||
Alternate,
|
||||
}
|
||||
|
||||
enum CanvasGeometryCombine
|
||||
{
|
||||
Intersect,
|
||||
Xor,
|
||||
Exclude,
|
||||
Union,
|
||||
}
|
||||
|
||||
class CanvasGeometry : IGeometrySource2D
|
||||
{
|
||||
public static CanvasGeometry CreateEllipse(object arg0, float arg1, float arg2, float arg3, float arg4) => null;
|
||||
public static CanvasGeometry CreateGroup(object arg0, CanvasGeometry[] arg1) => null;
|
||||
public static CanvasGeometry CreateGroup(object arg0, CanvasGeometry[] arg1, CanvasFilledRegionDetermination arg3) => null;
|
||||
public static CanvasGeometry CreatePath(CanvasPathBuilder builder) => null;
|
||||
public static CanvasGeometry CreateRoundedRectangle(object arg0, float arg1, float arg2, float arg3, float arg4, float arg5, float arg6) => null;
|
||||
public CanvasGeometry CombineWith(CanvasGeometry arg) => null;
|
||||
public CanvasGeometry CombineWith(CanvasGeometry otherGeometry, Matrix3x2 otherGeometryTransform, CanvasGeometryCombine combine) => null;
|
||||
public CanvasGeometry Transform(Matrix3x2 transform) => null;
|
||||
}
|
||||
|
||||
class CanvasPathBuilder : IDisposable
|
||||
{
|
||||
public CanvasPathBuilder(object device) { }
|
||||
public void AddCubicBezier(Vector2 arg0, Vector2 arg1, Vector2 arg2) { }
|
||||
public void AddLine(Vector2 value) { }
|
||||
public void BeginFigure(Vector2 arg) { }
|
||||
public void EndFigure(CanvasFigureLoop arg) { }
|
||||
public void SetFilledRegionDetermination(CanvasFilledRegionDetermination arg) { }
|
||||
void IDisposable.Dispose() => throw new NotImplementedException();
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче