Ejemplo n.º 1
0
 void WriteAnimatedVisualCall(CodeBuilder builder, CodeGenInfo info)
 {
     builder.WriteLine("new AnimatedVisual(compositor,");
     builder.Indent();
     builder.WriteCommaSeparatedLines(info.LoadedImageSurfaceNodes.Select(n => n.FieldName));
     builder.WriteLine(");");
     builder.UnIndent();
 }
Ejemplo n.º 2
0
        /// <inheritdoc/>
        // Called by the base class to write the end of the file (i.e. everything after the body of the Instantiator class).
        protected override void WriteFileEnd(
            CodeBuilder builder,
            CodeGenInfo info)
        {
            // Write the constructor for the instantiator.
            if (info.HasLoadedImageSurface)
            {
                builder.WriteLine($"internal AnimatedVisual(Compositor compositor,");
                builder.Indent();

                // Define the image surface parameters of the AnimatedVisual() constructor.
                builder.WriteCommaSeparatedLines(info.LoadedImageSurfaceNodes.Select(n => $"{_stringifier.ReferenceTypeName(n.TypeName)} {_stringifier.CamelCase(n.Name)}"));
                builder.WriteLine(")");
                builder.UnIndent();
                builder.OpenScope();

                builder.WriteLine("_c = compositor;");
                builder.WriteLine($"{info.ReusableExpressionAnimationFieldName} = compositor.CreateExpressionAnimation();");

                // Initialize the private image surface variables with the input parameters of the constructor.
                var nodes = info.LoadedImageSurfaceNodes.ToArray();
                foreach (var n in nodes)
                {
                    builder.WriteLine($"{n.FieldName} = {_stringifier.CamelCase(n.Name)};");
                }
            }
            else
            {
                builder.WriteLine("internal AnimatedVisual(Compositor compositor)");
                builder.OpenScope();
                builder.WriteLine("_c = compositor;");
                builder.WriteLine($"{info.ReusableExpressionAnimationFieldName} = compositor.CreateExpressionAnimation();");
            }

            builder.WriteLine("Root();");
            builder.CloseScope();
            builder.WriteLine();

            // Write the IAnimatedVisual implementation.
            builder.WriteLine("Visual IAnimatedVisual.RootVisual => _root;");
            builder.WriteLine($"TimeSpan IAnimatedVisual.Duration => TimeSpan.FromTicks({info.DurationTicksFieldName});");
            builder.WriteLine($"Vector2 IAnimatedVisual.Size => {Vector2(info.CompositionDeclaredSize)};");
            builder.WriteLine("void IDisposable.Dispose() => _root?.Dispose();");

            // Close the scope for the instantiator class.
            builder.CloseScope();

            // Close the scope for the class.
            builder.CloseScope();

            // Close the scope for the namespace
            builder.CloseScope();
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Generate the body of the TryCreateAnimatedVisual() method for the composition that contains LoadedImageSurfaces.
 /// </summary>
 void WriteTryCreateInstantiatorWithImageLoading(CodeBuilder builder, CodeGenInfo info)
 {
     builder.WriteLine("m_isTryCreateAnimatedVisualCalled = true;");
     builder.WriteLine();
     builder.WriteLine("diagnostics = nullptr;");
     builder.WriteLine("if (!IsRuntimeCompatible())");
     builder.OpenScope();
     builder.WriteLine("return nullptr;");
     builder.CloseScope();
     builder.WriteLine();
     builder.WriteLine("EnsureImageLoadingStarted();");
     builder.WriteLine();
     builder.WriteLine("if (m_isAnimatedVisualSourceDynamic && m_loadCompleteEventCount != c_loadedImageSurfaceCount)");
     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(");");
     builder.CloseScope();
     builder.WriteLine();
 }
Ejemplo n.º 4
0
        /// <inheritdoc/>
        // Called by the base class to write the end of the file (i.e. everything after the body of the Instantiator class).
        protected override void WriteFileEnd(
            CodeBuilder builder,
            CodeGenInfo info)
        {
            if (info.UsesCanvasEffects ||
                info.UsesCanvasGeometry)
            {
                // Utility method for D2D geometries
                builder.WriteLine("static IGeometrySource2D^ CanvasGeometryToIGeometrySource2D(CanvasGeometry geo)");
                builder.OpenScope();
                builder.WriteLine("ComPtr<ABI::Windows::Graphics::IGeometrySource2D> interop = geo.Detach();");
                builder.WriteLine("return reinterpret_cast<IGeometrySource2D^>(interop.Get());");
                builder.CloseScope();
                builder.WriteLine();

                // Utility method for fail-fasting on bad HRESULTs from d2d operations
                builder.WriteLine("static void FFHR(HRESULT hr)");
                builder.OpenScope();
                builder.WriteLine("if (hr != S_OK)");
                builder.OpenScope();
                builder.WriteLine("RoFailFastWithErrorContext(hr);");
                builder.CloseScope();
                builder.CloseScope();
                builder.WriteLine();
            }

            // Write the constructor for the instantiator.
            builder.UnIndent();
            builder.WriteLine("public:");
            builder.Indent();

            if (info.HasLoadedImageSurface)
            {
                builder.WriteLine("AnimatedVisual(Compositor^ compositor,");
                builder.Indent();

                builder.WriteCommaSeparatedLines(info.LoadedImageSurfaceNodes.Select(n => $"{_stringifier.ReferenceTypeName(n.TypeName)} {_stringifier.CamelCase(n.Name)}"));

                // Initializer list.
                builder.WriteLine(") : _c(compositor)");

                // Instantiate the reusable ExpressionAnimation.
                builder.WriteLine($", {info.ReusableExpressionAnimationFieldName}(compositor->CreateExpressionAnimation())");

                // Initialize the image surfaces.
                var nodes = info.LoadedImageSurfaceNodes.ToArray();
                foreach (var n in nodes)
                {
                    builder.WriteLine($", {n.FieldName}({_stringifier.CamelCase(n.Name)})");
                }

                builder.UnIndent();
            }
            else
            {
                builder.WriteLine("AnimatedVisual(Compositor^ compositor)");

                // Initializer list.
                builder.Indent();
                builder.WriteLine(": _c(compositor)");

                // Instantiate the reusable ExpressionAnimation.
                builder.WriteLine($", {info.ReusableExpressionAnimationFieldName}(compositor->CreateExpressionAnimation())");
                builder.UnIndent();
            }

            builder.OpenScope();
            if (info.UsesCanvasEffects ||
                info.UsesCanvasGeometry)
            {
                builder.WriteLine($"{FailFastWrapper("D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, _d2dFactory.GetAddressOf())")};");
            }

            // Instantiate the root. This will cause the whole Visual tree to be built and animations started.
            builder.WriteLine("Root();");
            builder.CloseScope();

            // Write the destructor. This is how CX implements IClosable/IDisposable.
            builder.WriteLine("virtual ~AnimatedVisual() { }");

            // Write the members on IAnimatedVisual.
            builder.WriteLine();
            builder.WriteLine("property TimeSpan Duration");
            builder.OpenScope();
            builder.WriteLine("virtual TimeSpan get() { return { c_durationTicks }; }");
            builder.CloseScope();
            builder.WriteLine();
            builder.WriteLine("property Visual^ RootVisual");
            builder.OpenScope();
            builder.WriteLine("virtual Visual^ get() { return _root; }");
            builder.CloseScope();
            builder.WriteLine();
            builder.WriteLine("property float2 Size");
            builder.OpenScope();
            builder.WriteLine($"virtual float2 get() {{ return {Vector2(info.CompositionDeclaredSize)}; }}");
            builder.CloseScope();
            builder.WriteLine();

            // Close the scope for the instantiator class.
            builder.UnIndent();
            builder.WriteLine("};");

            // Close the anonymous namespace.
            builder.WriteLine("} // end namespace");
            builder.WriteLine();

            // Generate the method that creates an instance of the composition.
            builder.WriteLine($"Microsoft::UI::Xaml::Controls::IAnimatedVisual^ AnimatedVisuals::{info.ClassName}::TryCreateAnimatedVisual(");
            builder.Indent();
            builder.WriteLine("Compositor^ compositor,");
            builder.WriteLine("Object^* diagnostics)");
            builder.UnIndent();
            builder.OpenScope();

            if (info.HasLoadedImageSurface)
            {
                WriteTryCreateInstantiatorWithImageLoading(builder, info);
            }
            else
            {
                builder.WriteLine("diagnostics = nullptr;");
                builder.WriteLine("if (!IsRuntimeCompatible())");
                builder.OpenScope();
                builder.WriteLine("return nullptr;");
                builder.CloseScope();
                builder.WriteLine("return ref new AnimatedVisual(compositor);");
                builder.CloseScope();
            }

            if (info.HasLoadedImageSurface)
            {
                // Generate the get() and set() methods of IsAnimatedVisualSourceDynamic property.
                WriteIsAnimatedVisualSourceDynamicGetSet(builder, info);

                // Generate the method that load all the LoadedImageSurfaces.
                WriteEnsureImageLoadingStarted(builder, info);

                // Generate the method that handle the LoadCompleted event of the LoadedImageSurface objects.
                WriteHandleLoadCompleted(builder, info);
            }
        }