| File: RenderTree\RenderTreeFrameArrayBuilder.cs | Web Access |
| Project: src\aspnetcore\src\Components\Components\src\Microsoft.AspNetCore.Components.csproj (Microsoft.AspNetCore.Components) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.RenderTree; /// <summary> /// A special subclass of <see cref="ArrayBuilder{T}"/> that contains methods optimized for appending <see cref="RenderTreeFrame"/> entries. /// </summary> internal sealed class RenderTreeFrameArrayBuilder : ArrayBuilder<RenderTreeFrame> { // You may notice a repeated block at the top of each of these methods. This is intentionally inlined into each // method because doing so improves intensive rendering scenarios by around 1% (based on the FastGrid benchmark). public void AppendElement(int sequence, string elementName) { if (_itemsInUse == _items.Length) { GrowBuffer(_items.Length * 2); } _items[_itemsInUse++] = new RenderTreeFrame { SequenceField = sequence, FrameTypeField = RenderTreeFrameType.Element, ElementNameField = elementName, }; } public void AppendText(int sequence, string textContent) { if (_itemsInUse == _items.Length) { GrowBuffer(_items.Length * 2); } _items[_itemsInUse++] = new RenderTreeFrame { SequenceField = sequence, FrameTypeField = RenderTreeFrameType.Text, TextContentField = textContent, }; } public void AppendMarkup(int sequence, string markupContent) { if (_itemsInUse == _items.Length) { GrowBuffer(_items.Length * 2); } _items[_itemsInUse++] = new RenderTreeFrame { SequenceField = sequence, FrameTypeField = RenderTreeFrameType.Markup, MarkupContentField = markupContent, }; } public void AppendAttribute(int sequence, string attributeName, object? attributeValue) { if (_itemsInUse == _items.Length) { GrowBuffer(_items.Length * 2); } _items[_itemsInUse++] = new RenderTreeFrame { SequenceField = sequence, FrameTypeField = RenderTreeFrameType.Attribute, AttributeNameField = attributeName, AttributeValueField = attributeValue, }; } public void AppendComponent(int sequence, [DynamicallyAccessedMembers(Component)] Type componentType) { if (_itemsInUse == _items.Length) { GrowBuffer(_items.Length * 2); } _items[_itemsInUse++] = new RenderTreeFrame { SequenceField = sequence, FrameTypeField = RenderTreeFrameType.Component, ComponentTypeField = componentType, }; } public void AppendElementReferenceCapture(int sequence, Action<ElementReference> elementReferenceCaptureAction) { if (_itemsInUse == _items.Length) { GrowBuffer(_items.Length * 2); } _items[_itemsInUse++] = new RenderTreeFrame { SequenceField = sequence, FrameTypeField = RenderTreeFrameType.ElementReferenceCapture, ElementReferenceCaptureActionField = elementReferenceCaptureAction, }; } public void AppendComponentReferenceCapture(int sequence, Action<object> componentReferenceCaptureAction, int parentFrameIndexValue) { if (_itemsInUse == _items.Length) { GrowBuffer(_items.Length * 2); } _items[_itemsInUse++] = new RenderTreeFrame { SequenceField = sequence, FrameTypeField = RenderTreeFrameType.ComponentReferenceCapture, ComponentReferenceCaptureActionField = componentReferenceCaptureAction, ComponentReferenceCaptureParentFrameIndexField = parentFrameIndexValue, }; } public void AppendRegion(int sequence) { if (_itemsInUse == _items.Length) { GrowBuffer(_items.Length * 2); } _items[_itemsInUse++] = new RenderTreeFrame { SequenceField = sequence, FrameTypeField = RenderTreeFrameType.Region, }; } public void AppendComponentRenderMode(IComponentRenderMode renderMode) { if (_itemsInUse == _items.Length) { GrowBuffer(_items.Length * 2); } _items[_itemsInUse++] = new RenderTreeFrame { SequenceField = 0, // We're only interested in one of these, so it's not useful to optimize diffing over multiple FrameTypeField = RenderTreeFrameType.ComponentRenderMode, ComponentRenderModeField = renderMode, }; } public void AppendNamedEvent(string eventType, string assignedName) { if (_itemsInUse == _items.Length) { GrowBuffer(_items.Length * 2); } _items[_itemsInUse++] = new RenderTreeFrame { SequenceField = 0, // We're only interested in one of these per eventType, so it's not useful to optimize diffing over multiple FrameTypeField = RenderTreeFrameType.NamedEvent, NamedEventTypeField = eventType, NamedEventAssignedNameField = assignedName, }; } }