Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 44 additions & 12 deletions src/valdi_modules/src/valdi/valdi_core/src/Renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ interface RenderedElement {
id: number;
nodePrototype: NodePrototype | undefined;
attributes: StringMap<any>;
directionWasSetDuringRender?: boolean;

wasVisibleOnce?: boolean;
// Bridge instance, will be set if the element was requested externally.
Expand Down Expand Up @@ -561,6 +562,7 @@ export class Renderer implements IRenderer {

private currentNode: VirtualNode | undefined;
private nodeStack: VirtualNode[] = [];
private rootElementEndingRender: RenderedElement | undefined;

readonly nodeTree: VirtualNode;
private readonly elementTree: RenderedElement;
Expand Down Expand Up @@ -978,6 +980,9 @@ export class Renderer implements IRenderer {
}

this.pushVirtualNode(resolvedNode);
if (resolvedNode.parentElement === this.elementTree) {
resolvedNode.element!.directionWasSetDuringRender = false;
}

if (justCreated && nodePrototype.attributes) {
enumeratePropertyList(nodePrototype.attributes, (name, value) => {
Expand All @@ -989,10 +994,15 @@ export class Renderer implements IRenderer {
endElement() {
const currentNode = this.currentNode;
if (currentNode && currentNode.parentElement === this.elementTree) {
for (const observer of this.observers) {
if (observer.onRootElementWillEndRender) {
observer.onRootElementWillEndRender();
this.rootElementEndingRender = currentNode.element;
try {
for (const observer of this.observers) {
if (observer.onRootElementWillEndRender) {
observer.onRootElementWillEndRender();
}
}
} finally {
this.rootElementEndingRender = undefined;
}
}

Expand Down Expand Up @@ -1459,13 +1469,7 @@ export class Renderer implements IRenderer {
// We need to render it with a new key

const duplicateKeyIndex = children.insertionIndex - resolvedNode.parentIndex + 1;
return this.resolveVirtualNode(
parent,
key,
duplicateKeyIndex,
componentConstructor,
componentPrototype,
);
return this.resolveVirtualNode(parent, key, duplicateKeyIndex, componentConstructor, componentPrototype);
}
}

Expand Down Expand Up @@ -1742,6 +1746,7 @@ export class Renderer implements IRenderer {

setAttributeString(name: string, value: string | undefined): boolean {
const element = this.getCurrentElement();
this.recordElementDirectionFromCurrentRender(element, name);
const attributes = element.attributes;
if (attributes[name] === value) {
return false;
Expand Down Expand Up @@ -1838,6 +1843,7 @@ export class Renderer implements IRenderer {
}

setAttributeOnElement(element: RenderedElement, name: string, value: any): boolean {
this.recordElementDirectionFromCurrentRender(element, name);
if (typeof value !== 'string' && (name === 'class' || name === '$class')) {
value = classNames(value);
}
Expand Down Expand Up @@ -2570,14 +2576,29 @@ export class Renderer implements IRenderer {
return nodes;
}

getRootElement(): IRenderedElement | undefined {
/** Return every top-level rendered element in render order. */
getRootElements(): IRenderedElement[] {
const out: IRenderedElement[] = [];
if (this.nodeTree.children) {
for (const node of this.nodeTree.children.children) {
this.collectElements(node, out);
}
}
return out[0];
return out;
}

/** Reports a declarative direction write for the root currently notifying render observers. */
wasElementDirectionSetDuringCurrentRender(element: IRenderedElement): boolean {
const renderedElement = this.getElementById(element.id);
return (
renderedElement !== undefined &&
renderedElement === this.rootElementEndingRender &&
renderedElement.directionWasSetDuringRender === true
);
}

getRootElement(): IRenderedElement | undefined {
return this.getRootElements()[0];
}

getComponentKey(component: IComponent): string {
Expand Down Expand Up @@ -2746,6 +2767,17 @@ export class Renderer implements IRenderer {
return this.elementById[elementId];
}

private recordElementDirectionFromCurrentRender(element: RenderedElement, attributeName: string): void {
if (
attributeName !== 'direction' ||
this.rootElementEndingRender !== undefined ||
this.currentNode?.element !== element
) {
return;
}
element.directionWasSetDuringRender = true;
}

private processFrameUpdates(updates: Float64Array) {
const elementById = this.elementById;
let elementsWithCallback: RenderedElement[] | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
} from './debugging/DaemonClientManager';
import { DebugLevel, SubmitDebugMessageFunc } from './debugging/DebugMessage';
import { DaemonClientMessageType, Messages, RemoteValdiContext } from './debugging/Messages';
import { NativeAppearanceDebugSettings } from './debugging/NativeAppearanceDebugSettings';
import { trace } from './utils/Trace';

interface StashedRootComponentHandle {
Expand Down Expand Up @@ -51,6 +52,7 @@ export class RootComponentsManager implements IRootComponentsManager, IDaemonCli
readonly rootComponents: StringMap<RootComponentHandle> = {};

private reloadedContextIds?: string[];
private nativeAppearanceDebugSettings?: NativeAppearanceDebugSettings;

constructor(
readonly rendererFactory: RendererFactory,
Expand All @@ -59,6 +61,7 @@ export class RootComponentsManager implements IRootComponentsManager, IDaemonCli
) {
if (daemonClientManager) {
daemonClientManager.addListener(this);
this.nativeAppearanceDebugSettings = new NativeAppearanceDebugSettings();
}
}

Expand Down Expand Up @@ -89,6 +92,8 @@ export class RootComponentsManager implements IRootComponentsManager, IDaemonCli
if (this.daemonClientManager) {
this.daemonClientManager.removeListener(this);
}
this.nativeAppearanceDebugSettings?.dispose();
this.nativeAppearanceDebugSettings = undefined;

return handles;
}
Expand Down Expand Up @@ -130,13 +135,15 @@ export class RootComponentsManager implements IRootComponentsManager, IDaemonCli
componentContext: any,
): RootComponentHandle {
const renderer = this.rendererFactory.makeRenderer(contextId);
const removeAppearanceObserver = this.nativeAppearanceDebugSettings?.addRenderer(renderer);

const observerDisposer = registerLogMetadataProvider('Valdi Runtime', renderer.dumpLogMetadata.bind(renderer));

const disposeFunction = () => {
if (onHotReloadSubscription) {
onHotReloadSubscription();
}
removeAppearanceObserver?.();
observerDisposer();
renderer.delegate.onDestroyed();
};
Expand Down
Loading
Loading