Pass the tree edits to JS code on render

This commit is contained in:
Steve Sanderson 2018-01-22 09:26:14 -08:00
parent 5435582c0e
commit 584e363110
4 changed files with 43 additions and 3 deletions

View File

@ -5,8 +5,10 @@ import { platform } from '../Environment';
export const renderComponentArgs = {
browserRendererId: (obj: RenderComponentArgsPointer) => platform.readInt32Field(obj, 0),
componentId: (obj: RenderComponentArgsPointer) => platform.readInt32Field(obj, 4),
renderTree: (obj: RenderComponentArgsPointer) => platform.readObjectField(obj, 8) as System_Array,
renderTreeLength: (obj: RenderComponentArgsPointer) => platform.readInt32Field(obj, 12),
renderTreeEdits: (obj: RenderComponentArgsPointer) => platform.readObjectField(obj, 8) as System_Array,
renderTreeEditsLength: (obj: RenderComponentArgsPointer) => platform.readInt32Field(obj, 12),
renderTree: (obj: RenderComponentArgsPointer) => platform.readObjectField(obj, 16) as System_Array,
renderTreeLength: (obj: RenderComponentArgsPointer) => platform.readInt32Field(obj, 20),
}
// Nominal type to ensure only valid pointers are passed to the renderComponentArgs functions.

View File

@ -0,0 +1,29 @@
import { System_Array, Pointer } from '../Platform/Platform';
import { platform } from '../Environment';
const renderTreeEditStructLength = 12;
export function getRenderTreeEditPtr(renderTreeEdits: System_Array, index: number): RenderTreeEditPointer {
return platform.getArrayEntryPtr(renderTreeEdits, index, renderTreeEditStructLength) as RenderTreeEditPointer;
}
export const renderTreeEdit = {
// The properties and memory layout must be kept in sync with the .NET equivalent in RenderTreeEdit.cs
type: (edit: RenderTreeEditPointer) => platform.readInt32Field(edit, 0) as EditType,
newTreeIndex: (edit: RenderTreeEditPointer) => platform.readInt32Field(edit, 4),
removedAttributeName: (edit: RenderTreeEditPointer) => platform.readStringField(edit, 8),
};
export enum EditType {
continue = 1,
prependNode = 2,
removeNode = 3,
setAttribute = 4,
removeAttribute = 5,
updateText = 6,
stepIn = 7,
stepOut = 8,
}
// Nominal type to ensure only valid pointers are passed to the renderTreeEdit functions.
// At runtime the values are just numbers.
export interface RenderTreeEditPointer extends Pointer { RenderTreeEditPointer__DO_NOT_IMPLEMENT: any }

View File

@ -1,6 +1,7 @@
import { System_Object, System_String, System_Array, MethodHandle, Pointer } from '../Platform/Platform';
import { platform } from '../Environment';
import { getTreeNodePtr, renderTreeNode, NodeType, RenderTreeNodePointer } from './RenderTreeNode';
import { getRenderTreeEditPtr, renderTreeEdit, EditType, RenderTreeEditPointer } from './RenderTreeEdit';
import { renderComponentArgs, RenderComponentArgsPointer } from './RenderComponentArgs';
let raiseEventMethod: MethodHandle;
let renderComponentMethod: MethodHandle;
@ -40,6 +41,8 @@ export function renderRenderTree(args: RenderComponentArgsPointer) {
clearElement(element);
const edits = renderComponentArgs.renderTreeEdits(args);
const editsLength = renderComponentArgs.renderTreeEditsLength(args);
const tree = renderComponentArgs.renderTree(args);
const treeLength = renderComponentArgs.renderTreeLength(args);
insertNodeRange(browserRendererId, componentId, element, tree, 0, treeLength - 1);

View File

@ -76,6 +76,8 @@ namespace Microsoft.Blazor.Browser.Rendering
{
BrowserRendererId = _browserRendererId,
ComponentId = componentId,
RenderTreeEdits = renderTreeDiff.Edits.Array,
RenderTreeEditsLength = renderTreeDiff.Edits.Count,
RenderTree = renderTreeDiff.CurrentState.Array,
RenderTreeLength = renderTreeDiff.CurrentState.Count
});
@ -84,10 +86,14 @@ namespace Microsoft.Blazor.Browser.Rendering
// Encapsulates the data we pass to the JS rendering function
private struct RenderComponentArgs
{
// Important: If you edit this struct, keep it in sync with RenderComponentArgs.ts
public int BrowserRendererId;
public int ComponentId;
public RenderTreeEdit[] RenderTreeEdits;
public int RenderTreeEditsLength;
public RenderTreeNode[] RenderTree;
public int RenderTreeLength;
public int RenderTreeLength; // TODO: Should be possible to remove this field once the JS code works entirely from the edits
}
}
}