Ejemplo n.º 1
0
 internal void WriteCodeBuilder(CodeBuilder builder)
 {
     _lines.Add(new CodeLine {
         Text = builder, IndentCount = _indentCount
     });
 }
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)
        {
            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);
            }
        }
Ejemplo n.º 3
0
        /// <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,
            CodeGenInfo info)
        {
            builder.WriteLine("#include \"pch.h\"");
            builder.WriteLine($"#include \"{_headerFileName}\"");

            // floatY, floatYxZ
            builder.WriteLine("#include \"WindowsNumerics.h\"");

            if (info.UsesCanvasEffects ||
                info.UsesCanvasGeometry)
            {
                // D2D
                builder.WriteLine("#include \"d2d1.h\"");
                builder.WriteLine("#include <d2d1_1.h>");
                builder.WriteLine("#include <d2d1helper.h>");

                // Interop
                builder.WriteLine("#include <Windows.Graphics.Interop.h>");

                // ComPtr
                builder.WriteLine("#include <wrl.h>");
            }

            if (info.UsesStreams)
            {
                builder.WriteLine("#include <iostream>");
            }

            if (info.UsesCompositeEffect)
            {
                // The CompsiteEffect class requires std::vector.
                builder.WriteLine("#include <vector>");
            }

            builder.WriteLine();

            // A sorted set to hold the namespaces that the generated code will use. The set is maintained in sorted order.
            var namespaces = new SortedSet <string>();

            if (info.UsesCanvasEffects ||
                info.UsesCanvas)
            {
                // Interop
                builder.WriteLine("#include <Windows.Graphics.Effects.h>");
                builder.WriteLine("#include <Windows.Graphics.Effects.Interop.h>");
            }

            namespaces.Add("Windows::Foundation");
            namespaces.Add("Windows::Foundation::Numerics");
            namespaces.Add("Windows::UI");
            namespaces.Add("Windows::UI::Composition");
            namespaces.Add("Windows::Graphics");
            namespaces.Add("Microsoft::WRL");
            if (info.UsesNamespaceWindowsUIXamlMedia)
            {
                namespaces.Add("Windows::UI::Xaml::Media");
            }

            if (info.UsesStreams)
            {
                namespaces.Add("Platform");
                namespaces.Add("Windows::Storage::Streams");
            }

            // Write out each namespace using.
            foreach (var n in namespaces)
            {
                builder.WriteLine($"using namespace {n};");
            }

            builder.WriteLine();

            // Put the Instantiator class in an anonymous namespace.
            builder.WriteLine("namespace");
            builder.WriteLine("{");

            if (info.UsesCanvasEffects ||
                info.UsesCanvasGeometry)
            {
                // Write GeoSource to allow it's use in function definitions
                builder.WriteLine($"{_stringifier.GeoSourceClass}");

                // Typedef to simplify generation
                builder.WriteLine("typedef ComPtr<GeoSource> CanvasGeometry;");
            }

            if (info.UsesCompositeEffect)
            {
                // Write the composite effect class that will allow the use
                // of this effect without win2d.
                builder.WriteLine($"{CompositionEffectClass}");
            }
        }
Ejemplo n.º 4
0
        /// <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)
        {
            // A sorted set to hold the namespaces that the generated code will use. The set is maintained in sorted order.
            var namespaces = new SortedSet<string>();

            if (Info.UsesCanvas)
            {
                namespaces.Add("Microsoft.Graphics.Canvas");
            }

            if (Info.UsesCanvasEffects)
            {
                namespaces.Add("Microsoft.Graphics.Canvas.Effects");
            }

            if (Info.UsesCanvasGeometry)
            {
                namespaces.Add("Microsoft.Graphics.Canvas.Geometry");
            }

            if (Info.UsesNamespaceWindowsUIXamlMedia)
            {
                namespaces.Add("System.ComponentModel");
                namespaces.Add("System.Runtime.InteropServices.WindowsRuntime");
                namespaces.Add("Windows.Foundation");
                namespaces.Add("Windows.UI.Xaml.Media");
            }

            if (Info.GenerateDependencyObject)
            {
                namespaces.Add("Windows.UI.Xaml");
            }

            if (Info.UsesStreams)
            {
                namespaces.Add("System.IO");
            }

            namespaces.Add("System");
            namespaces.Add("System.Numerics");
            namespaces.Add("Windows.UI");
            namespaces.Add("Windows.UI.Composition");

            // Write out each namespace using.
            foreach (var n in namespaces)
            {
                builder.WriteLine($"using {n};");
            }

            builder.WriteLine();

            builder.WriteLine($"namespace {Info.Namespace}");
            builder.OpenScope();

            // Write a description of the source as comments.
            foreach (var line in GetSourceDescriptionLines())
            {
                builder.WritePreformattedCommentLine(line);
            }

            // If the composition has LoadedImageSurface, write a class that implements the IDynamicAnimatedVisualSource interface.
            // Otherwise, implement the IAnimatedVisualSource interface.
            if (Info.LoadedImageSurfaces.Count > 0)
            {
                WriteIDynamicAnimatedVisualSource(builder, Info);
            }
            else
            {
                WriteIAnimatedVisualSource(builder, Info);
            }

            builder.CloseScope();
            builder.WriteLine();
        }