Skip to content

Commit

Permalink
fix: make on* callbacks settable (#672)
Browse files Browse the repository at this point in the history
* fix: make on- callbacks settable

* test: test setting not calling
  • Loading branch information
andretchen0 authored May 3, 2024
1 parent 1121eb1 commit ac152df
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 0 deletions.
72 changes: 72 additions & 0 deletions playground/src/pages/basic/OnCallbacks.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
import { Mesh, MeshBasicMaterial, SphereGeometry } from 'three'
const geo = new SphereGeometry()
const mat = new MeshBasicMaterial()
const obj = new Mesh(geo, mat)
const meshNumOnBeforeRenders = shallowRef(0)
const meshNumOnAfterRenders = shallowRef(0)
const primitiveNumOnBeforeRenders = shallowRef(0)
const primitiveNumOnAfterRenders = shallowRef(0)
const materialNumOnBeforeCompiles = shallowRef(0)
const meshOnBeforeRender = () => { meshNumOnBeforeRenders.value++ }
const meshOnAfterRender = () => { meshNumOnAfterRenders.value++ }
const primitiveOnBeforeRender = () => { primitiveNumOnBeforeRenders.value++ }
const primitiveOnAfterRender = () => { primitiveNumOnAfterRenders.value++ }
const materialOnBeforeCompile = () => { materialNumOnBeforeCompiles.value++ }
</script>

<template>
<div class="overlay">
<h2>Primitive</h2>
<ul>
<li># onBeforeRender calls: {{ primitiveNumOnBeforeRenders }}</li>
<li># onAfterRender calls: {{ primitiveNumOnAfterRenders }}</li>
</ul>
<h2>Mesh</h2>
<ul>
<li># onBeforeRender calls: {{ meshNumOnBeforeRenders }}</li>
<li># onAfterRender calls: {{ meshNumOnAfterRenders }}</li>
</ul>
<h2>Material</h2>
<ul>
<li># onBeforeCompile calls: {{ materialNumOnBeforeCompiles }}</li>
</ul>
</div>
<TresCanvas>
<TresMesh
:position="[1, 0, 0]"
:scale="0.5"
:on-before-render="meshOnBeforeRender"
:on-after-render="meshOnAfterRender"
>
<TresBoxGeometry />
<TresMeshStandardMaterial
:on-before-compile="materialOnBeforeCompile"
/>
</TresMesh>
<primitive
:object="obj"
:position="[-1, 0, 0]"
:scale="0.5"
:on-before-render="primitiveOnBeforeRender"
:on-after-render="primitiveOnAfterRender"
/>
<TresGridHelper :args="[10, 10, 0x444444, 'teal']" />
</TresCanvas>
</template>

<style scoped>
.overlay {
position: fixed;
z-index: 1;
font-family: sans-serif;
background-color: #fff;
border-radius: 10px;
padding: 10px;
margin: 10px;
}
</style>
5 changes: 5 additions & 0 deletions playground/src/router/routes/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ export const basicRoutes = [
name: 'Responsiveness',
component: () => import('../../pages/basic/Responsiveness.vue'),
},
{
path: '/basic/onCallbacks',
name: 'on... callbacks',
component: () => import('../../pages/basic/OnCallbacks.vue'),
},
{
path: '/basic/pierced-props',
name: 'Pierced Props',
Expand Down
21 changes: 21 additions & 0 deletions src/core/nodeOps.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,27 @@ describe('nodeOps', () => {
expect(node.defines[allCapsUnderscoresKey]).equals(allCapsUnderscoresValue)
})

it('replaces "on*" methods on Object3D', () => {
// Issue: https://github.com/Tresjs/tres/issues/360
const { createElement, patchProp } = nodeOps
const object = createElement('TresObject3D', undefined, undefined, {})

const onAfterRender = () => {}
const onAfterShadow = () => {}
const onBeforeRender = () => {}
const onBeforeShadow = () => {}

patchProp(object, 'onAfterRender', null, onAfterRender)
patchProp(object, 'onAfterShadow', null, onAfterShadow)
patchProp(object, 'onBeforeRender', null, onBeforeRender)
patchProp(object, 'onBeforeShadow', null, onBeforeShadow)

expect(object.onAfterRender).toBe(onAfterRender)
expect(object.onAfterShadow).toBe(onAfterShadow)
expect(object.onBeforeRender).toBe(onBeforeRender)
expect(object.onBeforeShadow).toBe(onBeforeShadow)
})

it('calls object methods', () => {
const camera = nodeOps.createElement('TresPerspectiveCamera', undefined, undefined, {})
const spy = vi.spyOn(camera, 'lookAt')
Expand Down
5 changes: 5 additions & 0 deletions src/core/nodeOps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ export const nodeOps: () => RendererOptions<TresObject, TresObject | null> = ()
if (Array.isArray(value)) { node[finalKey](...value) }
else { node[finalKey](value) }
}
// NOTE: Set on* callbacks
// Issue: https://github.com/Tresjs/tres/issues/360
if (finalKey.startsWith('on') && isFunction(value)) {
root[finalKey] = value
}
return
}
if (!target?.set && !isFunction(target)) { root[finalKey] = value }
Expand Down

0 comments on commit ac152df

Please sign in to comment.