Skip to content

Commit

Permalink
Fix for #406 (#433)
Browse files Browse the repository at this point in the history
When using the "-AdditionalInterface" parameter in LottieGen (which causes the generated code to declare that it implements interfaces that it otherwise doesn't know about), the interface needs to be known to the generated IDL file.
There are 2 ways that the IDL may know about the interface:
1. The interface may exist in a .winmd file that is referenced by the project.
2. The interface may be defined in the project using an IDL file.

LottieGen doesn't know which case the user requires. Previously we were assuming case 2 which causes problems if the interface is not in an IDL file.
Rather than requiring the user to tell LottieGen which case is being used, we know wrap the import in a condition that depends on the existence of the file. This should handle both cases seamlessly.
  • Loading branch information
Simeon authored Mar 8, 2021
1 parent e7befb4 commit 42a35f0
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 12 deletions.
4 changes: 3 additions & 1 deletion source/LottieReader/Serialization/Animatables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#nullable enable

using System;
using System.Collections.Generic;
using System.Linq;
Expand Down Expand Up @@ -588,7 +590,7 @@ IEnumerable<KeyFrame<T>> ReadKeyFrames(
// An initial keyframe is created to describe the initial value. It has no easing function.
//
// -
T endValue = default(T);
T? endValue = default(T);

// The initial keyframe has the same value as the initial value. Easing therefore doesn't
// matter, but might as well use hold as it's the simplest (it does not interpolate).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,18 +113,19 @@ string GenerateIdlText()
{
var builder = new CodeBuilder();
builder.WriteLine(string.Join("\r\n", AutoGeneratedHeaderText));
var idlImports = new List<string>();

idlImports.AddRange(SourceInfo.AdditionalInterfaces.Select(n => n.NormalizedQualifiedName));

if (idlImports.Any())
if (SourceInfo.AdditionalInterfaces.Any())
{
foreach (var import in idlImports)
foreach (var import in SourceInfo.AdditionalInterfaces.Select(n => n.NormalizedQualifiedName))
{
builder.WriteLine($"import \"{import}.idl\";");
// Import an IDL file for the definition of each additional interface.
// We don't know whether the user defined the interface in IDL or
// whether they are reusing an interface that is already defined in
// a .winmd, so be resilient to both cases by only importing the IDL
// file if it exists.
WriteImportFileIfExists(builder, $"{import}.idl");
builder.WriteLine();
}

builder.WriteLine();
}

builder.WriteLine($"namespace {SourceInfo.Namespace}");
Expand Down Expand Up @@ -558,9 +559,7 @@ protected override void WriteImplementationFileStart(CodeBuilder builder)
// {_cppwinrtGeneratedFileNameBase}.cpp is needed for UWP, but is not usually generated by
// "cppwinrt for WIN32 apps. The file is related to how cppwinrt makes types activatable.
// If the file exists, we'll include it.
builder.WriteLine($"#if __has_include(\"{_cppwinrtGeneratedFileNameBase}.cpp\")");
builder.WriteLine($"#include \"{_cppwinrtGeneratedFileNameBase}.cpp\"");
builder.WriteLine("#endif");
WriteIncludeFileIfExists(builder, $"{_cppwinrtGeneratedFileNameBase}.cpp");
builder.WriteLine("#include <winrt/Windows.Foundation.Metadata.h>");
builder.WriteLine("#include <winrt/Windows.Foundation.Collections.h>");

Expand Down Expand Up @@ -1429,6 +1428,28 @@ protected override void WriteCanvasGeometryGroupFactory(CodeBuilder builder, Can
builder.WriteLine($"auto result = {FieldAssignment(fieldName)}winrt::make_self<CanvasGeometry>(group);");
}

// Writes code that is only included if the given file exists.
static void WriteIncludeFileIfExists(CodeBuilder builder, string fileName)
=> WriteIfFileExists(
builder,
fileName,
() => builder.WriteLine($"#include \"{fileName}\""));

// Writes code that is only imported if the given file exists.
static void WriteImportFileIfExists(CodeBuilder builder, string fileName)
=> WriteIfFileExists(
builder,
fileName,
() => builder.WriteLine($"import \"{fileName}\";"));

// Writes code that is only compiled if the given file exists.
static void WriteIfFileExists(CodeBuilder builder, string fileName, Action action)
{
builder.WriteLine($"#if __has_include (\"{fileName}\")");
action();
builder.WriteLine("#endif");
}

string QualifiedTypeName(PropertySetValueType propertySetValueType)
=> propertySetValueType switch
{
Expand Down

0 comments on commit 42a35f0

Please sign in to comment.