From 711dd419259ea7210a1f254e28b2db922436ba58 Mon Sep 17 00:00:00 2001 From: alvarosabu Date: Tue, 22 Aug 2023 12:06:21 +0200 Subject: [PATCH 1/3] fix: instances re-instancing when not needed --- src/core/nodeOps.ts | 11 +++++++++-- src/utils/index.ts | 12 ++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/core/nodeOps.ts b/src/core/nodeOps.ts index 5441e48aa..a3be63b41 100644 --- a/src/core/nodeOps.ts +++ b/src/core/nodeOps.ts @@ -67,6 +67,11 @@ export const nodeOps: RendererOptions = { if (props?.geometry?.isBufferGeometry) (instance as TresObject3D).userData.tres__geometryViaProp = true } + // Since THREE instances properties are not consistent, (Orbit Controls doesn't have a `type` property) + // we take the tag name and we save it on the userData for later use in the re-instancing process. + if (!instance.userData) instance.userData = {} + instance.userData.tres__name = name + return instance }, insert(child, parent) { @@ -188,9 +193,11 @@ export const nodeOps: RendererOptions = { const prevNode = node as TresObject3D const prevArgs = _prevValue ?? [] const args = nextValue ?? [] + const instanceName = node.userData.tres__name || node.type - if (node.type && !deepArrayEqual(prevArgs, args)) { - root = Object.assign(prevNode, new catalogue.value[node.type](...nextValue)) + if (instanceName && prevArgs.length > 0 && !deepArrayEqual(prevArgs, args)) { + console.log('reinstancing', { instanceName, prevArgs, args }) + root = Object.assign(prevNode, new catalogue.value[instanceName](...nextValue)) } return } diff --git a/src/utils/index.ts b/src/utils/index.ts index 1e6330e8e..637cae545 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -26,6 +26,10 @@ const HTML_TAGS = export const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS) +export function isDOMElement(obj: any): obj is HTMLElement { + return obj && obj.nodeType === 1; +} + export function kebabToCamel(str: string) { return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase()) } @@ -77,6 +81,14 @@ export const set = (obj: any, path: string | string[], value: any): void => { export function deepEqual(a: any, b: any): boolean { + if (isDOMElement(a) && isDOMElement(b)) { + const attrsA = a.attributes; + const attrsB = b.attributes; + + if (attrsA.length !== attrsB.length) return false; + + return Array.from(attrsA).every(({ name, value }) => b.getAttribute(name) === value); + } // If both are primitives, return true if they are equal if (a === b) return true; From f0f9930317d9e5c62d01e6aa20a2ffcc61b82fb3 Mon Sep 17 00:00:00 2001 From: alvarosabu Date: Tue, 22 Aug 2023 15:58:08 +0200 Subject: [PATCH 2/3] chore: remove console --- src/core/nodeOps.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/nodeOps.ts b/src/core/nodeOps.ts index a3be63b41..b0b0b03a0 100644 --- a/src/core/nodeOps.ts +++ b/src/core/nodeOps.ts @@ -196,7 +196,6 @@ export const nodeOps: RendererOptions = { const instanceName = node.userData.tres__name || node.type if (instanceName && prevArgs.length > 0 && !deepArrayEqual(prevArgs, args)) { - console.log('reinstancing', { instanceName, prevArgs, args }) root = Object.assign(prevNode, new catalogue.value[instanceName](...nextValue)) } return From e470734ab9169f48621d0481c9fe3608b821fffe Mon Sep 17 00:00:00 2001 From: Tino Koch Date: Tue, 22 Aug 2023 16:16:17 +0200 Subject: [PATCH 3/3] chore: minor changes concerning re-instancing --- src/core/nodeOps.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/nodeOps.ts b/src/core/nodeOps.ts index b0b0b03a0..2b96bcb09 100644 --- a/src/core/nodeOps.ts +++ b/src/core/nodeOps.ts @@ -69,8 +69,10 @@ export const nodeOps: RendererOptions = { // Since THREE instances properties are not consistent, (Orbit Controls doesn't have a `type` property) // we take the tag name and we save it on the userData for later use in the re-instancing process. - if (!instance.userData) instance.userData = {} - instance.userData.tres__name = name + instance.userData = { + ...instance.userData, + tres__name: name + } return instance }, @@ -195,7 +197,7 @@ export const nodeOps: RendererOptions = { const args = nextValue ?? [] const instanceName = node.userData.tres__name || node.type - if (instanceName && prevArgs.length > 0 && !deepArrayEqual(prevArgs, args)) { + if (instanceName && prevArgs.length && !deepArrayEqual(prevArgs, args)) { root = Object.assign(prevNode, new catalogue.value[instanceName](...nextValue)) } return