From ae3c219bdcaca7f939ff8981a0a461942b192159 Mon Sep 17 00:00:00 2001 From: Cody Bennett <23324155+CodyJasonBennett@users.noreply.github.com> Date: Fri, 22 Jul 2022 06:56:25 -0500 Subject: [PATCH] fix(renderer): update instance on commitupdate, cleanup prop filter --- packages/fiber/src/core/renderer.ts | 17 +++++++----- packages/fiber/src/core/utils.ts | 40 ++++++++++++++--------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/packages/fiber/src/core/renderer.ts b/packages/fiber/src/core/renderer.ts index 375451d6d6..d426c228e7 100644 --- a/packages/fiber/src/core/renderer.ts +++ b/packages/fiber/src/core/renderer.ts @@ -116,8 +116,9 @@ function createRenderer(_roots: Map, _getEventPriority?: const childIndex = parent.children.indexOf(child) if (childIndex !== -1) parent.children.splice(childIndex, 1) - if (child.props.attach) detach(parent, child) - else if (child.object.isObject3D && parent.object.isObject3D) { + if (child.props.attach) { + detach(parent, child) + } else if (child.object.isObject3D && parent.object.isObject3D) { parent.object.remove(child.object) removeInteractivity(child.root, child.object as unknown as THREE.Object3D) } @@ -286,14 +287,14 @@ function createRenderer(_roots: Map, _getEventPriority?: insertInContainerBefore: () => {}, getRootHostContext: () => null, getChildHostContext: (parentHostContext) => parentHostContext, - prepareUpdate(instance, type, oldProps, newProps) { + prepareUpdate(instance, _type, oldProps, newProps) { // Reconstruct primitives if object prop changes - if (type === 'primitive' && oldProps.object !== newProps.object) return [true] + if (instance.type === 'primitive' && oldProps.object !== newProps.object) return [true] // Reconstruct elements if args change if (newProps.args?.some((value, index) => value !== oldProps.args?.[index])) return [true] // Create a diff-set, flag if there are any changes - const changedProps = diffProps(instance, newProps, oldProps, true) + const changedProps = diffProps(newProps, oldProps, true) if (Object.keys(changedProps).length) return [false, changedProps] // Otherwise do not touch the instance @@ -303,9 +304,11 @@ function createRenderer(_roots: Map, _getEventPriority?: const [reconstruct, changedProps] = diff! // Reconstruct when args or true, commitMount: commitInstance, diff --git a/packages/fiber/src/core/utils.ts b/packages/fiber/src/core/utils.ts index 3282d3175b..a54d16dd40 100644 --- a/packages/fiber/src/core/utils.ts +++ b/packages/fiber/src/core/utils.ts @@ -1,7 +1,7 @@ import * as THREE from 'three' import * as React from 'react' import { EventHandlers } from './events' -import { AttachType, Instance, InstanceProps } from './renderer' +import { Instance, InstanceProps } from './renderer' import { Dpr, RootState, Size } from './store' export type Camera = THREE.OrthographicCamera | THREE.PerspectiveCamera @@ -177,24 +177,26 @@ export function detach(parent: Instance, child: Instance) { } const DEFAULT = '__default' -const REACT_RESERVED_PROPS = ['children', 'key', 'ref'] -const INSTANCE_RESERVED_PROPS = ['args', 'object', 'dispose', 'attach'] +const RESERVED_PROPS = [ + // React internal props + 'children', + 'key', + 'ref', + // Instance props + 'args', + 'dispose', + 'attach', + // 'object', -- internal to primitives +] // This function prepares a set of changes to be applied to the instance -export function diffProps( - instance: Instance, - newProps: InstanceProps, - oldProps: InstanceProps, - remove = false, -): InstanceProps { +export function diffProps(newProps: InstanceProps, oldProps: InstanceProps, remove = false): InstanceProps { const changedProps: InstanceProps = {} // Sort through props for (const key in newProps) { // Skip reserved keys - if (REACT_RESERVED_PROPS.includes(key as typeof REACT_RESERVED_PROPS[number])) continue - // Skip primitives - if (instance.type === 'primitive' && key === 'object') continue + if (RESERVED_PROPS.includes(key)) continue // Skip if props match if (is.equ(newProps[key], oldProps[key])) continue @@ -205,7 +207,7 @@ export function diffProps( // Catch removed props, prepend them so they can be reset or removed if (remove) { for (const key in oldProps) { - if (REACT_RESERVED_PROPS.includes(key)) continue + if (RESERVED_PROPS.includes(key)) continue else if (!newProps.hasOwnProperty(key)) changedProps[key] = DEFAULT + 'remove' } } @@ -214,20 +216,16 @@ export function diffProps( } // This function applies a set of changes to the instance -export function applyProps(object: any, newProps: any, oldProps?: any) { +export function applyProps(object: any, props: any) { const instance = object.__r3f as Instance | undefined const rootState = instance?.root.getState() const prevHandlers = instance?.eventCount - for (const prop in newProps) { - let value = newProps[prop] + for (const prop in props) { + let value = props[prop] // Don't mutate reserved keys - if (REACT_RESERVED_PROPS.includes(prop as typeof REACT_RESERVED_PROPS[number])) continue - if (INSTANCE_RESERVED_PROPS.includes(prop as typeof INSTANCE_RESERVED_PROPS[number])) continue - - // Don't mutate unchanged keys - if (newProps[prop] === oldProps?.[prop]) continue + if (RESERVED_PROPS.includes(prop)) continue // Deal with pointer events ... if (instance && /^on(Pointer|Click|DoubleClick|ContextMenu|Wheel)/.test(prop)) {