@huukhanhnguyen/model / schema/renderDiff
schema/renderDiff
FrameDiff
FrameDiff<
T> = {added:ObjectData[];kept: {cell:RenderCell<T>;objectData:ObjectData; }[];removed:RenderCell<T>[];updated: {cell:RenderCell<T>;objectData:ObjectData; }[]; }
Type Parameters
T
T = unknown
added
added:
ObjectData[]
New geometry — host builds (tessellates) a fresh object.
kept
kept: {
cell:RenderCell<T>;objectData:ObjectData; }[]
Same geometry, same props — host keeps the object untouched.
cell
cell:
RenderCell<T>
objectData
objectData:
ObjectData
removed
removed:
RenderCell<T>[]
Gone — host removes + disposes.
updated
updated: {
cell:RenderCell<T>;objectData:ObjectData; }[]
Same geometry, different props — host updates material/layer/name only.
cell
cell:
RenderCell<T>
objectData
objectData:
ObjectData
RenderCell
RenderCell<
T> = {data:T;key:string;layer?:string;material?:string;name?:string;objectData:ObjectData; }
One mounted render object in the previous frame: its content key, the props it was rendered with, and the host payload (a Three Object3D, SU entity ids, …) the host needs back on keep/update/remove.
Type Parameters
T
T = unknown
data
data:
T
key
key:
string
layer?
optionallayer?:string
material?
optionalmaterial?:string
name?
optionalname?:string
objectData
objectData:
ObjectData
The data document this cell was mounted FROM. The diff itself only needs key + the props, but an unmount hook is handed a DOCUMENT like every other scene point (see SceneHooks) — so the cell keeps the one it was built from, and the previous frame's documents stay reachable for exactly one frame.
SceneHooks
SceneHooks = {
afterMount?: (data) =>void;afterUnmount?: (data) =>void;afterUpdate?: (data) =>void;beforeMount?: (data) =>void;beforeUnmount?: (data) =>void;beforeUpdate?: (data) =>void; }
The moment a node's output CROSSES INTO THE SCENE, observed per document over a frame transition (renderDiff.ts's fireFrameHooks).
These are NODE-SIDE points, not events of a renderer. The engine says "this document entered / changed / left"; what a host does about it is the host's business. So do NOT complete the analogy with three.js — nothing here is shaped like onBeforeRender / onAfterRender / onBeforeShadow / onBeforeCompile, because those belong to ONE renderer and this kernel has to run in a viewer, an editor, headless, or under a renderer nobody has written yet.
Different words from the node tier (NodeHooks' beforeRemove/afterRemove) on purpose: a node leaving the GRAPH and a document leaving the SCENE are different events, and one node can mount and unmount many times without ever being removed.
THREE PAIRS, one per transition the diff actually computes: added → beforeMount / afterMount props-updated → beforeUpdate / afterUpdate removed → beforeUnmount / afterUnmount kept → NO point at all kept gets nothing because nothing happened — the same test that keeps a cache point out of the node tier: a moment with no value gets no name. props-updated is its own transition and not a rebuild: contentKey excludes props deliberately, so "same shape, new paint" arrives here (with the NEW document) instead of as an unmount+mount pair.
There is deliberately NO insert point. domphy separates Insert from Mount because a DOM subtree can be inserted while still detached — "in the tree" and "live" are two moments there. Here the frame IS the scene: a document is in it or it is not, so mount is ONE moment and a second point would name nothing.
A hook OBSERVES — never DECIDES, exactly as at the node tier: the return value is discarded (callHook), so a handler cannot veto a mount or rewrite what the diff decided.
afterMount?
optionalafterMount?: (data) =>void
Parameters
data
Returns
void
afterUnmount?
optionalafterUnmount?: (data) =>void
Parameters
data
Returns
void
afterUpdate?
optionalafterUpdate?: (data) =>void
Parameters
data
Returns
void
beforeMount?
optionalbeforeMount?: (data) =>void
Parameters
data
Returns
void
beforeUnmount?
optionalbeforeUnmount?: (data) =>void
Parameters
data
Returns
void
beforeUpdate?
optionalbeforeUpdate?: (data) =>void
Same geometry, new material/layer/name — handed the NEW document.
Parameters
data
Returns
void