示例#1
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.
            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();
        }
        /// <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)
        {
            if (info.RequiresWin2d)
            {
                builder.WriteLine("using Microsoft.Graphics.Canvas.Geometry;");
            }

            builder.WriteLine("using Microsoft.UI.Xaml.Controls;");
            builder.WriteLine("using System;");
            builder.WriteLine("using System.Numerics;");
            builder.WriteLine("using Windows.UI;");
            builder.WriteLine("using Windows.UI.Composition;");

            builder.WriteLine();
            builder.WriteLine("namespace AnimatedVisuals");
            builder.OpenScope();
            builder.WriteLine($"sealed class {info.ClassName} : IAnimatedVisualSource");
            builder.OpenScope();

            // Generate the method that creates an instance of the animated visual.
            builder.WriteLine("public IAnimatedVisual TryCreateAnimatedVisual(Compositor compositor, out object diagnostics)");
            builder.OpenScope();
            builder.WriteLine("diagnostics = null;");
            builder.WriteLine("if (!IsRuntimeCompatible())");
            builder.OpenScope();
            builder.WriteLine("return null;");
            builder.CloseScope();
            builder.WriteLine("return new AnimatedVisual(compositor);");
            builder.CloseScope();
            builder.WriteLine();
        }
示例#3
0
        void WriteEnsureImageLoadingStarted(CodeBuilder builder, CodeGenInfo info)
        {
            builder.WriteLine("void EnsureImageLoadingStarted()");
            builder.OpenScope();
            builder.WriteLine("if (!_isImageLoadingStarted)");
            builder.OpenScope();
            builder.WriteLine("var eventHandler = new TypedEventHandler<LoadedImageSurface, LoadedImageSourceLoadCompletedEventArgs>(HandleLoadCompleted);");

            var nodes = info.LoadedImageSurfaceNodes.ToArray();

            foreach (var n in nodes)
            {
                switch (n.LoadedImageSurfaceType)
                {
                case LoadedImageSurface.LoadedImageSurfaceType.FromStream:
                    builder.WriteLine($"{n.FieldName} = LoadedImageSurface.StartLoadFromStream({n.BytesFieldName}.AsBuffer().AsStream().AsRandomAccessStream());");
                    break;

                case LoadedImageSurface.LoadedImageSurfaceType.FromUri:
                    builder.WriteLine($"{n.FieldName} = LoadedImageSurface.StartLoadFromUri(new Uri(\"{n.ImageUri}\"));");
                    break;

                default:
                    throw new InvalidOperationException();
                }

                builder.WriteLine($"{n.FieldName}.LoadCompleted += eventHandler;");
            }

            builder.WriteLine("_isImageLoadingStarted = true;");
            builder.CloseScope();
            builder.CloseScope();
            builder.WriteLine();
        }
示例#4
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();
 }
示例#5
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)
        {
            // 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>();

            if (info.UsesCanvas)
            {
                namepaces.Add("Microsoft.Graphics.Canvas");
            }

            if (info.UsesCanvasEffects)
            {
                namepaces.Add("Microsoft.Graphics.Canvas.Effects");
            }

            if (info.UsesCanvasGeometry)
            {
                namepaces.Add("Microsoft.Graphics.Canvas.Geometry");
            }

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

            if (info.UsesStreams)
            {
                namepaces.Add("System.IO");
            }

            namepaces.Add("Microsoft.UI.Xaml.Controls");
            namepaces.Add("System");
            namepaces.Add("System.Numerics");
            namepaces.Add("Windows.UI");
            namepaces.Add("Windows.UI.Composition");

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

            builder.WriteLine();

            // If the composition has LoadedImageSurface, write a class that implements the IDynamicAnimatedVisualSource interface.
            // Otherwise, implement the IAnimatedVisualSource interface.
            if (info.HasLoadedImageSurface)
            {
                WriteIDynamicAnimatedVisualSource(builder, info);
            }
            else
            {
                WriteIAnimatedVisualSource(builder, info);
            }
        }
        /// <inheritdoc/>
        protected override void WriteInstantiatorStart(CodeBuilder builder, CodeGenInfo info)
        {
            // Start writing the instantiator.
            builder.WriteLine("ref class AnimatedVisual sealed : public Microsoft::UI::Xaml::Controls::IAnimatedVisual");
            builder.OpenScope();

            // D2D factory field.
            builder.WriteLine("ComPtr<ID2D1Factory> _d2dFactory;");
        }
示例#7
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();
        }
示例#8
0
        /// <inheritdoc/>
        protected override void WriteLoadedImageSurfaceFactory(CodeBuilder builder, CodeGenInfo info, LoadedImageSurface obj, string fieldName, Uri imageUri)
        {
            switch (obj.Type)
            {
            case LoadedImageSurface.LoadedImageSurfaceType.FromStream:
                builder.WriteLine($"var result = Windows.UI.Xaml.Media.LoadedImageSurface.StartLoadFromStream({fieldName}.AsBuffer().AsStream().AsRandomAccessStream());");
                break;

            case LoadedImageSurface.LoadedImageSurfaceType.FromUri:
                builder.WriteLine($"var result = Windows.UI.Xaml.Media.LoadedImageSurface.StartLoadFromUri(new Uri(\"{imageUri}\"));");
                break;
            }
        }
        /// <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}\"");
            if (info.UsesCanvasEffects)
            {
                // D2D
                builder.WriteLine("#include \"d2d1.h\"");
                builder.WriteLine("#include <d2d1_1.h>");
                builder.WriteLine("#include <d2d1helper.h>");

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

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

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

            if (info.UsesCanvasEffects ||
                info.UsesCanvas)
            {
                // throw an exception in this case for now. In the future the necessary
                // C++ code gen will be added
                throw new InvalidOperationException("Win2D dependency detected.");
            }

            builder.WriteLine();
            builder.WriteLine("using namespace Windows::Foundation;");
            builder.WriteLine("using namespace Windows::Foundation::Numerics;");
            builder.WriteLine("using namespace Windows::UI;");
            builder.WriteLine("using namespace Windows::UI::Composition;");
            builder.WriteLine("using namespace Windows::Graphics;");
            builder.WriteLine("using namespace Microsoft::WRL;");
            builder.WriteLine();

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

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

            // Typedef to simplify generation
            builder.WriteLine("typedef ComPtr<GeoSource> CanvasGeometry;");
        }
示例#10
0
 void WriteIsAnimatedVisualSourceDynamicGetSet(CodeBuilder builder, CodeGenInfo info)
 {
     builder.WriteLine($"bool AnimatedVisuals::{info.ClassName}::IsAnimatedVisualSourceDynamic::get()");
     builder.OpenScope();
     builder.WriteLine("return m_isAnimatedVisualSourceDynamic;");
     builder.CloseScope();
     builder.WriteLine();
     builder.WriteLine($"void AnimatedVisuals::{info.ClassName}::IsAnimatedVisualSourceDynamic::set(bool isAnimatedVisualSourceDynamic)");
     builder.OpenScope();
     builder.WriteLine("if (!m_isTryCreateAnimatedVisualCalled && m_isAnimatedVisualSourceDynamic != isAnimatedVisualSourceDynamic)");
     builder.OpenScope();
     builder.WriteLine("m_isAnimatedVisualSourceDynamic = isAnimatedVisualSourceDynamic;");
     builder.WriteLine("PropertyChanged(this, ref new PropertyChangedEventArgs(\"IsAnimatedVisualSourceDynamic\"));");
     builder.CloseScope();
     builder.CloseScope();
 }
示例#11
0
        /// <summary>
        /// Write a class that implements the IAnimatedVisualSource interface.
        /// </summary>
        void WriteIAnimatedVisualSource(CodeBuilder builder, CodeGenInfo info)
        {
            builder.WriteLine("namespace AnimatedVisuals");
            builder.OpenScope();
            builder.WriteLine($"sealed class {info.ClassName} : IAnimatedVisualSource");
            builder.OpenScope();

            // Generate the method that creates an instance of the animated visual.
            builder.WriteLine("public IAnimatedVisual TryCreateAnimatedVisual(Compositor compositor, out object diagnostics)");
            builder.OpenScope();
            builder.WriteLine("diagnostics = null;");
            builder.WriteLine("if (!IsRuntimeCompatible())");
            builder.OpenScope();
            builder.WriteLine("return null;");
            builder.CloseScope();
            builder.WriteLine("return new AnimatedVisual(compositor);");
            builder.CloseScope();
            builder.WriteLine();
        }
示例#12
0
        ///// <summary>
        ///// 清空项目的编译缓存
        ///// </summary>
        //public void ClearCache(EntityInfo entityInfo, List<UIProjectItem> lstItem)
        //{
        //    foreach (UIProjectItem pitem in lstItem)
        //    {
        //        string mPath = UIConfigItem.FormatParameter(pitem.ModelPath, entityInfo);
        //        CodeGenCache.DeleteGenerationer(mPath);
        //        if (pitem.ChildItems != null && pitem.ChildItems.Count > 0)
        //        {
        //            ClearCache(entityInfo, pitem.ChildItems);
        //        }
        //    }
        //}

        /// <summary>
        /// 生成代码
        /// </summary>
        /// <param name="entityInfo">实体信息</param>
        /// <param name="classConfig">UI配置信息</param>
        /// <param name="selectPropertys">选中需要生成的属性信息</param>
        /// <param name="lstItem">UI项目项</param>
        /// <param name="parentItem">父项</param>
        /// <returns></returns>
        private void GenerateCode(EntityInfo entityInfo, UIConfigItem classConfig, Project selectedProject,
                                  List <UIModelItem> selectPropertys, UIModelItem classInfo, List <UIProjectItem> lstItem, ProjectItem parentItem)
        {
            Encoding fileEncoding = null;

            foreach (UIProjectItem pitem in lstItem)
            {
                string      mPath   = UIConfigItem.FormatParameter(pitem.ModelPath, entityInfo, selectedProject);
                string      tPath   = UIConfigItem.FormatParameter(pitem.TargetPath, entityInfo, selectedProject);
                CodeGenInfo info    = CodeGenCache.GetGenerationer(mPath, entityInfo);
                string      content = info.Invoke(entityInfo, classConfig, selectPropertys, classInfo);
                fileEncoding = pitem.Encoding;
                ProjectItem item = SaveItem(tPath, selectedProject, content, pitem.GenType, parentItem, fileEncoding);
                if (pitem.ChildItems != null && pitem.ChildItems.Count > 0)
                {
                    GenerateCode(entityInfo, classConfig, selectedProject, selectPropertys, classInfo, pitem.ChildItems, item);
                }
            }
        }
示例#13
0
        /// <inheritdoc/>
        protected override void WriteLoadedImageSurfaceFactory(CodeBuilder builder, CodeGenInfo info, LoadedImageSurface obj, string fieldName, Uri imageUri)
        {
            switch (obj.Type)
            {
            case LoadedImageSurface.LoadedImageSurfaceType.FromStream:
                builder.WriteLine("auto stream = ref new InMemoryRandomAccessStream();");
                builder.WriteLine("auto dataWriter = ref new DataWriter(stream->GetOutputStreamAt(0));");
                builder.WriteLine($"dataWriter->WriteBytes({fieldName});");
                builder.WriteLine("dataWriter->StoreAsync();");
                builder.WriteLine("dataWriter->FlushAsync();");
                builder.WriteLine("stream->Seek(0);");
                builder.WriteLine($"{_stringifier.Var} result = Windows::UI::Xaml::Media::LoadedImageSurface::StartLoadFromStream(stream);");
                break;

            case LoadedImageSurface.LoadedImageSurfaceType.FromUri:
                builder.WriteLine($"{_stringifier.Var} result = Windows::UI::Xaml::Media::LoadedImageSurface::StartLoadFromUri(ref new Uri(\"{imageUri}\"));");
                break;
            }
        }
示例#14
0
        void WriteEnsureImageLoadingStarted(CodeBuilder builder, CodeGenInfo info)
        {
            builder.WriteLine($"void AnimatedVisuals::{info.ClassName}::EnsureImageLoadingStarted()");
            builder.OpenScope();
            builder.WriteLine("if (!m_isImageLoadingStarted)");
            builder.OpenScope();
            builder.WriteLine($"auto eventHandler = ref new TypedEventHandler<LoadedImageSurface^, LoadedImageSourceLoadCompletedEventArgs^>(this, &AnimatedVisuals::{info.ClassName}::HandleLoadCompleted);");

            var nodes = info.LoadedImageSurfaceNodes.ToArray();

            foreach (var n in nodes)
            {
                var imageMemberName = MakeFieldName(n.Name);
                switch (n.LoadedImageSurfaceType)
                {
                case LoadedImageSurface.LoadedImageSurfaceType.FromStream:
                    var streamName     = $"stream_{n.Name}";
                    var dataWriterName = $"dataWriter_{n.Name}";
                    builder.WriteLine($"auto {streamName} = ref new InMemoryRandomAccessStream();");
                    builder.WriteLine($"auto {dataWriterName} = ref new DataWriter({streamName}->GetOutputStreamAt(0));");
                    builder.WriteLine($"{dataWriterName}->WriteBytes({n.BytesFieldName});");
                    builder.WriteLine($"{dataWriterName}->StoreAsync();");
                    builder.WriteLine($"{dataWriterName}->FlushAsync();");
                    builder.WriteLine($"{streamName}->Seek(0);");
                    builder.WriteLine($"{imageMemberName} = Windows::UI::Xaml::Media::LoadedImageSurface::StartLoadFromStream({streamName});");
                    break;

                case LoadedImageSurface.LoadedImageSurfaceType.FromUri:
                    builder.WriteLine($"{imageMemberName} = Windows::UI::Xaml::Media::LoadedImageSurface::StartLoadFromUri(ref new Uri(\"{n.ImageUri}\"));");
                    break;

                default:
                    throw new InvalidOperationException();
                }

                builder.WriteLine($"{imageMemberName}->LoadCompleted += eventHandler;");
            }

            builder.WriteLine("m_isImageLoadingStarted = true;");
            builder.CloseScope();
            builder.CloseScope();
            builder.WriteLine();
        }
        /// <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}\"");
            if (info.RequiresWin2d)
            {
                // D2D
                builder.WriteLine("#include \"d2d1.h\"");
                builder.WriteLine("#include <d2d1_1.h>");
                builder.WriteLine("#include <d2d1helper.h>");

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

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

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

            builder.WriteLine();
            builder.WriteLine("using namespace Windows::Foundation;");
            builder.WriteLine("using namespace Windows::Foundation::Numerics;");
            builder.WriteLine("using namespace Windows::UI;");
            builder.WriteLine("using namespace Windows::UI::Composition;");
            builder.WriteLine("using namespace Windows::Graphics;");
            builder.WriteLine("using namespace Microsoft::WRL;");
            builder.WriteLine();

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

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

            // Typedef to simplify generation
            builder.WriteLine("typedef ComPtr<GeoSource> CanvasGeometry;");
        }
示例#16
0
 void WriteHandleLoadCompleted(CodeBuilder builder, CodeGenInfo info)
 {
     builder.WriteLine($"void AnimatedVisuals::{info.ClassName}::HandleLoadCompleted(LoadedImageSurface^ sender, LoadedImageSourceLoadCompletedEventArgs^ e)");
     builder.OpenScope();
     builder.WriteLine("m_loadCompleteEventCount++;");
     builder.WriteLine("if (e->Status == LoadedImageSourceLoadStatus::Success)");
     builder.OpenScope();
     builder.WriteLine("if (m_isAnimatedVisualSourceDynamic && m_loadCompleteEventCount == c_loadedImageSurfaceCount)");
     builder.OpenScope();
     builder.WriteLine("RaiseAnimatedVisualInvalidatedEvent(this, nullptr);");
     builder.CloseScope();
     builder.WriteLine("m_imageSuccessfulLoadingProgress = (double)m_loadCompleteEventCount / c_loadedImageSurfaceCount;");
     builder.WriteLine("PropertyChanged(this, ref new PropertyChangedEventArgs(\"ImageSuccessfulLoadingProgress\"));");
     builder.CloseScope();
     builder.WriteLine();
     builder.WriteLine("if (m_loadCompleteEventCount == c_loadedImageSurfaceCount)");
     builder.OpenScope();
     builder.WriteLine("m_isImageLoadingCompleted = true;");
     builder.WriteLine("PropertyChanged(this, ref new PropertyChangedEventArgs(\"IsImageLoadingCompleted\"));");
     builder.CloseScope();
     builder.CloseScope();
     builder.WriteLine();
 }
示例#17
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();
 }
示例#18
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);
            }
        }
        /// <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)
        {
            // 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();
            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();
            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 Windows::Foundation::TimeSpan Duration");
            builder.OpenScope();
            builder.WriteLine("virtual Windows::Foundation::TimeSpan get() { return { c_durationTicks }; }");
            builder.CloseScope();
            builder.WriteLine();
            builder.WriteLine("property Windows::UI::Composition::Visual^ RootVisual");
            builder.OpenScope();
            builder.WriteLine("virtual Windows::UI::Composition::Visual^ get() { return _root; }");
            builder.CloseScope();
            builder.WriteLine();
            builder.WriteLine("property Windows::Foundation::Numerics::float2 Size");
            builder.OpenScope();
            builder.WriteLine($"virtual Windows::Foundation::Numerics::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();
            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();
        }
示例#20
0
        /// <summary>
        /// Write a class that implements the IDynamicAnimatedVisualSource interface.
        /// </summary>
        void WriteIDynamicAnimatedVisualSource(CodeBuilder builder, CodeGenInfo info)
        {
            var nodes = info.LoadedImageSurfaceNodes.ToArray();

            builder.WriteLine("namespace AnimatedVisuals");
            builder.OpenScope();
            builder.WriteLine($"sealed class {info.ClassName} : IDynamicAnimatedVisualSource, INotifyPropertyChanged");
            builder.OpenScope();

            // Declare variables.
            builder.WriteLine($"{_stringifier.Const(_stringifier.Int32TypeName)} c_loadedImageSurfaceCount = {nodes.Distinct().Count()};");
            builder.WriteLine($"{_stringifier.Int32TypeName} _loadCompleteEventCount;");
            builder.WriteLine("bool _isAnimatedVisualSourceDynamic = true;");
            builder.WriteLine("bool _isTryCreateAnimatedVisualCalled;");
            builder.WriteLine("bool _isImageLoadingStarted;");
            builder.WriteLine("EventRegistrationTokenTable<TypedEventHandler<IDynamicAnimatedVisualSource, object>> _animatedVisualInvalidatedEventTokenTable;");

            // Declare the variables to hold the surfaces.
            foreach (var n in nodes)
            {
                builder.WriteLine($"{_stringifier.ReferenceTypeName(n.TypeName)} {n.FieldName};");
            }

            builder.WriteLine();

            // Implement the INotifyPropertyChanged.PropertyChanged event.
            builder.WriteSummaryComment("This implementation of the INotifyPropertyChanged.PropertyChanged event is specific to C# and does not work on WinRT.");
            builder.WriteLine("public event PropertyChangedEventHandler PropertyChanged;");
            builder.WriteLine();

            // Implement the AnimatedVisualInvalidated event.
            WriteAnimatedVisualInvalidatedEvent(builder);

            // Define properties.
            builder.WriteSummaryComment("If this property is set to true, <see cref=\"TryCreateAnimatedVisual\"/> will return null until all images have loaded. When all images have loaded, <see cref=\"TryCreateAnimatedVisual\"/> will return the AnimatedVisual. To use, set it when declaring the AnimatedVisualSource. Once <see cref=\"TryCreateAnimatedVisual\"/> is called, changes made to this property will be ignored. Default value is true.");
            builder.WriteLine("public bool IsAnimatedVisualSourceDynamic");
            builder.OpenScope();
            builder.WriteLine("get { return _isAnimatedVisualSourceDynamic; }");
            builder.WriteLine("set");
            builder.OpenScope();
            builder.WriteLine("if (!_isTryCreateAnimatedVisualCalled && _isAnimatedVisualSourceDynamic != value)");
            builder.OpenScope();
            builder.WriteLine("_isAnimatedVisualSourceDynamic = value;");
            builder.WriteLine("NotifyPropertyChanged(nameof(IsAnimatedVisualSourceDynamic));");
            builder.CloseScope();
            builder.CloseScope();
            builder.CloseScope();
            builder.WriteLine();

            builder.WriteSummaryComment("Returns true if all images have loaded. To see if the images succeeded to load, see <see cref=\"ImageSuccessfulLoadingProgress\"/>.");
            builder.WriteLine("public bool IsImageLoadingCompleted { get; private set; }");
            builder.WriteLine();

            builder.WriteSummaryComment("Represents the progress of the image loading. Returns value between 0 and 1. 0 means none of the images finished loading. 1 means all images finished loading.");
            builder.WriteLine("public double ImageSuccessfulLoadingProgress { get; private set; }");
            builder.WriteLine();

            // Generate the method that creates an instance of the animated visual.
            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.OpenScope();
            builder.WriteLine("return null;");
            builder.CloseScope();
            builder.WriteLine();
            builder.WriteLine("EnsureImageLoadingStarted();");
            builder.WriteLine();
            builder.WriteLine("if (_isAnimatedVisualSourceDynamic && _loadCompleteEventCount != c_loadedImageSurfaceCount)");
            builder.OpenScope();
            builder.WriteLine("return null;");
            builder.CloseScope();
            builder.WriteLine("return");
            builder.Indent();
            WriteAnimatedVisualCall(builder, info);
            builder.UnIndent();
            builder.CloseScope();
            builder.WriteLine();

            // 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);

            // Generate the method that raise the PropertyChanged event.
            builder.WriteLine("void NotifyPropertyChanged(string name)");
            builder.OpenScope();
            builder.WriteLine("PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));");
            builder.CloseScope();
            builder.WriteLine();

            // Generate the method that get or create the EventRegistrationTokenTable.
            builder.WriteLine("EventRegistrationTokenTable<TypedEventHandler<IDynamicAnimatedVisualSource, object>> GetAnimatedVisualInvalidatedEventRegistrationTokenTable()");
            builder.OpenScope();
            builder.WriteLine("return EventRegistrationTokenTable<TypedEventHandler<IDynamicAnimatedVisualSource, object>>.GetOrCreateEventRegistrationTokenTable(ref _animatedVisualInvalidatedEventTokenTable);");
            builder.CloseScope();
            builder.WriteLine();
        }
示例#21
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}");
            }
        }
示例#22
0
 /// <inheritdoc/>
 protected override void WriteInstantiatorStart(CodeBuilder builder, CodeGenInfo info)
 {
     // Start the instantiator class.
     builder.WriteLine("sealed class AnimatedVisual : IAnimatedVisual");
     builder.OpenScope();
 }