internal ContentFactory(LottieVisualDiagnostics diagnostics)
 {
     _diagnostics = diagnostics;
 }
Beispiel #2
0
        internal async Task <ContentFactory> LoadAsync(LottieVisualOptions options)
        {
            LottieVisualDiagnostics diagnostics = null;
            var timeMeasurer = TimeMeasurer.Create();

            if (options.HasFlag(LottieVisualOptions.IncludeDiagnostics))
            {
                diagnostics = new LottieVisualDiagnostics {
                    Options = options
                };
            }

            var result = new ContentFactory(diagnostics);

            // Get the file name and JSON contents.
            (var fileName, var jsonStream) = await GetJsonStreamAsync();

            if (diagnostics != null)
            {
                diagnostics.FileName = fileName;
                diagnostics.ReadTime = timeMeasurer.GetElapsedAndRestart();
            }

            if (jsonStream is null)
            {
                // Failed to load ...
                return(result);
            }

            // Parsing large Lottie files can take significant time. Do it on
            // another thread.
            LottieComposition lottieComposition = null;

            await CheckedAwaitAsync(Task.Run(() =>
            {
                lottieComposition =
                    LottieCompositionReader.ReadLottieCompositionFromJsonStream(
                        jsonStream,
                        LottieCompositionReader.Options.IgnoreMatchNames,
                        out var readerIssues);

                if (diagnostics != null)
                {
                    diagnostics.JsonParsingIssues = ToIssues(readerIssues);
                }
            }));

            if (diagnostics != null)
            {
                diagnostics.ParseTime = timeMeasurer.GetElapsedAndRestart();
            }

            if (lottieComposition is null)
            {
                // Failed to load...
                return(result);
            }

            if (diagnostics != null)
            {
                // Save the LottieComposition in the diagnostics so that the xml and codegen
                // code can be derived from it.
                diagnostics.LottieComposition = lottieComposition;

                // Validate the composition and report if issues are found.
                diagnostics.LottieValidationIssues = ToIssues(LottieCompositionValidator.Validate(lottieComposition));
                diagnostics.ValidationTime         = timeMeasurer.GetElapsedAndRestart();
            }

            result.SetDimensions(
                width: lottieComposition.Width,
                height: lottieComposition.Height,
                duration: lottieComposition.Duration);

            // Translating large Lotties can take significant time. Do it on another thread.
            WinCompData.Visual wincompDataRootVisual = null;
            uint requiredUapVersion  = 0;
            var  optimizationEnabled = options.HasFlag(LottieVisualOptions.Optimize);

            TranslationResult translationResult;

            await CheckedAwaitAsync(Task.Run(() =>
            {
                // Generate property bindings only if the diagnostics object was requested.
                // This is because the binding information is output in the diagnostics object
                // so there's no point translating bindings if the diagnostics object
                // isn't available.
                var makeColorsBindable = diagnostics != null && options.HasFlag(LottieVisualOptions.BindableColors);
                translationResult      = LottieToWinCompTranslator.TryTranslateLottieComposition(
                    lottieComposition: lottieComposition,
                    configuration: new TranslatorConfiguration
                {
                    TranslatePropertyBindings = makeColorsBindable,
                    GenerateColorBindings     = makeColorsBindable,
                    TargetUapVersion          = GetCurrentUapVersion(),
                });

                wincompDataRootVisual = translationResult.RootVisual;
                requiredUapVersion    = translationResult.MinimumRequiredUapVersion;

                if (diagnostics != null)
                {
                    diagnostics.TranslationIssues = ToIssues(translationResult.TranslationIssues);
                    diagnostics.TranslationTime   = timeMeasurer.GetElapsedAndRestart();

                    // If there were any property bindings, save them in the Diagnostics object.
                    if (translationResult.SourceMetadata.TryGetValue(s_propertyBindingNamesKey, out var propertyBindingNames))
                    {
                        diagnostics.ThemePropertyBindings = (IReadOnlyList <PropertyBinding>)propertyBindingNames;
                    }
                }

                // Optimize the resulting translation. This will usually significantly reduce the size of
                // the Composition code, however it might slow down loading too much on complex Lotties.
                if (wincompDataRootVisual != null && optimizationEnabled)
                {
                    // Optimize.
                    wincompDataRootVisual = UIData.Tools.Optimizer.Optimize(wincompDataRootVisual, ignoreCommentProperties: true);

                    if (diagnostics != null)
                    {
                        diagnostics.OptimizationTime = timeMeasurer.GetElapsedAndRestart();
                    }
                }
            }));

            if (wincompDataRootVisual is null)
            {
                // Failed.
                return(result);
            }
            else
            {
                if (diagnostics != null)
                {
                    // Save the root visual so diagnostics can generate XML and codegen.
                    diagnostics.RootVisual         = wincompDataRootVisual;
                    diagnostics.RequiredUapVersion = requiredUapVersion;
                }

                result.SetRootVisual(wincompDataRootVisual);
                return(result);
            }
        }