Skip to content

Commit fbdaa13

Browse files
committed
feature: disposable flag on node localstate
1 parent a839320 commit fbdaa13

File tree

2 files changed

+19
-21
lines changed

2 files changed

+19
-21
lines changed

src/core/nodeOps.ts

+18-21
Original file line numberDiff line numberDiff line change
@@ -75,22 +75,22 @@ export const nodeOps: RendererOptions<TresObject, TresObject | null> = {
7575
else if (instance.isBufferGeometry) instance.attach = 'geometry'
7676
}
7777

78-
// determine whether the material was passed via prop to
79-
// prevent it's disposal when node is removed later in it's lifecycle
80-
81-
if (instance.isObject3D) {
82-
if (props?.material?.isMaterial) (instance as TresObject3D).userData.tres__materialViaProp = true
83-
if (props?.geometry?.isBufferGeometry) (instance as TresObject3D).userData.tres__geometryViaProp = true
84-
}
85-
8678
instance.__tres = {
8779
...instance.__tres,
8880
type: name,
8981
memoizedProps: props,
9082
eventCount: 0,
83+
disposable: true,
9184
primitive: tag === 'primitive',
9285
}
9386

87+
// determine whether the material was passed via prop to
88+
// prevent it's disposal when node is removed later in it's lifecycle
89+
90+
if (instance.isObject3D && (props?.material || props?.geometry)) {
91+
instance.__tres.disposable = false
92+
}
93+
9494
return instance as TresObject
9595
},
9696
insert(child, parent) {
@@ -134,24 +134,21 @@ export const nodeOps: RendererOptions<TresObject, TresObject | null> = {
134134
},
135135
remove(node) {
136136
if (!node) return
137+
const ctx = node.__tres
137138
// remove is only called on the node being removed and not on child nodes.
138139
const {
139140
deregisterObjectAtPointerEventHandler,
140141
deregisterBlockingObjectAtPointerEventHandler,
141-
} = node.__tres.root
142+
} = ctx.root
142143

143144
if (node.isObject3D) {
144-
const object3D = node as unknown as Object3D
145145

146-
const disposeMaterialsAndGeometries = (object3D: Object3D) => {
146+
const disposeMaterialsAndGeometries = (object3D: TresObject) => {
147147
const tresObject3D = object3D as TresObject3D
148-
149-
if (!object3D.userData.tres__materialViaProp) {
148+
// TODO: to be improved on https://github.com/Tresjs/tres/pull/466/files
149+
if (ctx.disposable) {
150150
tresObject3D.material?.dispose()
151151
tresObject3D.material = undefined
152-
}
153-
154-
if (!object3D.userData.tres__geometryViaProp) {
155152
tresObject3D.geometry?.dispose()
156153
tresObject3D.geometry = undefined
157154
}
@@ -174,15 +171,15 @@ export const nodeOps: RendererOptions<TresObject, TresObject | null> = {
174171

175172
node.removeFromParent?.()
176173

177-
object3D.traverse((child: Object3D) => {
178-
disposeMaterialsAndGeometries(child)
174+
node.traverse((child: Object3D) => {
175+
disposeMaterialsAndGeometries(child as TresObject)
179176
deregisterCameraIfRequired(child)
180177
deregisterAtPointerEventHandlerIfRequired?.(child as TresObject)
181178
})
182179

183-
disposeMaterialsAndGeometries(object3D)
184-
deregisterCameraIfRequired(object3D)
185-
deregisterAtPointerEventHandlerIfRequired?.(object3D as TresObject)
180+
disposeMaterialsAndGeometries(node)
181+
deregisterCameraIfRequired(node as Object3D)
182+
deregisterAtPointerEventHandlerIfRequired?.(node as TresObject)
186183
}
187184

188185
invalidateInstance(node as TresObject)

src/types/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export interface LocalState {
4747
eventCount: number
4848
handlers: Partial<EventHandlers>
4949
memoizedProps: { [key: string]: any }
50+
disposable: boolean
5051
}
5152

5253
// Custom type for geometry and material properties in Object3D

0 commit comments

Comments
 (0)